Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/CarnetApp/CarnetNextcloud.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xCOPYING661
-rwxr-xr-xMakefile157
-rwxr-xr-xREADME.md4
-rw-r--r--appinfo/app.php44
-rwxr-xr-xappinfo/info.xml23
-rwxr-xr-xappinfo/routes.php26
-rwxr-xr-xcomposer.json17
-rw-r--r--composer.lock1513
-rwxr-xr-xcss/material.indigo-pink.min.css7789
-rwxr-xr-xcss/style.css3
-rwxr-xr-ximg/app.svg56
-rwxr-xr-xjs/browsers/browser.js539
-rwxr-xr-xjs/browsers/design.css152
-rwxr-xr-xjs/browsers/file-browser.js109
-rwxr-xr-xjs/browsers/note.js24
-rwxr-xr-xjs/browsers/note_card_view.js250
-rwxr-xr-xjs/browsers/search.js86
-rwxr-xr-xjs/libs/material.js4010
-rwxr-xr-xjs/script.js0
-rwxr-xr-xlib/Controller/NoteController.php323
-rwxr-xr-xlib/Controller/PageController.php40
-rwxr-xr-xphpunit.integration.xml7
-rwxr-xr-xphpunit.xml7
-rwxr-xr-xtemplates/content/index.php1
-rwxr-xr-xtemplates/index.php18
-rwxr-xr-xtemplates/navigation/index.php10
-rwxr-xr-xtemplates/settings/index.php10
-rwxr-xr-xtemplates/writer.php20
-rwxr-xr-xtests/Integration/AppTest.php29
-rwxr-xr-xtests/Unit/Controller/PageControllerTest.php31
-rwxr-xr-xtests/bootstrap.php19
-rw-r--r--vendor/autoload.php7
l---------vendor/bin/phpunit1
-rw-r--r--vendor/composer/ClassLoader.php445
-rw-r--r--vendor/composer/LICENSE56
-rw-r--r--vendor/composer/autoload_classmap.php474
-rw-r--r--vendor/composer/autoload_files.php11
-rw-r--r--vendor/composer/autoload_namespaces.php10
-rw-r--r--vendor/composer/autoload_psr4.php17
-rw-r--r--vendor/composer/autoload_real.php70
-rw-r--r--vendor/composer/autoload_static.php565
-rw-r--r--vendor/composer/installed.json1552
-rw-r--r--vendor/doctrine/instantiator/CONTRIBUTING.md35
-rw-r--r--vendor/doctrine/instantiator/LICENSE19
-rw-r--r--vendor/doctrine/instantiator/README.md40
-rw-r--r--vendor/doctrine/instantiator/composer.json45
-rw-r--r--vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php29
-rw-r--r--vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php52
-rw-r--r--vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php66
-rw-r--r--vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php216
-rw-r--r--vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php37
-rwxr-xr-xvendor/myclabs/deep-copy/.gitattributes7
-rwxr-xr-xvendor/myclabs/deep-copy/.gitignore3
-rw-r--r--vendor/myclabs/deep-copy/.scrutinizer.yml4
-rwxr-xr-xvendor/myclabs/deep-copy/.travis.yml40
-rw-r--r--vendor/myclabs/deep-copy/LICENSE20
-rw-r--r--vendor/myclabs/deep-copy/README.md376
-rw-r--r--vendor/myclabs/deep-copy/composer.json38
-rw-r--r--vendor/myclabs/deep-copy/doc/clone.pngbin0 -> 12380 bytes
-rw-r--r--vendor/myclabs/deep-copy/doc/deep-clone.pngbin0 -> 14009 bytes
-rw-r--r--vendor/myclabs/deep-copy/doc/deep-copy.pngbin0 -> 10895 bytes
-rw-r--r--vendor/myclabs/deep-copy/doc/graph.pngbin0 -> 6436 bytes
-rw-r--r--vendor/myclabs/deep-copy/fixtures/f001/A.php20
-rw-r--r--vendor/myclabs/deep-copy/fixtures/f001/B.php20
-rw-r--r--vendor/myclabs/deep-copy/fixtures/f002/A.php33
-rw-r--r--vendor/myclabs/deep-copy/fixtures/f003/Foo.php26
-rw-r--r--vendor/myclabs/deep-copy/fixtures/f004/UnclonableItem.php13
-rw-r--r--vendor/myclabs/deep-copy/fixtures/f005/Foo.php13
-rw-r--r--vendor/myclabs/deep-copy/fixtures/f006/A.php26
-rw-r--r--vendor/myclabs/deep-copy/fixtures/f006/B.php26
-rw-r--r--vendor/myclabs/deep-copy/fixtures/f007/FooDateInterval.php15
-rw-r--r--vendor/myclabs/deep-copy/fixtures/f007/FooDateTimeZone.php15
-rw-r--r--vendor/myclabs/deep-copy/fixtures/f008/A.php18
-rw-r--r--vendor/myclabs/deep-copy/fixtures/f008/B.php7
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/DeepCopy.php281
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php9
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/Exception/PropertyException.php9
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php33
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php28
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php22
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php18
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/Filter/KeepFilter.php16
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/Filter/ReplaceFilter.php39
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php24
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php22
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Matcher.php14
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyMatcher.php39
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php32
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php46
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php78
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php33
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php30
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php17
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php10
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedListFilter.php51
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php13
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/TypeMatcher/TypeMatcher.php29
-rw-r--r--vendor/myclabs/deep-copy/src/DeepCopy/deep_copy.php20
-rw-r--r--vendor/nelexa/zip/.gitignore5
-rw-r--r--vendor/nelexa/zip/.travis.yml24
-rw-r--r--vendor/nelexa/zip/CHANGELOG.md42
-rw-r--r--vendor/nelexa/zip/README.RU.md821
-rw-r--r--vendor/nelexa/zip/README.md823
-rw-r--r--vendor/nelexa/zip/composer.json47
-rw-r--r--vendor/nelexa/zip/phpunit.xml23
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Crypto/TraditionalPkwareEncryptionEngine.php225
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Crypto/WinZipAesEngine.php252
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Crypto/ZipEncryptionEngine.php32
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Exception/Crc32Exception.php66
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Exception/InvalidArgumentException.php14
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Exception/RuntimeException.php13
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Exception/ZipAuthenticationException.php13
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Exception/ZipCryptoException.php14
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Exception/ZipException.php14
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Exception/ZipNotFoundEntry.php14
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Exception/ZipUnsupportMethod.php14
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Extra/ExtraField.php35
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Extra/ExtraFieldsCollection.php240
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Extra/ExtraFieldsFactory.php173
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Extra/Fields/ApkAlignmentExtraField.php112
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Extra/Fields/DefaultExtraField.php71
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Extra/Fields/JarMarkerExtraField.php51
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Extra/Fields/NtfsExtraField.php133
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Extra/Fields/WinZipAesEntryExtraField.php256
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Extra/Fields/Zip64ExtraField.php118
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Mapper/OffsetPositionMapper.php43
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Mapper/PositionMapper.php30
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Model/EndOfCentralDirectory.php120
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Model/Entry/OutputOffsetEntry.php49
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Model/Entry/ZipAbstractEntry.php762
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Model/Entry/ZipChangesEntry.php63
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Model/Entry/ZipNewEntry.php89
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Model/Entry/ZipSourceEntry.php95
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Model/ZipEntry.php430
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Model/ZipEntryMatcher.php166
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Model/ZipInfo.php594
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Model/ZipModel.php344
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Stream/ResponseStream.php298
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Stream/ZipInputStream.php603
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Stream/ZipInputStreamInterface.php53
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Stream/ZipOutputStream.php528
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Stream/ZipOutputStreamInterface.php29
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Util/CryptoUtil.php33
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Util/DateTimeConverter.php78
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Util/FilesUtil.php228
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Util/Iterator/IgnoreFilesFilterIterator.php61
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Util/Iterator/IgnoreFilesRecursiveFilterIterator.php70
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Util/PackUtil.php65
-rw-r--r--vendor/nelexa/zip/src/PhpZip/Util/StringUtil.php31
-rw-r--r--vendor/nelexa/zip/src/PhpZip/ZipFile.php1512
-rw-r--r--vendor/nelexa/zip/src/PhpZip/ZipFileInterface.php633
-rw-r--r--vendor/nelexa/zip/tests/PhpZip/PhpZipExtResourceTest.php142
-rw-r--r--vendor/nelexa/zip/tests/PhpZip/ZipAlignTest.php147
-rw-r--r--vendor/nelexa/zip/tests/PhpZip/ZipFileAddDirTest.php383
-rw-r--r--vendor/nelexa/zip/tests/PhpZip/ZipFileTest.php2009
-rw-r--r--vendor/nelexa/zip/tests/PhpZip/ZipMatcherTest.php111
-rw-r--r--vendor/nelexa/zip/tests/PhpZip/ZipPasswordTest.php399
-rw-r--r--vendor/nelexa/zip/tests/PhpZip/ZipTestCase.php137
-rw-r--r--vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/binarynull.zipbin0 -> 656 bytes
-rw-r--r--vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/bug40228.zipbin0 -> 274 bytes
-rw-r--r--vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/bug49072.zipbin0 -> 162657 bytes
-rw-r--r--vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/bug70752.zipbin0 -> 175 bytes
-rw-r--r--vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/bug8009.zipbin0 -> 112 bytes
-rw-r--r--vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/pecl12414.zipbin0 -> 17271 bytes
-rw-r--r--vendor/nelexa/zip/tests/PhpZip/resources/aes_password_archive.zipbin0 -> 193 bytes
-rw-r--r--vendor/nelexa/zip/tests/PhpZip/resources/test.apkbin0 -> 1633373 bytes
-rw-r--r--vendor/phpdocumentor/reflection-common/.travis.yml35
-rw-r--r--vendor/phpdocumentor/reflection-common/LICENSE22
-rw-r--r--vendor/phpdocumentor/reflection-common/README.md2
-rw-r--r--vendor/phpdocumentor/reflection-common/composer.json29
-rw-r--r--vendor/phpdocumentor/reflection-common/src/Element.php32
-rw-r--r--vendor/phpdocumentor/reflection-common/src/File.php40
-rw-r--r--vendor/phpdocumentor/reflection-common/src/Fqsen.php82
-rw-r--r--vendor/phpdocumentor/reflection-common/src/Location.php57
-rw-r--r--vendor/phpdocumentor/reflection-common/src/Project.php25
-rw-r--r--vendor/phpdocumentor/reflection-common/src/ProjectFactory.php27
-rw-r--r--vendor/phpdocumentor/reflection-docblock/.coveralls.yml3
-rw-r--r--vendor/phpdocumentor/reflection-docblock/LICENSE21
-rw-r--r--vendor/phpdocumentor/reflection-docblock/README.md67
-rw-r--r--vendor/phpdocumentor/reflection-docblock/composer.json34
-rw-r--r--vendor/phpdocumentor/reflection-docblock/easy-coding-standard.neon31
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock.php236
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php114
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php191
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php170
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php155
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php319
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php26
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php93
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php100
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php52
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php83
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php97
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php176
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php18
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Strategy.php18
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php27
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php47
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php31
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php91
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php77
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php242
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php141
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php118
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php118
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php118
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php42
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php21
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Url.php40
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php72
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php88
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php94
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php97
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php72
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php83
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php118
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php94
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlockFactory.php277
-rw-r--r--vendor/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php23
-rw-r--r--vendor/phpdocumentor/type-resolver/LICENSE21
-rw-r--r--vendor/phpdocumentor/type-resolver/README.md182
-rw-r--r--vendor/phpdocumentor/type-resolver/composer.json27
-rw-r--r--vendor/phpdocumentor/type-resolver/src/FqsenResolver.php77
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Type.php18
-rw-r--r--vendor/phpdocumentor/type-resolver/src/TypeResolver.php298
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/Array_.php86
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/Boolean.php31
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/Callable_.php31
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/Compound.php93
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/Context.php84
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/ContextFactory.php210
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/Float_.php31
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/Integer.php28
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/Iterable_.php31
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/Mixed_.php31
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/Null_.php31
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/Nullable.php56
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/Object_.php71
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/Parent_.php33
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/Resource_.php31
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/Scalar.php31
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/Self_.php33
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/Static_.php38
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/String_.php31
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/This.php34
-rw-r--r--vendor/phpdocumentor/type-resolver/src/Types/Void_.php34
-rw-r--r--vendor/phpspec/prophecy/CHANGES.md213
-rw-r--r--vendor/phpspec/prophecy/LICENSE23
-rw-r--r--vendor/phpspec/prophecy/README.md391
-rw-r--r--vendor/phpspec/prophecy/composer.json50
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Argument.php212
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php101
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php52
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php52
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ApproximateValueToken.php55
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php86
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php143
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php82
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php75
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php116
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php74
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php80
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php73
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php104
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php67
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php43
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php76
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Call/Call.php162
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Call/CallCenter.php229
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php42
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Comparator/Factory.php47
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Comparator/ProphecyComparator.php28
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php68
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php48
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php72
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/HhvmExceptionPatch.php63
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php140
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php94
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php104
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php57
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php123
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ThrowablePatch.php95
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php83
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php22
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php146
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php129
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php67
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php260
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php102
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ClassNode.php169
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php198
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php22
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/TypeHintReference.php46
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php127
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php52
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php40
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php31
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php31
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php33
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php18
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php18
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php20
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotExtendableException.php41
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php60
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php41
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Exception.php26
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php16
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php51
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php24
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php18
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php18
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php31
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php32
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php34
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php34
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php18
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassAndInterfaceTagRetriever.php69
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassTagRetriever.php52
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/LegacyClassTagRetriever.php35
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/MethodTagRetrieverInterface.php30
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php86
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php107
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php65
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php68
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php37
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php66
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php35
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php61
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php55
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php99
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php488
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php281
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php27
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php34
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php44
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php29
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Prophet.php135
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php212
-rw-r--r--vendor/phpspec/prophecy/src/Prophecy/Util/StringUtil.php99
-rw-r--r--vendor/phpunit/php-code-coverage/.gitattributes1
-rw-r--r--vendor/phpunit/php-code-coverage/.github/CONTRIBUTING.md1
-rw-r--r--vendor/phpunit/php-code-coverage/.github/ISSUE_TEMPLATE.md18
-rw-r--r--vendor/phpunit/php-code-coverage/.gitignore6
-rw-r--r--vendor/phpunit/php-code-coverage/.php_cs69
-rw-r--r--vendor/phpunit/php-code-coverage/.travis.yml42
-rw-r--r--vendor/phpunit/php-code-coverage/ChangeLog-2.2.md56
-rw-r--r--vendor/phpunit/php-code-coverage/ChangeLog-3.0.md31
-rw-r--r--vendor/phpunit/php-code-coverage/ChangeLog-3.1.md30
-rw-r--r--vendor/phpunit/php-code-coverage/ChangeLog-3.2.md23
-rw-r--r--vendor/phpunit/php-code-coverage/ChangeLog-3.3.md33
-rw-r--r--vendor/phpunit/php-code-coverage/ChangeLog-4.0.md67
-rw-r--r--vendor/phpunit/php-code-coverage/LICENSE33
-rw-r--r--vendor/phpunit/php-code-coverage/README.md51
-rw-r--r--vendor/phpunit/php-code-coverage/build.xml21
-rw-r--r--vendor/phpunit/php-code-coverage/composer.json51
-rw-r--r--vendor/phpunit/php-code-coverage/phpunit.xml21
-rw-r--r--vendor/phpunit/php-code-coverage/src/CodeCoverage.php1107
-rw-r--r--vendor/phpunit/php-code-coverage/src/Driver/Driver.php52
-rw-r--r--vendor/phpunit/php-code-coverage/src/Driver/HHVM.php29
-rw-r--r--vendor/phpunit/php-code-coverage/src/Driver/PHPDBG.php111
-rw-r--r--vendor/phpunit/php-code-coverage/src/Driver/Xdebug.php117
-rw-r--r--vendor/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php18
-rw-r--r--vendor/phpunit/php-code-coverage/src/Exception/Exception.php18
-rw-r--r--vendor/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php37
-rw-r--r--vendor/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php18
-rw-r--r--vendor/phpunit/php-code-coverage/src/Exception/RuntimeException.php15
-rw-r--r--vendor/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php54
-rw-r--r--vendor/phpunit/php-code-coverage/src/Filter.php173
-rw-r--r--vendor/phpunit/php-code-coverage/src/Node/AbstractNode.php342
-rw-r--r--vendor/phpunit/php-code-coverage/src/Node/Builder.php244
-rw-r--r--vendor/phpunit/php-code-coverage/src/Node/Directory.php483
-rw-r--r--vendor/phpunit/php-code-coverage/src/Node/File.php722
-rw-r--r--vendor/phpunit/php-code-coverage/src/Node/Iterator.php103
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Clover.php251
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Crap4j.php172
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Facade.php179
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer.php298
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php302
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php101
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php551
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/coverage_bar.html.dist5
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/bootstrap.min.css6
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/nv.d3.min.css1
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/style.css122
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/dashboard.html.dist284
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory.html.dist61
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory_item.html.dist13
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file.html.dist90
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file_item.html.dist14
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.eotbin0 -> 20127 bytes
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.svg288
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.ttfbin0 -> 45404 bytes
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.woffbin0 -> 23424 bytes
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.woff2bin0 -> 18028 bytes
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/bootstrap.min.js7
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/d3.min.js5
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/holder.min.js12
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/html5shiv.min.js326
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/jquery.min.js4
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/nv.d3.min.js8
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/respond.min.js5
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/method_item.html.dist11
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/PHP.php51
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Text.php257
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Xml/Coverage.php67
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Xml/Directory.php15
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Xml/Facade.php238
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Xml/File.php72
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Xml/Method.php57
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Xml/Node.php88
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Xml/Project.php62
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Xml/Report.php71
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Xml/Tests.php46
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Xml/Totals.php141
-rw-r--r--vendor/phpunit/php-code-coverage/src/Report/Xml/Unit.php96
-rw-r--r--vendor/phpunit/php-code-coverage/src/Util.php48
-rw-r--r--vendor/phpunit/php-code-coverage/tests/TestCase.php343
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/BankAccount-clover.xml26
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/BankAccount-crap4j.xml59
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/BankAccount-text.txt12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/BankAccount.php33
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/BankAccountTest.php66
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoverageClassExtendedTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoverageClassTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionParenthesesTest.php11
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionParenthesesWhitespaceTest.php11
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionTest.php11
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodOneLineAnnotationTest.php11
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesWhitespaceTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoverageNoneTest.php9
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPrivateTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoverageNotProtectedTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPublicTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoverageNothingTest.php13
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoveragePrivateTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoverageProtectedTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoveragePublicTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoverageTwoDefaultClassAnnotations.php18
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoveredClass.php36
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/CoveredFunction.php4
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageClassExtendedTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageClassTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassPublicTest.php15
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassTest.php20
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageMethodTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPrivateTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotProtectedTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPublicTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePrivateTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageProtectedTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePublicTest.php12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveredClass.php38
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/NotExistingCoveredElementTest.php24
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html267
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/dashboard.html290
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/index.html119
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/dashboard.html288
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html119
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html211
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/dashboard.html286
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html99
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html234
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForBankAccount/BankAccount.php.xml40
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForBankAccount/index.xml29
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/index.xml26
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.xml41
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/index.xml26
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/source_with_ignore.php.xml28
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-clover.xml22
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-crap4j.xml37
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-text.txt12
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-clover.xml17
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-crap4j.xml37
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-text.txt10
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/source_with_class_and_anonymous_function.php19
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/source_with_ignore.php37
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/source_with_namespace.php20
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/source_with_oneline_annotations.php36
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/source_without_ignore.php4
-rw-r--r--vendor/phpunit/php-code-coverage/tests/_files/source_without_namespace.php18
-rw-r--r--vendor/phpunit/php-code-coverage/tests/bootstrap.php5
-rw-r--r--vendor/phpunit/php-code-coverage/tests/tests/BuilderTest.php212
-rw-r--r--vendor/phpunit/php-code-coverage/tests/tests/CloverTest.php49
-rw-r--r--vendor/phpunit/php-code-coverage/tests/tests/CodeCoverageTest.php547
-rw-r--r--vendor/phpunit/php-code-coverage/tests/tests/Crap4jTest.php49
-rw-r--r--vendor/phpunit/php-code-coverage/tests/tests/FilterTest.php194
-rw-r--r--vendor/phpunit/php-code-coverage/tests/tests/HTMLTest.php103
-rw-r--r--vendor/phpunit/php-code-coverage/tests/tests/TextTest.php49
-rw-r--r--vendor/phpunit/php-code-coverage/tests/tests/UtilTest.php27
-rw-r--r--vendor/phpunit/php-code-coverage/tests/tests/XMLTest.php99
-rw-r--r--vendor/phpunit/php-file-iterator/.gitattributes1
-rw-r--r--vendor/phpunit/php-file-iterator/.gitignore7
-rw-r--r--vendor/phpunit/php-file-iterator/ChangeLog.md41
-rw-r--r--vendor/phpunit/php-file-iterator/LICENSE33
-rw-r--r--vendor/phpunit/php-file-iterator/README.md12
-rw-r--r--vendor/phpunit/php-file-iterator/composer.json36
-rw-r--r--vendor/phpunit/php-file-iterator/src/Facade.php123
-rw-r--r--vendor/phpunit/php-file-iterator/src/Factory.php91
-rw-r--r--vendor/phpunit/php-file-iterator/src/Iterator.php158
-rw-r--r--vendor/phpunit/php-text-template/.gitattributes1
-rw-r--r--vendor/phpunit/php-text-template/.gitignore5
-rw-r--r--vendor/phpunit/php-text-template/LICENSE33
-rw-r--r--vendor/phpunit/php-text-template/README.md14
-rw-r--r--vendor/phpunit/php-text-template/composer.json29
-rw-r--r--vendor/phpunit/php-text-template/src/Template.php135
-rw-r--r--vendor/phpunit/php-timer/.gitattributes1
-rw-r--r--vendor/phpunit/php-timer/.gitignore4
-rw-r--r--vendor/phpunit/php-timer/.travis.yml27
-rw-r--r--vendor/phpunit/php-timer/LICENSE33
-rw-r--r--vendor/phpunit/php-timer/README.md45
-rw-r--r--vendor/phpunit/php-timer/composer.json37
-rw-r--r--vendor/phpunit/php-timer/phpunit.xml19
-rw-r--r--vendor/phpunit/php-timer/src/Timer.php105
-rw-r--r--vendor/phpunit/php-timer/tests/TimerTest.php98
-rw-r--r--vendor/phpunit/php-token-stream/.gitattributes1
-rw-r--r--vendor/phpunit/php-token-stream/.gitignore3
-rw-r--r--vendor/phpunit/php-token-stream/.travis.yml26
-rw-r--r--vendor/phpunit/php-token-stream/ChangeLog.md19
-rw-r--r--vendor/phpunit/php-token-stream/LICENSE33
-rw-r--r--vendor/phpunit/php-token-stream/README.md14
-rw-r--r--vendor/phpunit/php-token-stream/build.xml21
-rw-r--r--vendor/phpunit/php-token-stream/composer.json38
-rw-r--r--vendor/phpunit/php-token-stream/phpunit.xml17
-rw-r--r--vendor/phpunit/php-token-stream/src/Token.php1460
-rw-r--r--vendor/phpunit/php-token-stream/src/Token/Stream.php607
-rw-r--r--vendor/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php46
-rw-r--r--vendor/phpunit/php-token-stream/tests/Token/ClassTest.php169
-rw-r--r--vendor/phpunit/php-token-stream/tests/Token/ClosureTest.php78
-rw-r--r--vendor/phpunit/php-token-stream/tests/Token/FunctionTest.php139
-rw-r--r--vendor/phpunit/php-token-stream/tests/Token/IncludeTest.php65
-rw-r--r--vendor/phpunit/php-token-stream/tests/Token/InterfaceTest.php195
-rw-r--r--vendor/phpunit/php-token-stream/tests/Token/NamespaceTest.php69
-rw-r--r--vendor/phpunit/php-token-stream/tests/TokenTest.php32
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/classExtendsNamespacedClass.php10
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/classInNamespace.php6
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/classInScopedNamespace.php9
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/classUsesNamespacedFunction.php8
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_named_empty.php7
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_that_declares_anonymous_class.php15
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_that_declares_anonymous_class2.php16
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/class_with_multiple_anonymous_classes_and_functions.php26
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/closure.php7
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/issue19.php3
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/issue30.php8
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/multipleNamespacesWithOneClassUsingBraces.php12
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/multipleNamespacesWithOneClassUsingNonBraceSyntax.php14
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/php-code-coverage-issue-424.php13
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/source.php36
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/source2.php6
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/source3.php14
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/source4.php30
-rw-r--r--vendor/phpunit/php-token-stream/tests/_fixture/source5.php5
-rw-r--r--vendor/phpunit/php-token-stream/tests/bootstrap.php15
-rw-r--r--vendor/phpunit/phpunit-mock-objects/.gitattributes1
-rw-r--r--vendor/phpunit/phpunit-mock-objects/.gitignore7
-rw-r--r--vendor/phpunit/phpunit-mock-objects/.php_cs67
-rw-r--r--vendor/phpunit/phpunit-mock-objects/.travis.yml28
-rw-r--r--vendor/phpunit/phpunit-mock-objects/CONTRIBUTING.md1
-rw-r--r--vendor/phpunit/phpunit-mock-objects/LICENSE33
-rw-r--r--vendor/phpunit/phpunit-mock-objects/README.md22
-rw-r--r--vendor/phpunit/phpunit-mock-objects/build.xml42
-rw-r--r--vendor/phpunit/phpunit-mock-objects/composer.json53
-rw-r--r--vendor/phpunit/phpunit-mock-objects/phpunit.xml21
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Identity.php31
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/InvocationMocker.php291
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Match.php27
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/MethodNameMatch.php27
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Namespace.php38
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/ParametersMatch.php49
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Stub.php27
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/BadMethodCallException.php16
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/Exception.php18
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/RuntimeException.php16
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php1324
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/deprecation.tpl.dist2
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_class.tpl.dist40
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_class_method.tpl.dist7
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_clone.tpl.dist4
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_method.tpl.dist22
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_method_void.tpl.dist20
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_static_method.tpl.dist5
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/proxied_method.tpl.dist22
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/proxied_method_void.tpl.dist22
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/trait_class.tpl.dist4
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/unmocked_clone.tpl.dist5
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/wsdl_class.tpl.dist7
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/wsdl_method.tpl.dist4
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation.php22
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Object.php37
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Static.php207
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/InvocationMocker.php178
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invokable.php39
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher.php274
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyInvokedCount.php32
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyParameters.php35
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/ConsecutiveParameters.php126
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Invocation.php46
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtIndex.php87
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php57
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php45
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtMostCount.php57
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedCount.php110
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedRecorder.php68
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/MethodName.php68
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Parameters.php158
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/StatelessInvocation.php54
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockBuilder.php408
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockObject.php55
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub.php30
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ConsecutiveCalls.php48
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Exception.php48
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/MatcherCollection.php25
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Return.php41
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnArgument.php38
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnCallback.php51
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnReference.php22
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnSelf.php34
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnValueMap.php47
-rw-r--r--vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Verifiable.php25
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/GeneratorTest.php200
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockBuilderTest.php126
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Builder/InvocationMockerTest.php63
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/232.phpt129
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/abstract_class.phpt147
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class.phpt125
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_call_parent_clone.phpt77
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_call_parent_constructor.phpt76
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_dont_call_parent_clone.phpt76
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_dont_call_parent_constructor.phpt76
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_implementing_interface_call_parent_constructor.phpt81
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_implementing_interface_dont_call_parent_constructor.phpt81
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_partial.phpt103
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_with_method_named_method.phpt92
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_with_method_with_variadic_arguments.phpt99
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/interface.phpt97
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/invocation_object_clone_object.phpt126
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class.phpt127
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_call_parent_clone.phpt79
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_call_parent_constructor.phpt78
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_dont_call_parent_clone.phpt78
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_dont_call_parent_constructor.phpt78
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_implementing_interface_call_parent_constructor.phpt83
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_implementing_interface_dont_call_parent_constructor.phpt83
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_partial.phpt105
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_interface.phpt99
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nonexistent_class.phpt74
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nonexistent_class_with_namespace.phpt82
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nonexistent_class_with_namespace_starting_with_separator.phpt82
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nullable_types.phpt103
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/proxy.phpt121
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_nullable.phpt101
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_object_method.phpt104
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_self.phpt101
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_static_method.phpt87
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_void.phpt99
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/scalar_type_declarations.phpt103
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/wsdl_class.phpt37
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/wsdl_class_namespace.phpt39
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/wsdl_class_partial.phpt30
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Invocation/ObjectTest.php108
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Invocation/StaticTest.php87
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/Matcher/ConsecutiveParametersTest.php56
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObject/class_with_deprecated_method.phpt105
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/MockObjectTest.php1034
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/ProxyObjectTest.php39
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/AbstractMockTestClass.php10
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/AbstractTrait.php15
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/AnInterface.php5
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/AnInterfaceWithReturnType.php5
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/AnotherInterface.php5
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/Bar.php8
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/ClassThatImplementsSerializable.php15
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/ClassWithSelfTypeHint.php7
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/ClassWithStaticMethod.php7
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/Foo.php8
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/FunctionCallback.php9
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/GoogleSearch.wsdl198
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/InterfaceWithSemiReservedMethodName.php5
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/InterfaceWithStaticMethod.php5
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/MethodCallback.php21
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/MethodCallbackByReference.php13
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/MockTestInterface.php6
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/Mockable.php28
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/PartialMockTestClass.php18
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/SingletonClass.php28
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/SomeClass.php13
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/StaticMockTestClass.php12
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/StringableClass.php8
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/_fixture/TraversableMockTestInterface.php4
-rw-r--r--vendor/phpunit/phpunit-mock-objects/tests/bootstrap.php3
-rw-r--r--vendor/phpunit/phpunit/.gitattributes4
-rw-r--r--vendor/phpunit/phpunit/.github/CODE_OF_CONDUCT.md28
-rw-r--r--vendor/phpunit/phpunit/.github/CONTRIBUTING.md72
-rw-r--r--vendor/phpunit/phpunit/.github/ISSUE_TEMPLATE.md15
-rw-r--r--vendor/phpunit/phpunit/.gitignore20
-rw-r--r--vendor/phpunit/phpunit/.php_cs.dist81
-rw-r--r--vendor/phpunit/phpunit/.stickler.yml3
-rw-r--r--vendor/phpunit/phpunit/.travis.yml55
-rw-r--r--vendor/phpunit/phpunit/ChangeLog-5.7.md242
-rw-r--r--vendor/phpunit/phpunit/LICENSE33
-rw-r--r--vendor/phpunit/phpunit/README.md46
-rw-r--r--vendor/phpunit/phpunit/build.xml418
-rw-r--r--vendor/phpunit/phpunit/composer.json86
-rwxr-xr-xvendor/phpunit/phpunit/phpunit52
-rw-r--r--vendor/phpunit/phpunit/phpunit.xml34
-rw-r--r--vendor/phpunit/phpunit/phpunit.xsd254
-rw-r--r--vendor/phpunit/phpunit/src/Exception.php16
-rw-r--r--vendor/phpunit/phpunit/src/Extensions/GroupTestSuite.php58
-rw-r--r--vendor/phpunit/phpunit/src/Extensions/PhptTestCase.php430
-rw-r--r--vendor/phpunit/phpunit/src/Extensions/PhptTestSuite.php38
-rw-r--r--vendor/phpunit/phpunit/src/Extensions/RepeatedTest.php88
-rw-r--r--vendor/phpunit/phpunit/src/Extensions/TestDecorator.php107
-rw-r--r--vendor/phpunit/phpunit/src/Extensions/TicketListener.php194
-rw-r--r--vendor/phpunit/phpunit/src/ForwardCompatibility/Assert.php17
-rw-r--r--vendor/phpunit/phpunit/src/ForwardCompatibility/AssertionFailedError.php17
-rw-r--r--vendor/phpunit/phpunit/src/ForwardCompatibility/BaseTestListener.php17
-rw-r--r--vendor/phpunit/phpunit/src/ForwardCompatibility/Test.php17
-rw-r--r--vendor/phpunit/phpunit/src/ForwardCompatibility/TestCase.php17
-rw-r--r--vendor/phpunit/phpunit/src/ForwardCompatibility/TestListener.php17
-rw-r--r--vendor/phpunit/phpunit/src/ForwardCompatibility/TestSuite.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Assert.php2952
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Assert/Functions.php2174
-rw-r--r--vendor/phpunit/phpunit/src/Framework/AssertionFailedError.php25
-rw-r--r--vendor/phpunit/phpunit/src/Framework/BaseTestListener.php58
-rw-r--r--vendor/phpunit/phpunit/src/Framework/CodeCoverageException.php13
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint.php149
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/And.php121
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php80
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php107
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Attribute.php84
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Callback.php59
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php80
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php52
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Composite.php67
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Count.php122
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php58
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Exception.php85
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php66
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php81
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegExp.php74
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/FileExists.php58
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php53
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/IsAnything.php58
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php64
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/IsEqual.php177
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/IsFalse.php38
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/IsFinite.php38
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php130
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php38
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php92
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/IsJson.php75
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/IsNan.php38
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/IsNull.php38
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/IsReadable.php58
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/IsTrue.php38
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/IsType.php141
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/IsWritable.php58
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php69
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches/ErrorMessageProvider.php67
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/LessThan.php53
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Not.php156
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php33
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Or.php113
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/PCREMatch.php61
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/SameSize.php25
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/StringContains.php79
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php53
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/StringMatches.php99
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php53
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php123
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php93
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Constraint/Xor.php118
-rw-r--r--vendor/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Error.php32
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Error/Deprecated.php22
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Error/Notice.php22
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Error/Warning.php22
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Exception.php76
-rw-r--r--vendor/phpunit/phpunit/src/Framework/ExceptionWrapper.php89
-rw-r--r--vendor/phpunit/phpunit/src/Framework/ExpectationFailedException.php39
-rw-r--r--vendor/phpunit/phpunit/src/Framework/IncompleteTest.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/IncompleteTestCase.php82
-rw-r--r--vendor/phpunit/phpunit/src/Framework/IncompleteTestError.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php13
-rw-r--r--vendor/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/OutputError.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/RiskyTest.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/RiskyTestError.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/SelfDescribing.php22
-rw-r--r--vendor/phpunit/phpunit/src/Framework/SkippedTest.php16
-rw-r--r--vendor/phpunit/phpunit/src/Framework/SkippedTestCase.php80
-rw-r--r--vendor/phpunit/phpunit/src/Framework/SkippedTestError.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/SyntheticError.php78
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Test.php24
-rw-r--r--vendor/phpunit/phpunit/src/Framework/TestCase.php2491
-rw-r--r--vendor/phpunit/phpunit/src/Framework/TestFailure.php161
-rw-r--r--vendor/phpunit/phpunit/src/Framework/TestListener.php102
-rw-r--r--vendor/phpunit/phpunit/src/Framework/TestResult.php1310
-rw-r--r--vendor/phpunit/phpunit/src/Framework/TestSuite.php1000
-rw-r--r--vendor/phpunit/phpunit/src/Framework/TestSuite/DataProvider.php24
-rw-r--r--vendor/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php17
-rw-r--r--vendor/phpunit/phpunit/src/Framework/Warning.php25
-rw-r--r--vendor/phpunit/phpunit/src/Framework/WarningTestCase.php75
-rw-r--r--vendor/phpunit/phpunit/src/Runner/BaseTestRunner.php139
-rw-r--r--vendor/phpunit/phpunit/src/Runner/Exception.php13
-rw-r--r--vendor/phpunit/phpunit/src/Runner/Filter/Factory.php48
-rw-r--r--vendor/phpunit/phpunit/src/Runner/Filter/Group.php56
-rw-r--r--vendor/phpunit/phpunit/src/Runner/Filter/Group/Exclude.php22
-rw-r--r--vendor/phpunit/phpunit/src/Runner/Filter/Group/Include.php22
-rw-r--r--vendor/phpunit/phpunit/src/Runner/Filter/Test.php117
-rw-r--r--vendor/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php116
-rw-r--r--vendor/phpunit/phpunit/src/Runner/TestSuiteLoader.php30
-rw-r--r--vendor/phpunit/phpunit/src/Runner/Version.php73
-rw-r--r--vendor/phpunit/phpunit/src/TextUI/Command.php1172
-rw-r--r--vendor/phpunit/phpunit/src/TextUI/ResultPrinter.php680
-rw-r--r--vendor/phpunit/phpunit/src/TextUI/TestRunner.php1142
-rw-r--r--vendor/phpunit/phpunit/src/Util/Blacklist.php111
-rw-r--r--vendor/phpunit/phpunit/src/Util/Configuration.php1135
-rw-r--r--vendor/phpunit/phpunit/src/Util/ConfigurationGenerator.php66
-rw-r--r--vendor/phpunit/phpunit/src/Util/ErrorHandler.php115
-rw-r--r--vendor/phpunit/phpunit/src/Util/Fileloader.php68
-rw-r--r--vendor/phpunit/phpunit/src/Util/Filesystem.php38
-rw-r--r--vendor/phpunit/phpunit/src/Util/Filter.php103
-rw-r--r--vendor/phpunit/phpunit/src/Util/Getopt.php164
-rw-r--r--vendor/phpunit/phpunit/src/Util/GlobalState.php214
-rw-r--r--vendor/phpunit/phpunit/src/Util/InvalidArgumentHelper.php39
-rw-r--r--vendor/phpunit/phpunit/src/Util/Log/JSON.php254
-rw-r--r--vendor/phpunit/phpunit/src/Util/Log/JUnit.php450
-rw-r--r--vendor/phpunit/phpunit/src/Util/Log/TAP.php261
-rw-r--r--vendor/phpunit/phpunit/src/Util/Log/TeamCity.php406
-rw-r--r--vendor/phpunit/phpunit/src/Util/PHP.php410
-rw-r--r--vendor/phpunit/phpunit/src/Util/PHP/Default.php208
-rw-r--r--vendor/phpunit/phpunit/src/Util/PHP/Template/TestCaseMethod.tpl.dist102
-rw-r--r--vendor/phpunit/phpunit/src/Util/PHP/Windows.php40
-rw-r--r--vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php10
-rw-r--r--vendor/phpunit/phpunit/src/Util/Printer.php144
-rw-r--r--vendor/phpunit/phpunit/src/Util/Regex.php33
-rw-r--r--vendor/phpunit/phpunit/src/Util/String.php61
-rw-r--r--vendor/phpunit/phpunit/src/Util/Test.php1099
-rw-r--r--vendor/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php142
-rw-r--r--vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php399
-rw-r--r--vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter/HTML.php137
-rw-r--r--vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter/Text.php52
-rw-r--r--vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter/XML.php225
-rw-r--r--vendor/phpunit/phpunit/src/Util/TestSuiteIterator.php101
-rw-r--r--vendor/phpunit/phpunit/src/Util/Type.php41
-rw-r--r--vendor/phpunit/phpunit/src/Util/XML.php246
-rw-r--r--vendor/phpunit/phpunit/tests/Extensions/PhptTestCaseTest.php263
-rw-r--r--vendor/phpunit/phpunit/tests/Extensions/RepeatedTestTest.php60
-rw-r--r--vendor/phpunit/phpunit/tests/Fail/fail.phpt5
-rw-r--r--vendor/phpunit/phpunit/tests/Framework/AssertTest.php3768
-rw-r--r--vendor/phpunit/phpunit/tests/Framework/BaseTestListenerTest.php28
-rw-r--r--vendor/phpunit/phpunit/tests/Framework/Constraint/ArraySubsetTest.php65
-rw-r--r--vendor/phpunit/phpunit/tests/Framework/Constraint/CountTest.php92
-rw-r--r--vendor/phpunit/phpunit/tests/Framework/Constraint/ExceptionMessageRegExpTest.php51
-rw-r--r--vendor/phpunit/phpunit/tests/Framework/Constraint/ExceptionMessageTest.php48
-rw-r--r--vendor/phpunit/phpunit/tests/Framework/Constraint/IsJsonTest.php29
-rw-r--r--vendor/phpunit/phpunit/tests/Framework/Constraint/JsonMatches/ErrorMessageProviderTest.php78
-rw-r--r--vendor/phpunit/phpunit/tests/Framework/Constraint/JsonMatchesTest.php39
-rw-r--r--vendor/phpunit/phpunit/tests/Framework/ConstraintTest.php3053
-rw-r--r--vendor/phpunit/phpunit/tests/Framework/SuiteTest.php269
-rw-r--r--vendor/phpunit/phpunit/tests/Framework/TestCaseTest.php690
-rw-r--r--vendor/phpunit/phpunit/tests/Framework/TestFailureTest.php21
-rw-r--r--vendor/phpunit/phpunit/tests/Framework/TestImplementorTest.php24
-rw-r--r--vendor/phpunit/phpunit/tests/Framework/TestListenerTest.php110
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1149.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1149/Issue1149Test.php18
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1216.phpt25
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1216/Issue1216Test.php8
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1216/bootstrap1216.php2
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1216/phpunit1216.xml8
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1265.phpt21
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1265/Issue1265Test.php8
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1265/phpunit1265.xml2
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1330.phpt24
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1330/Issue1330Test.php8
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1330/phpunit1330.xml5
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1335.phpt19
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1335/Issue1335Test.php67
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1335/bootstrap1335.php13
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1337.phpt19
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1337/Issue1337Test.php19
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1348.phpt34
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1348/Issue1348Test.php14
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1351.phpt46
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1351/ChildProcessClass1351.php4
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1351/Issue1351Test.php48
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1374.phpt19
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1374/Issue1374Test.php21
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1437.phpt26
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1437/Issue1437Test.php9
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1468.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1468/Issue1468Test.php11
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1471.phpt26
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1471/Issue1471Test.php12
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1472.phpt25
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1472/Issue1472Test.php21
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1570.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/1570/Issue1570Test.php8
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2137-filter.phpt28
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2137-no_filter.phpt30
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2137/Issue2137Test.php33
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2145.phpt26
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2145/Issue2145Test.php16
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2158.phpt19
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2158/Issue2158Test.php23
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2158/constant.inc5
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2299/Issue2299Test.php20
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2366.phpt19
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2366/Issue2366Test.php30
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2380.phpt19
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2380/Issue2380Test.php21
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2382.phpt19
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2382/Issue2382Test.php22
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2435.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2435/Issue2435Test.php12
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/244.phpt32
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/244/Issue244Test.php55
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2731.phpt26
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2731/Issue2731Test.php11
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2758.phpt22
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2758/Issue2758Test.php7
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2758/Issue2758TestListener.php12
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2758/phpunit.xml7
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2811.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2811/Issue2811Test.php10
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2972.phpt18
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2972/issue-2972-test.phpt10
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/2972/unconventiallyNamedIssue2972Test.php13
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/322.phpt26
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/322/Issue322Test.php17
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/322/phpunit322.xml11
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/433.phpt31
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/433/Issue433Test.php21
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/445.phpt32
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/445/Issue445Test.php21
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/498.phpt29
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/498/Issue498Test.php44
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/503.phpt33
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/503/Issue503Test.php11
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/581.phpt42
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/581/Issue581Test.php11
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/74.phpt28
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/74/Issue74Test.php9
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/74/NewException.php4
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/765.phpt26
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/765/Issue765Test.php22
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/797.phpt22
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/797/Issue797Test.php10
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/797/bootstrap797.php6
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/863.phpt24
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/873-php5.phpt22
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/873-php7.phpt22
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/GitHub/873/Issue873Test.php9
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/Trac/1021.phpt19
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/Trac/1021/Issue1021Test.php23
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/Trac/523.phpt19
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/Trac/523/Issue523Test.php13
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/Trac/578.phpt37
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/Trac/578/Issue578Test.php20
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/Trac/684.phpt25
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/Trac/684/Issue684Test.php4
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/Trac/783.phpt21
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/Trac/783/ChildSuite.php15
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/Trac/783/OneTest.php10
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/Trac/783/ParentSuite.php13
-rw-r--r--vendor/phpunit/phpunit/tests/Regression/Trac/783/TwoTest.php10
-rw-r--r--vendor/phpunit/phpunit/tests/Runner/BaseTestRunnerTest.php18
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/_files/expect_external.txt1
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/_files/phpt-env.expected.txt1
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/_files/phpt_external.php2
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/abstract-test-class.phpt24
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/assertion.phpt38
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/code-coverage-ignore.phpt36
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/colors-always.phpt18
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/concrete-test-class.phpt18
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/custom-printer-debug.phpt26
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/custom-printer-verbose.phpt31
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/dataprovider-debug.phpt33
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/dataprovider-issue-2833.phpt17
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/dataprovider-issue-2859.phpt17
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/dataprovider-issue-2922.phpt18
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/dataprovider-log-xml-isolation.phpt46
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/dataprovider-log-xml.phpt45
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/dataprovider-testdox.phpt19
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/debug.phpt25
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/default-isolation.phpt19
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/default.phpt18
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/dependencies-clone.phpt22
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/dependencies-isolation.phpt42
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/dependencies.phpt41
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/dependencies2-isolation.phpt19
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/dependencies2.phpt18
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/dependencies3-isolation.phpt19
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/dependencies3.phpt19
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/disable-code-coverage-ignore.phpt40
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/empty-testcase.phpt25
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/exception-stack.phpt64
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/exclude-group-isolation.phpt21
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/exclude-group.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/failure-isolation.phpt141
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/failure-reverse-list.phpt141
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/failure.phpt140
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/fatal-isolation.phpt25
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-class-isolation.phpt21
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-class.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-classname-and-range-isolation.phpt21
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-classname-and-range.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-number-isolation.phpt21
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-number.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-range-isolation.phpt21
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-range.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-regexp-isolation.phpt21
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-regexp.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-string-isolation.phpt21
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-string.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-range-isolation.phpt21
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-range.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-regexp-isolation.phpt21
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-regexp.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-string-isolation.phpt21
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-string.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-method-case-insensitive.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-method-case-sensitive-no-result.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-method-isolation.phpt21
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-method.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/filter-no-results.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/forward-compatibility.phpt18
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/group-isolation.phpt21
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/group.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/help.phpt99
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/help2.phpt100
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/ini-isolation.phpt21
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/list-groups.phpt18
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/list-suites.phpt16
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/log-json-post-66021.phpt73
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/log-junit.phpt68
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/log-tap.phpt27
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/log-teamcity.phpt38
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/mycommand.phpt23
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/options-after-arguments.phpt18
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/output-isolation.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/phar-extension-suppressed.phpt12
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/phar-extension.phpt21
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/phpt-args.phpt12
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/phpt-env.phpt12
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/phpt-external.phpt6
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/phpt-stderr.phpt8
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/phpt-stdin.phpt11
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/phpt-xfail.phpt18
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/repeat.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/report-useless-tests-incomplete.phpt20
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/report-useless-tests-isolation.phpt21
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/report-useless-tests.phpt28
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/stop-on-warning-via-cli.phpt25
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/stop-on-warning-via-config.phpt26
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/tap.phpt17
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/teamcity-inner-exceptions.phpt39
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/teamcity.phpt37
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/test-suffix-multiple.phpt19
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/test-suffix-single.phpt19
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/testdox-exclude-group.phpt25
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/testdox-group.phpt25
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/testdox-html.phpt56
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/testdox-text.phpt24
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/testdox-xml.phpt56
-rw-r--r--vendor/phpunit/phpunit/tests/TextUI/testdox.phpt18
-rw-r--r--vendor/phpunit/phpunit/tests/Util/ConfigurationTest.php431
-rw-r--r--vendor/phpunit/phpunit/tests/Util/GetoptTest.php60
-rw-r--r--vendor/phpunit/phpunit/tests/Util/GlobalStateTest.php30
-rw-r--r--vendor/phpunit/phpunit/tests/Util/PHPTest.php132
-rw-r--r--vendor/phpunit/phpunit/tests/Util/RegexTest.php47
-rw-r--r--vendor/phpunit/phpunit/tests/Util/TestDox/NamePrettifierTest.php66
-rw-r--r--vendor/phpunit/phpunit/tests/Util/TestTest.php823
-rw-r--r--vendor/phpunit/phpunit/tests/Util/XMLTest.php90
-rw-r--r--vendor/phpunit/phpunit/tests/_files/AbstractTest.php7
-rw-r--r--vendor/phpunit/phpunit/tests/_files/ArrayAccessible.php40
-rw-r--r--vendor/phpunit/phpunit/tests/_files/AssertionExample.php8
-rw-r--r--vendor/phpunit/phpunit/tests/_files/AssertionExampleTest.php10
-rw-r--r--vendor/phpunit/phpunit/tests/_files/Author.php26
-rw-r--r--vendor/phpunit/phpunit/tests/_files/BankAccount.php81
-rw-r--r--vendor/phpunit/phpunit/tests/_files/BankAccountTest.php93
-rw-r--r--vendor/phpunit/phpunit/tests/_files/BankAccountTest.test.php86
-rw-r--r--vendor/phpunit/phpunit/tests/_files/BankAccountTest2.php56
-rw-r--r--vendor/phpunit/phpunit/tests/_files/BaseTestListenerSample.php11
-rw-r--r--vendor/phpunit/phpunit/tests/_files/BeforeAndAfterTest.php35
-rw-r--r--vendor/phpunit/phpunit/tests/_files/BeforeClassAndAfterClassTest.php35
-rw-r--r--vendor/phpunit/phpunit/tests/_files/BeforeClassWithOnlyDataProviderTest.php39
-rw-r--r--vendor/phpunit/phpunit/tests/_files/Book.php19
-rw-r--r--vendor/phpunit/phpunit/tests/_files/Calculator.php14
-rw-r--r--vendor/phpunit/phpunit/tests/_files/ChangeCurrentWorkingDirectoryTest.php9
-rw-r--r--vendor/phpunit/phpunit/tests/_files/ClassWithNonPublicAttributes.php29
-rw-r--r--vendor/phpunit/phpunit/tests/_files/ClassWithScalarTypeDeclarations.php7
-rw-r--r--vendor/phpunit/phpunit/tests/_files/ClassWithToString.php21
-rw-r--r--vendor/phpunit/phpunit/tests/_files/ClonedDependencyTest.php39
-rw-r--r--vendor/phpunit/phpunit/tests/_files/ConcreteTest.my.php7
-rw-r--r--vendor/phpunit/phpunit/tests/_files/ConcreteTest.php7
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoverageClassExtendedTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoverageClassTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoverageFunctionParenthesesTest.php11
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoverageFunctionParenthesesWhitespaceTest.php11
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoverageFunctionTest.php11
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoverageMethodOneLineAnnotationTest.php11
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoverageMethodParenthesesTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoverageMethodParenthesesWhitespaceTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoverageMethodTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoverageNamespacedFunctionTest.php11
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoverageNoneTest.php9
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoverageNotPrivateTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoverageNotProtectedTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoverageNotPublicTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoverageNothingTest.php13
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoveragePrivateTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoverageProtectedTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoveragePublicTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoverageTwoDefaultClassAnnotations.php17
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoveredClass.php36
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CoveredFunction.php4
-rw-r--r--vendor/phpunit/phpunit/tests/_files/CustomPrinter.php4
-rw-r--r--vendor/phpunit/phpunit/tests/_files/DataProviderDebugTest.php48
-rw-r--r--vendor/phpunit/phpunit/tests/_files/DataProviderDependencyTest.php25
-rw-r--r--vendor/phpunit/phpunit/tests/_files/DataProviderFilterTest.php39
-rw-r--r--vendor/phpunit/phpunit/tests/_files/DataProviderIncompleteTest.php37
-rw-r--r--vendor/phpunit/phpunit/tests/_files/DataProviderIssue2833/FirstTest.php23
-rw-r--r--vendor/phpunit/phpunit/tests/_files/DataProviderIssue2833/SecondTest.php15
-rw-r--r--vendor/phpunit/phpunit/tests/_files/DataProviderIssue2859/phpunit.xml10
-rw-r--r--vendor/phpunit/phpunit/tests/_files/DataProviderIssue2859/tests/another/TestWithDataProviderTest.php21
-rw-r--r--vendor/phpunit/phpunit/tests/_files/DataProviderIssue2922/FirstTest.php24
-rw-r--r--vendor/phpunit/phpunit/tests/_files/DataProviderIssue2922/SecondTest.php14
-rw-r--r--vendor/phpunit/phpunit/tests/_files/DataProviderSkippedTest.php37
-rw-r--r--vendor/phpunit/phpunit/tests/_files/DataProviderTest.php21
-rw-r--r--vendor/phpunit/phpunit/tests/_files/DataProviderTestDoxTest.php26
-rw-r--r--vendor/phpunit/phpunit/tests/_files/DependencyFailureTest.php29
-rw-r--r--vendor/phpunit/phpunit/tests/_files/DependencySuccessTest.php21
-rw-r--r--vendor/phpunit/phpunit/tests/_files/DependencyTestSuite.php13
-rw-r--r--vendor/phpunit/phpunit/tests/_files/DoubleTestCase.php25
-rw-r--r--vendor/phpunit/phpunit/tests/_files/DummyException.php5
-rw-r--r--vendor/phpunit/phpunit/tests/_files/EmptyTestCaseTest.php4
-rw-r--r--vendor/phpunit/phpunit/tests/_files/ExceptionInAssertPostConditionsTest.php35
-rw-r--r--vendor/phpunit/phpunit/tests/_files/ExceptionInAssertPreConditionsTest.php35
-rw-r--r--vendor/phpunit/phpunit/tests/_files/ExceptionInSetUpTest.php35
-rw-r--r--vendor/phpunit/phpunit/tests/_files/ExceptionInTearDownTest.php35
-rw-r--r--vendor/phpunit/phpunit/tests/_files/ExceptionInTest.php35
-rw-r--r--vendor/phpunit/phpunit/tests/_files/ExceptionNamespaceTest.php38
-rw-r--r--vendor/phpunit/phpunit/tests/_files/ExceptionStackTest.php21
-rw-r--r--vendor/phpunit/phpunit/tests/_files/ExceptionTest.php139
-rw-r--r--vendor/phpunit/phpunit/tests/_files/Failure.php8
-rw-r--r--vendor/phpunit/phpunit/tests/_files/FailureTest.php75
-rw-r--r--vendor/phpunit/phpunit/tests/_files/FatalTest.php13
-rw-r--r--vendor/phpunit/phpunit/tests/_files/IgnoreCodeCoverageClass.php16
-rw-r--r--vendor/phpunit/phpunit/tests/_files/IgnoreCodeCoverageClassTest.php15
-rw-r--r--vendor/phpunit/phpunit/tests/_files/IncompleteTest.php8
-rw-r--r--vendor/phpunit/phpunit/tests/_files/Inheritance/InheritanceA.php7
-rw-r--r--vendor/phpunit/phpunit/tests/_files/Inheritance/InheritanceB.php8
-rw-r--r--vendor/phpunit/phpunit/tests/_files/InheritedTestCase.php7
-rw-r--r--vendor/phpunit/phpunit/tests/_files/IniTest.php8
-rw-r--r--vendor/phpunit/phpunit/tests/_files/IsolationTest.php13
-rw-r--r--vendor/phpunit/phpunit/tests/_files/JsonData/arrayObject.json1
-rw-r--r--vendor/phpunit/phpunit/tests/_files/JsonData/simpleObject.json1
-rw-r--r--vendor/phpunit/phpunit/tests/_files/MockRunner.php7
-rw-r--r--vendor/phpunit/phpunit/tests/_files/Mockable.php26
-rw-r--r--vendor/phpunit/phpunit/tests/_files/MultiDependencyTest.php23
-rw-r--r--vendor/phpunit/phpunit/tests/_files/MultipleDataProviderTest.php75
-rw-r--r--vendor/phpunit/phpunit/tests/_files/MyCommand.php15
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NamespaceCoverageClassExtendedTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NamespaceCoverageClassTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NamespaceCoverageCoversClassPublicTest.php15
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NamespaceCoverageCoversClassTest.php20
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NamespaceCoverageMethodTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotPrivateTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotProtectedTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotPublicTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NamespaceCoveragePrivateTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NamespaceCoverageProtectedTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NamespaceCoveragePublicTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NamespaceCoveredClass.php38
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NamespaceCoveredFunction.php7
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NoArgTestCaseTest.php7
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NoTestCaseClass.php4
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NoTestCases.php7
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NonStatic.php8
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NotExistingCoveredElementTest.php24
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NotPublicTestCase.php11
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NotVoidTestCase.php4
-rw-r--r--vendor/phpunit/phpunit/tests/_files/NothingTest.php7
-rw-r--r--vendor/phpunit/phpunit/tests/_files/OneTestCase.php11
-rw-r--r--vendor/phpunit/phpunit/tests/_files/OutputTestCase.php27
-rw-r--r--vendor/phpunit/phpunit/tests/_files/OverrideTestCase.php7
-rw-r--r--vendor/phpunit/phpunit/tests/_files/RequirementsClassBeforeClassHookTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/RequirementsClassDocBlockTest.php22
-rw-r--r--vendor/phpunit/phpunit/tests/_files/RequirementsTest.php345
-rw-r--r--vendor/phpunit/phpunit/tests/_files/SampleArrayAccess.php36
-rw-r--r--vendor/phpunit/phpunit/tests/_files/SampleClass.php14
-rw-r--r--vendor/phpunit/phpunit/tests/_files/Singleton.php22
-rw-r--r--vendor/phpunit/phpunit/tests/_files/StackTest.php24
-rw-r--r--vendor/phpunit/phpunit/tests/_files/StatusTest.php37
-rw-r--r--vendor/phpunit/phpunit/tests/_files/StopOnWarningTestSuite.php13
-rw-r--r--vendor/phpunit/phpunit/tests/_files/StopsOnWarningTest.php7
-rw-r--r--vendor/phpunit/phpunit/tests/_files/Struct.php10
-rw-r--r--vendor/phpunit/phpunit/tests/_files/Success.php7
-rw-r--r--vendor/phpunit/phpunit/tests/_files/TemplateMethodsTest.php51
-rw-r--r--vendor/phpunit/phpunit/tests/_files/TestAutoreferenced.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/TestDoxGroupTest.php18
-rw-r--r--vendor/phpunit/phpunit/tests/_files/TestGeneratorMaker.php11
-rw-r--r--vendor/phpunit/phpunit/tests/_files/TestIncomplete.php8
-rw-r--r--vendor/phpunit/phpunit/tests/_files/TestIterator.php36
-rw-r--r--vendor/phpunit/phpunit/tests/_files/TestIterator2.php35
-rw-r--r--vendor/phpunit/phpunit/tests/_files/TestSkipped.php8
-rw-r--r--vendor/phpunit/phpunit/tests/_files/TestTestError.php8
-rw-r--r--vendor/phpunit/phpunit/tests/_files/TestWithTest.php24
-rw-r--r--vendor/phpunit/phpunit/tests/_files/ThrowExceptionTestCase.php8
-rw-r--r--vendor/phpunit/phpunit/tests/_files/ThrowNoExceptionTestCase.php7
-rw-r--r--vendor/phpunit/phpunit/tests/_files/WasRun.php10
-rw-r--r--vendor/phpunit/phpunit/tests/_files/bar.xml1
-rw-r--r--vendor/phpunit/phpunit/tests/_files/configuration.colors.empty.xml1
-rw-r--r--vendor/phpunit/phpunit/tests/_files/configuration.colors.false.xml1
-rw-r--r--vendor/phpunit/phpunit/tests/_files/configuration.colors.invalid.xml1
-rw-r--r--vendor/phpunit/phpunit/tests/_files/configuration.colors.true.xml1
-rw-r--r--vendor/phpunit/phpunit/tests/_files/configuration.custom-printer.xml2
-rw-r--r--vendor/phpunit/phpunit/tests/_files/configuration.suites.xml6
-rw-r--r--vendor/phpunit/phpunit/tests/_files/configuration.xml121
-rw-r--r--vendor/phpunit/phpunit/tests/_files/configuration_empty.xml49
-rw-r--r--vendor/phpunit/phpunit/tests/_files/configuration_stop_on_warning.xml2
-rw-r--r--vendor/phpunit/phpunit/tests/_files/configuration_xinclude.xml74
-rw-r--r--vendor/phpunit/phpunit/tests/_files/expectedFileFormat.txt1
-rw-r--r--vendor/phpunit/phpunit/tests/_files/foo.xml1
-rw-r--r--vendor/phpunit/phpunit/tests/_files/phpt-for-coverage.phpt8
-rw-r--r--vendor/phpunit/phpunit/tests/_files/phpt-xfail.phpt11
-rw-r--r--vendor/phpunit/phpunit/tests/_files/phpunit-example-extension/phpunit.xml10
-rw-r--r--vendor/phpunit/phpunit/tests/_files/phpunit-example-extension/tests/OneTest.php12
-rw-r--r--vendor/phpunit/phpunit/tests/_files/phpunit-example-extension/tools/phpunit.d/phpunit-example-extension-1.0.0.pharbin0 -> 3187 bytes
-rw-r--r--vendor/phpunit/phpunit/tests/_files/structureAttributesAreSameButValuesAreNot.xml10
-rw-r--r--vendor/phpunit/phpunit/tests/_files/structureExpected.xml10
-rw-r--r--vendor/phpunit/phpunit/tests/_files/structureIgnoreTextNodes.xml13
-rw-r--r--vendor/phpunit/phpunit/tests/_files/structureIsSameButDataIsNot.xml10
-rw-r--r--vendor/phpunit/phpunit/tests/_files/structureWrongNumberOfAttributes.xml10
-rw-r--r--vendor/phpunit/phpunit/tests/_files/structureWrongNumberOfNodes.xml9
-rw-r--r--vendor/phpunit/phpunit/tests/bootstrap.php6
-rw-r--r--vendor/psr/http-message/CHANGELOG.md36
-rw-r--r--vendor/psr/http-message/LICENSE19
-rw-r--r--vendor/psr/http-message/README.md13
-rw-r--r--vendor/psr/http-message/composer.json26
-rw-r--r--vendor/psr/http-message/src/MessageInterface.php187
-rw-r--r--vendor/psr/http-message/src/RequestInterface.php129
-rw-r--r--vendor/psr/http-message/src/ResponseInterface.php68
-rw-r--r--vendor/psr/http-message/src/ServerRequestInterface.php261
-rw-r--r--vendor/psr/http-message/src/StreamInterface.php158
-rw-r--r--vendor/psr/http-message/src/UploadedFileInterface.php123
-rw-r--r--vendor/psr/http-message/src/UriInterface.php323
-rw-r--r--vendor/sebastian/code-unit-reverse-lookup/.gitignore4
-rw-r--r--vendor/sebastian/code-unit-reverse-lookup/.php_cs67
-rw-r--r--vendor/sebastian/code-unit-reverse-lookup/.travis.yml25
-rw-r--r--vendor/sebastian/code-unit-reverse-lookup/ChangeLog.md10
-rw-r--r--vendor/sebastian/code-unit-reverse-lookup/LICENSE33
-rw-r--r--vendor/sebastian/code-unit-reverse-lookup/README.md14
-rw-r--r--vendor/sebastian/code-unit-reverse-lookup/build.xml22
-rw-r--r--vendor/sebastian/code-unit-reverse-lookup/composer.json28
-rw-r--r--vendor/sebastian/code-unit-reverse-lookup/phpunit.xml21
-rw-r--r--vendor/sebastian/code-unit-reverse-lookup/src/Wizard.php111
-rw-r--r--vendor/sebastian/code-unit-reverse-lookup/tests/WizardTest.php45
-rw-r--r--vendor/sebastian/comparator/.gitignore6
-rw-r--r--vendor/sebastian/comparator/.travis.yml25
-rw-r--r--vendor/sebastian/comparator/LICENSE33
-rw-r--r--vendor/sebastian/comparator/README.md39
-rw-r--r--vendor/sebastian/comparator/build.xml34
-rw-r--r--vendor/sebastian/comparator/build/travis-ci.xml11
-rw-r--r--vendor/sebastian/comparator/composer.json44
-rw-r--r--vendor/sebastian/comparator/phpunit.xml.dist21
-rw-r--r--vendor/sebastian/comparator/src/ArrayComparator.php132
-rw-r--r--vendor/sebastian/comparator/src/Comparator.php64
-rw-r--r--vendor/sebastian/comparator/src/ComparisonFailure.php129
-rw-r--r--vendor/sebastian/comparator/src/DOMNodeComparator.php107
-rw-r--r--vendor/sebastian/comparator/src/DateTimeComparator.php77
-rw-r--r--vendor/sebastian/comparator/src/DoubleComparator.php56
-rw-r--r--vendor/sebastian/comparator/src/ExceptionComparator.php51
-rw-r--r--vendor/sebastian/comparator/src/Factory.php107
-rw-r--r--vendor/sebastian/comparator/src/MockObjectComparator.php45
-rw-r--r--vendor/sebastian/comparator/src/NumericComparator.php68
-rw-r--r--vendor/sebastian/comparator/src/ObjectComparator.php105
-rw-r--r--vendor/sebastian/comparator/src/ResourceComparator.php52
-rw-r--r--vendor/sebastian/comparator/src/ScalarComparator.php90
-rw-r--r--vendor/sebastian/comparator/src/SplObjectStorageComparator.php69
-rw-r--r--vendor/sebastian/comparator/src/TypeComparator.php59
-rw-r--r--vendor/sebastian/comparator/tests/ArrayComparatorTest.php163
-rw-r--r--vendor/sebastian/comparator/tests/DOMNodeComparatorTest.php162
-rw-r--r--vendor/sebastian/comparator/tests/DateTimeComparatorTest.php216
-rw-r--r--vendor/sebastian/comparator/tests/DoubleComparatorTest.php134
-rw-r--r--vendor/sebastian/comparator/tests/ExceptionComparatorTest.php136
-rw-r--r--vendor/sebastian/comparator/tests/FactoryTest.php115
-rw-r--r--vendor/sebastian/comparator/tests/MockObjectComparatorTest.php166
-rw-r--r--vendor/sebastian/comparator/tests/NumericComparatorTest.php122
-rw-r--r--vendor/sebastian/comparator/tests/ObjectComparatorTest.php150
-rw-r--r--vendor/sebastian/comparator/tests/ResourceComparatorTest.php120
-rw-r--r--vendor/sebastian/comparator/tests/ScalarComparatorTest.php158
-rw-r--r--vendor/sebastian/comparator/tests/SplObjectStorageComparatorTest.php137
-rw-r--r--vendor/sebastian/comparator/tests/TypeComparatorTest.php104
-rw-r--r--vendor/sebastian/comparator/tests/_files/Author.php28
-rw-r--r--vendor/sebastian/comparator/tests/_files/Book.php21
-rw-r--r--vendor/sebastian/comparator/tests/_files/ClassWithToString.php19
-rw-r--r--vendor/sebastian/comparator/tests/_files/SampleClass.php29
-rw-r--r--vendor/sebastian/comparator/tests/_files/Struct.php25
-rw-r--r--vendor/sebastian/comparator/tests/_files/TestClass.php14
-rw-r--r--vendor/sebastian/comparator/tests/_files/TestClassComparator.php14
-rw-r--r--vendor/sebastian/comparator/tests/autoload.php38
-rw-r--r--vendor/sebastian/comparator/tests/bootstrap.php7
-rw-r--r--vendor/sebastian/diff/.gitignore4
-rw-r--r--vendor/sebastian/diff/.php_cs79
-rw-r--r--vendor/sebastian/diff/.travis.yml31
-rw-r--r--vendor/sebastian/diff/LICENSE33
-rw-r--r--vendor/sebastian/diff/README.md126
-rw-r--r--vendor/sebastian/diff/build.xml22
-rw-r--r--vendor/sebastian/diff/composer.json33
-rw-r--r--vendor/sebastian/diff/phpunit.xml19
-rw-r--r--vendor/sebastian/diff/src/Chunk.php103
-rw-r--r--vendor/sebastian/diff/src/Diff.php73
-rw-r--r--vendor/sebastian/diff/src/Differ.php399
-rw-r--r--vendor/sebastian/diff/src/LCS/LongestCommonSubsequence.php27
-rw-r--r--vendor/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php95
-rw-r--r--vendor/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php74
-rw-r--r--vendor/sebastian/diff/src/Line.php54
-rw-r--r--vendor/sebastian/diff/src/Parser.php110
-rw-r--r--vendor/sebastian/diff/tests/ChunkTest.php68
-rw-r--r--vendor/sebastian/diff/tests/DiffTest.php55
-rw-r--r--vendor/sebastian/diff/tests/DifferTest.php415
-rw-r--r--vendor/sebastian/diff/tests/LCS/LongestCommonSubsequenceTest.php198
-rw-r--r--vendor/sebastian/diff/tests/LCS/MemoryEfficientImplementationTest.php22
-rw-r--r--vendor/sebastian/diff/tests/LCS/TimeEfficientImplementationTest.php22
-rw-r--r--vendor/sebastian/diff/tests/LineTest.php44
-rw-r--r--vendor/sebastian/diff/tests/ParserTest.php151
-rw-r--r--vendor/sebastian/diff/tests/fixtures/patch.txt9
-rw-r--r--vendor/sebastian/diff/tests/fixtures/patch2.txt21
-rw-r--r--vendor/sebastian/environment/.gitignore4
-rw-r--r--vendor/sebastian/environment/.travis.yml16
-rw-r--r--vendor/sebastian/environment/LICENSE33
-rw-r--r--vendor/sebastian/environment/README.md72
-rw-r--r--vendor/sebastian/environment/build.xml26
-rw-r--r--vendor/sebastian/environment/composer.json30
-rw-r--r--vendor/sebastian/environment/phpunit.xml20
-rw-r--r--vendor/sebastian/environment/src/Console.php113
-rw-r--r--vendor/sebastian/environment/src/Runtime.php194
-rw-r--r--vendor/sebastian/environment/tests/ConsoleTest.php62
-rw-r--r--vendor/sebastian/environment/tests/RuntimeTest.php120
-rw-r--r--vendor/sebastian/exporter/.gitignore9
-rw-r--r--vendor/sebastian/exporter/.travis.yml23
-rw-r--r--vendor/sebastian/exporter/LICENSE33
-rw-r--r--vendor/sebastian/exporter/README.md172
-rw-r--r--vendor/sebastian/exporter/build.xml27
-rw-r--r--vendor/sebastian/exporter/composer.json48
-rw-r--r--vendor/sebastian/exporter/phpunit.xml.dist21
-rw-r--r--vendor/sebastian/exporter/src/Exporter.php303
-rw-r--r--vendor/sebastian/exporter/tests/ExporterTest.php358
-rw-r--r--vendor/sebastian/global-state/.gitignore6
-rw-r--r--vendor/sebastian/global-state/.travis.yml20
-rw-r--r--vendor/sebastian/global-state/LICENSE33
-rw-r--r--vendor/sebastian/global-state/README.md15
-rw-r--r--vendor/sebastian/global-state/build.xml33
-rw-r--r--vendor/sebastian/global-state/composer.json37
-rw-r--r--vendor/sebastian/global-state/phpunit.xml.dist21
-rw-r--r--vendor/sebastian/global-state/src/Blacklist.php149
-rw-r--r--vendor/sebastian/global-state/src/CodeExporter.php93
-rw-r--r--vendor/sebastian/global-state/src/Exception.php17
-rw-r--r--vendor/sebastian/global-state/src/Restorer.php141
-rw-r--r--vendor/sebastian/global-state/src/RuntimeException.php17
-rw-r--r--vendor/sebastian/global-state/src/Snapshot.php423
-rw-r--r--vendor/sebastian/global-state/tests/BlacklistTest.php113
-rw-r--r--vendor/sebastian/global-state/tests/SnapshotTest.php119
-rw-r--r--vendor/sebastian/global-state/tests/_fixture/BlacklistedChildClass.php17
-rw-r--r--vendor/sebastian/global-state/tests/_fixture/BlacklistedClass.php18
-rw-r--r--vendor/sebastian/global-state/tests/_fixture/BlacklistedImplementor.php18
-rw-r--r--vendor/sebastian/global-state/tests/_fixture/BlacklistedInterface.php17
-rw-r--r--vendor/sebastian/global-state/tests/_fixture/SnapshotClass.php37
-rw-r--r--vendor/sebastian/global-state/tests/_fixture/SnapshotDomDocument.php19
-rw-r--r--vendor/sebastian/global-state/tests/_fixture/SnapshotFunctions.php15
-rw-r--r--vendor/sebastian/global-state/tests/_fixture/SnapshotTrait.php17
-rw-r--r--vendor/sebastian/object-enumerator/.gitignore8
-rw-r--r--vendor/sebastian/object-enumerator/.php_cs67
-rw-r--r--vendor/sebastian/object-enumerator/.travis.yml23
-rw-r--r--vendor/sebastian/object-enumerator/ChangeLog.md25
-rw-r--r--vendor/sebastian/object-enumerator/LICENSE33
-rw-r--r--vendor/sebastian/object-enumerator/README.md14
-rw-r--r--vendor/sebastian/object-enumerator/build.xml23
-rw-r--r--vendor/sebastian/object-enumerator/composer.json34
-rw-r--r--vendor/sebastian/object-enumerator/phpunit.xml20
-rw-r--r--vendor/sebastian/object-enumerator/src/Enumerator.php93
-rw-r--r--vendor/sebastian/object-enumerator/src/Exception.php15
-rw-r--r--vendor/sebastian/object-enumerator/src/InvalidArgumentException.php15
-rw-r--r--vendor/sebastian/object-enumerator/tests/EnumeratorTest.php138
-rw-r--r--vendor/sebastian/object-enumerator/tests/Fixtures/ExceptionThrower.php28
-rw-r--r--vendor/sebastian/recursion-context/.gitignore9
-rw-r--r--vendor/sebastian/recursion-context/.travis.yml21
-rw-r--r--vendor/sebastian/recursion-context/LICENSE33
-rw-r--r--vendor/sebastian/recursion-context/README.md14
-rw-r--r--vendor/sebastian/recursion-context/build.xml27
-rw-r--r--vendor/sebastian/recursion-context/composer.json36
-rw-r--r--vendor/sebastian/recursion-context/phpunit.xml.dist20
-rw-r--r--vendor/sebastian/recursion-context/src/Context.php167
-rw-r--r--vendor/sebastian/recursion-context/src/Exception.php17
-rw-r--r--vendor/sebastian/recursion-context/src/InvalidArgumentException.php17
-rw-r--r--vendor/sebastian/recursion-context/tests/ContextTest.php144
-rw-r--r--vendor/sebastian/resource-operations/.gitignore3
-rw-r--r--vendor/sebastian/resource-operations/LICENSE33
-rw-r--r--vendor/sebastian/resource-operations/README.md16
-rw-r--r--vendor/sebastian/resource-operations/build.xml24
-rwxr-xr-xvendor/sebastian/resource-operations/build/generate.php62
-rw-r--r--vendor/sebastian/resource-operations/composer.json26
-rw-r--r--vendor/sebastian/resource-operations/src/ResourceOperations.php670
-rw-r--r--vendor/sebastian/version/.gitattributes1
-rw-r--r--vendor/sebastian/version/.gitignore1
-rw-r--r--vendor/sebastian/version/.php_cs66
-rw-r--r--vendor/sebastian/version/LICENSE33
-rw-r--r--vendor/sebastian/version/README.md43
-rw-r--r--vendor/sebastian/version/composer.json29
-rw-r--r--vendor/sebastian/version/src/Version.php109
-rw-r--r--vendor/symfony/polyfill-ctype/Ctype.php227
-rw-r--r--vendor/symfony/polyfill-ctype/LICENSE19
-rw-r--r--vendor/symfony/polyfill-ctype/README.md12
-rw-r--r--vendor/symfony/polyfill-ctype/bootstrap.php26
-rw-r--r--vendor/symfony/polyfill-ctype/composer.json34
-rw-r--r--vendor/symfony/yaml/.gitignore3
-rw-r--r--vendor/symfony/yaml/CHANGELOG.md179
-rw-r--r--vendor/symfony/yaml/Command/LintCommand.php250
-rw-r--r--vendor/symfony/yaml/Dumper.php97
-rw-r--r--vendor/symfony/yaml/Escaper.php101
-rw-r--r--vendor/symfony/yaml/Exception/DumpException.php21
-rw-r--r--vendor/symfony/yaml/Exception/ExceptionInterface.php21
-rw-r--r--vendor/symfony/yaml/Exception/ParseException.php139
-rw-r--r--vendor/symfony/yaml/Exception/RuntimeException.php21
-rw-r--r--vendor/symfony/yaml/Inline.php744
-rw-r--r--vendor/symfony/yaml/LICENSE19
-rw-r--r--vendor/symfony/yaml/Parser.php1095
-rw-r--r--vendor/symfony/yaml/README.md13
-rw-r--r--vendor/symfony/yaml/Tag/TaggedValue.php38
-rw-r--r--vendor/symfony/yaml/Tests/Command/LintCommandTest.php139
-rw-r--r--vendor/symfony/yaml/Tests/DumperTest.php429
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/YtsAnchorAlias.yml31
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/YtsBasicTests.yml202
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/YtsBlockMapping.yml51
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/YtsDocumentSeparator.yml85
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/YtsErrorTests.yml25
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/YtsFlowCollections.yml60
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/YtsFoldedScalars.yml176
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/YtsNullsAndEmpties.yml45
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/YtsSpecificationExamples.yml1662
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/YtsTypeTransfers.yml224
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/arrow.gifbin0 -> 185 bytes
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/booleanMappingKeys.yml11
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/embededPhp.yml1
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/escapedCharacters.yml155
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/index.yml18
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml14
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block_leading_space_in_first_line.yml4
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/nonStringKeys.yml3
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/not_readable.yml18
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/nullMappingKey.yml9
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/numericMappingKeys.yml23
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/sfComments.yml76
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/sfCompact.yml159
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/sfMergeKey.yml61
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/sfObjects.yml11
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/sfQuotes.yml33
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/sfTests.yml140
-rw-r--r--vendor/symfony/yaml/Tests/Fixtures/unindentedCollections.yml82
-rw-r--r--vendor/symfony/yaml/Tests/InlineTest.php760
-rw-r--r--vendor/symfony/yaml/Tests/ParseExceptionTest.php34
-rw-r--r--vendor/symfony/yaml/Tests/ParserTest.php2104
-rw-r--r--vendor/symfony/yaml/Tests/YamlTest.php44
-rw-r--r--vendor/symfony/yaml/Unescaper.php138
-rw-r--r--vendor/symfony/yaml/Yaml.php102
-rw-r--r--vendor/symfony/yaml/composer.json43
-rw-r--r--vendor/symfony/yaml/phpunit.xml.dist30
-rw-r--r--vendor/webmozart/assert/.composer-auth.json7
-rw-r--r--vendor/webmozart/assert/.styleci.yml11
-rw-r--r--vendor/webmozart/assert/CHANGELOG.md53
-rw-r--r--vendor/webmozart/assert/LICENSE20
-rw-r--r--vendor/webmozart/assert/README.md252
-rw-r--r--vendor/webmozart/assert/composer.json34
-rw-r--r--vendor/webmozart/assert/src/Assert.php1087
1480 files changed, 148718 insertions, 0 deletions
diff --git a/COPYING b/COPYING
new file mode 100755
index 0000000..dba13ed
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,661 @@
+ GNU AFFERO GENERAL PUBLIC LICENSE
+ Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+ A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate. Many developers of free software are heartened and
+encouraged by the resulting cooperation. However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+ The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community. It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server. Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+ An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals. This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU Affero General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Remote Network Interaction; Use with the GNU General Public License.
+
+ Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software. This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time. Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source. For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code. There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+<http://www.gnu.org/licenses/>.
diff --git a/Makefile b/Makefile
new file mode 100755
index 0000000..ada504f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,157 @@
+# This file is licensed under the Affero General Public License version 3 or
+# later. See the COPYING file.
+# @author Bernhard Posselt <dev@bernhard-posselt.com>
+# @copyright Bernhard Posselt 2016
+
+# Generic Makefile for building and packaging a Nextcloud app which uses npm and
+# Composer.
+#
+# Dependencies:
+# * make
+# * which
+# * curl: used if phpunit and composer are not installed to fetch them from the web
+# * tar: for building the archive
+# * npm: for building and testing everything JS
+#
+# If no composer.json is in the app root directory, the Composer step
+# will be skipped. The same goes for the package.json which can be located in
+# the app root or the js/ directory.
+#
+# The npm command by launches the npm build script:
+#
+# npm run build
+#
+# The npm test command launches the npm test script:
+#
+# npm run test
+#
+# The idea behind this is to be completely testing and build tool agnostic. All
+# build tools and additional package managers should be installed locally in
+# your project, since this won't pollute people's global namespace.
+#
+# The following npm scripts in your package.json install and update the bower
+# and npm dependencies and use gulp as build system (notice how everything is
+# run from the node_modules folder):
+#
+# "scripts": {
+# "test": "node node_modules/gulp-cli/bin/gulp.js karma",
+# "prebuild": "npm install && node_modules/bower/bin/bower install && node_modules/bower/bin/bower update",
+# "build": "node node_modules/gulp-cli/bin/gulp.js"
+# },
+
+app_name=$(notdir $(CURDIR))
+build_tools_directory=$(CURDIR)/build/tools
+source_build_directory=$(CURDIR)/build/artifacts/source
+source_package_name=$(source_build_directory)/$(app_name)
+appstore_build_directory=$(CURDIR)/build/artifacts/appstore
+appstore_package_name=$(appstore_build_directory)/$(app_name)
+npm=$(shell which npm 2> /dev/null)
+composer=$(shell which composer 2> /dev/null)
+
+all: build
+
+# Fetches the PHP and JS dependencies and compiles the JS. If no composer.json
+# is present, the composer step is skipped, if no package.json or js/package.json
+# is present, the npm step is skipped
+.PHONY: build
+build:
+ifneq (,$(wildcard $(CURDIR)/composer.json))
+ make composer
+endif
+ifneq (,$(wildcard $(CURDIR)/package.json))
+ make npm
+endif
+ifneq (,$(wildcard $(CURDIR)/js/package.json))
+ make npm
+endif
+
+# Installs and updates the composer dependencies. If composer is not installed
+# a copy is fetched from the web
+.PHONY: composer
+composer:
+ifeq (, $(composer))
+ @echo "No composer command available, downloading a copy from the web"
+ mkdir -p $(build_tools_directory)
+ curl -sS https://getcomposer.org/installer | php
+ mv composer.phar $(build_tools_directory)
+ php $(build_tools_directory)/composer.phar install --prefer-dist
+ php $(build_tools_directory)/composer.phar update --prefer-dist
+else
+ composer install --prefer-dist
+ composer update --prefer-dist
+endif
+
+# Installs npm dependencies
+.PHONY: npm
+npm:
+ifeq (,$(wildcard $(CURDIR)/package.json))
+ cd js && $(npm) run build
+else
+ npm run build
+endif
+
+# Removes the appstore build
+.PHONY: clean
+clean:
+ rm -rf ./build
+
+# Same as clean but also removes dependencies installed by composer, bower and
+# npm
+.PHONY: distclean
+distclean: clean
+ rm -rf vendor
+ rm -rf node_modules
+ rm -rf js/vendor
+ rm -rf js/node_modules
+
+# Builds the source and appstore package
+.PHONY: dist
+dist:
+ make source
+ make appstore
+
+# Builds the source package
+.PHONY: source
+source:
+ rm -rf $(source_build_directory)
+ mkdir -p $(source_build_directory)
+ tar cvzf $(source_package_name).tar.gz ../$(app_name) \
+ --exclude-vcs \
+ --exclude="../$(app_name)/build" \
+ --exclude="../$(app_name)/js/node_modules" \
+ --exclude="../$(app_name)/node_modules" \
+ --exclude="../$(app_name)/*.log" \
+ --exclude="../$(app_name)/js/*.log" \
+
+# Builds the source package for the app store, ignores php and js tests
+.PHONY: appstore
+appstore:
+ rm -rf $(appstore_build_directory)
+ mkdir -p $(appstore_build_directory)
+ tar cvzf $(appstore_package_name).tar.gz ../$(app_name) \
+ --exclude-vcs \
+ --exclude="../$(app_name)/build" \
+ --exclude="../$(app_name)/tests" \
+ --exclude="../$(app_name)/Makefile" \
+ --exclude="../$(app_name)/*.log" \
+ --exclude="../$(app_name)/phpunit*xml" \
+ --exclude="../$(app_name)/composer.*" \
+ --exclude="../$(app_name)/js/node_modules" \
+ --exclude="../$(app_name)/js/tests" \
+ --exclude="../$(app_name)/js/test" \
+ --exclude="../$(app_name)/js/*.log" \
+ --exclude="../$(app_name)/js/package.json" \
+ --exclude="../$(app_name)/js/bower.json" \
+ --exclude="../$(app_name)/js/karma.*" \
+ --exclude="../$(app_name)/js/protractor.*" \
+ --exclude="../$(app_name)/package.json" \
+ --exclude="../$(app_name)/bower.json" \
+ --exclude="../$(app_name)/karma.*" \
+ --exclude="../$(app_name)/protractor\.*" \
+ --exclude="../$(app_name)/.*" \
+ --exclude="../$(app_name)/js/.*" \
+
+.PHONY: test
+test: composer
+ $(CURDIR)/vendor/phpunit/phpunit/phpunit -c phpunit.xml
+ $(CURDIR)/vendor/phpunit/phpunit/phpunit -c phpunit.integration.xml
diff --git a/README.md b/README.md
new file mode 100755
index 0000000..884e52e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,4 @@
+# Carnet
+Place this app in **nextcloud/apps/**
+
+
diff --git a/appinfo/app.php b/appinfo/app.php
new file mode 100644
index 0000000..3fb4915
--- /dev/null
+++ b/appinfo/app.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * @author Christoph Wurst <christoph@winzerhof-wurst.at>
+ * @author Jan-Christoph Borchardt <hey@jancborchardt.net>
+ * @author Thomas Imbreckx <zinks@iozero.be>
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * Mail
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+namespace OCA\Carnet\AppInfo;
+use \OCP\AppFramework\App;
+use OCA\Mail\HordeTranslationHandler;
+if ((@include_once __DIR__ . '/../vendor/autoload.php')===false) {
+ throw new Exception('Cannot include autoload. Did you run install dependencies using composer?');
+}
+class Application extends App {
+
+ public function __construct(array $urlParams=array()){
+ parent::__construct('carnet', $urlParams);
+
+ $container = $this->getContainer();
+
+
+
+ $container->registerService('AppFolder', function($c) {
+ return $c->query('ServerContainer')->getAppFolder();
+ });
+
+ }
+}
+?> \ No newline at end of file
diff --git a/appinfo/info.xml b/appinfo/info.xml
new file mode 100755
index 0000000..1bee173
--- /dev/null
+++ b/appinfo/info.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
+ <id>carnet</id>
+ <name>Carnet</name>
+ <summary>Carnet on Nextcloud</summary>
+ <description><![CDATA[Carnet on Nextcloud]]></description>
+ <version>0.0.1</version>
+ <licence>agpl</licence>
+ <author mail="phie@phie.ovh" >Phie</author>
+ <namespace>Carnet</namespace>
+ <category>tools</category>
+ <bugs>https://github.com/PhieF/CarnetNextcloud/issues</bugs>
+ <dependencies>
+ <nextcloud min-version="13" max-version="13"/>
+ </dependencies>
+ <navigations>
+ <navigation>
+ <name>Carnet</name>
+ <route>carnet.page.index</route>
+ </navigation>
+ </navigations>
+</info>
diff --git a/appinfo/routes.php b/appinfo/routes.php
new file mode 100755
index 0000000..56ceac1
--- /dev/null
+++ b/appinfo/routes.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Create your routes in here. The name is the lowercase name of the controller
+ * without the controller part, the stuff after the hash is the method.
+ * e.g. page#index -> OCA\QuickDoc\Controller\PageController->index()
+ *
+ * The controller class has to be registered in the application.php file since
+ * it's instantiated in there
+ */
+
+return [
+ 'routes' => [
+ ['name' => 'page#index', 'url' => '/', 'verb' => 'GET'],
+ ['name' => 'page#writer', 'url' => '/writer', 'verb' => 'GET'],
+ ['name' => 'page#do_echo', 'url' => '/echo', 'verb' => 'POST'],
+ ['name' => 'note#openNote', 'url' => '/note/open', 'verb' => 'GET'],
+ ['name' => 'note#saveTextToOpenNote', 'url' => '/note/saveText', 'verb' => 'POST'],
+ ['name' => 'note#listDir', 'url' => '/browser/list', 'verb' => 'GET'],
+ ['name' => 'note#getRecent', 'url' => '/recentdb', 'verb' => 'GET'],
+ ['name' => 'note#postActions', 'url' => '/recentdb/action', 'verb' => 'POST'],
+ ['name' => 'note#getMetadata', 'url' => '/metadata', 'verg' => 'GET'],
+ ['name' => 'note#create', 'url' => '/notes', 'verb' => 'POST'],
+ ['name' => 'note#update', 'url' => '/notes/{id}', 'verb' => 'PUT'],
+ ['name' => 'note#destroy', 'url' => '/notes/{id}', 'verb' => 'DELETE']
+ ]
+]; \ No newline at end of file
diff --git a/composer.json b/composer.json
new file mode 100755
index 0000000..e015641
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,17 @@
+{
+ "name": "Quick Doc",
+ "description": "QuickDoc on Nextcloud",
+ "type": "project",
+ "license": "AGPL",
+ "authors": [
+ {
+ "name": "Phie"
+ }
+ ],
+ "require": {
+ "nelexa/zip": "^3.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.4"
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..6aa1f3f
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,1513 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "653e4fac06071d2911fae036e8265b8d",
+ "packages": [
+ {
+ "name": "nelexa/zip",
+ "version": "3.1.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Ne-Lexa/php-zip.git",
+ "reference": "251ce11bdc4754962f29cd2d31014549377ea617"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Ne-Lexa/php-zip/zipball/251ce11bdc4754962f29cd2d31014549377ea617",
+ "reference": "251ce11bdc4754962f29cd2d31014549377ea617",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.5 || ^7.0",
+ "psr/http-message": "^1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8|~5.7",
+ "zendframework/zend-diactoros": "^1.4"
+ },
+ "suggest": {
+ "ext-bz2": "Needed to support BZIP2 compression",
+ "ext-mcrypt": "Needed to support encrypt zip entries or use ext-openssl",
+ "ext-openssl": "Needed to support encrypt zip entries or use ext-mcrypt"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PhpZip\\": "src/PhpZip"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ne-Lexa",
+ "email": "alexey@nelexa.ru",
+ "role": "Developer"
+ }
+ ],
+ "description": "PhpZip is a php-library for extended work with ZIP-archives. Open, create, update, delete, extract and get info tool. Supports appending to existing ZIP files, WinZip AES encryption, Traditional PKWARE Encryption, ZipAlign tool, BZIP2 compression, external file attributes and ZIP64 extensions. Alternative ZipArchive. It does not require php-zip extension.",
+ "homepage": "https://github.com/Ne-Lexa/php-zip",
+ "keywords": [
+ "archive",
+ "extract",
+ "unzip",
+ "winzip",
+ "zip",
+ "zipalign",
+ "ziparchive"
+ ],
+ "time": "2018-04-25T09:44:11+00:00"
+ },
+ {
+ "name": "psr/http-message",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "time": "2016-08-06T14:39:51+00:00"
+ }
+ ],
+ "packages-dev": [
+ {
+ "name": "doctrine/instantiator",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
+ "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "athletic/athletic": "~0.1.8",
+ "ext-pdo": "*",
+ "ext-phar": "*",
+ "phpunit/phpunit": "^6.2.3",
+ "squizlabs/php_codesniffer": "^3.0.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "http://ocramius.github.com/"
+ }
+ ],
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://github.com/doctrine/instantiator",
+ "keywords": [
+ "constructor",
+ "instantiate"
+ ],
+ "time": "2017-07-22T11:58:36+00:00"
+ },
+ {
+ "name": "myclabs/deep-copy",
+ "version": "1.8.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8",
+ "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "replace": {
+ "myclabs/deep-copy": "self.version"
+ },
+ "require-dev": {
+ "doctrine/collections": "^1.0",
+ "doctrine/common": "^2.6",
+ "phpunit/phpunit": "^7.1"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "DeepCopy\\": "src/DeepCopy/"
+ },
+ "files": [
+ "src/DeepCopy/deep_copy.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Create deep copies (clones) of your objects",
+ "keywords": [
+ "clone",
+ "copy",
+ "duplicate",
+ "object",
+ "object graph"
+ ],
+ "time": "2018-06-11T23:09:50+00:00"
+ },
+ {
+ "name": "phpdocumentor/reflection-common",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+ "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
+ "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jaap van Otterdijk",
+ "email": "opensource@ijaap.nl"
+ }
+ ],
+ "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+ "homepage": "http://www.phpdoc.org",
+ "keywords": [
+ "FQSEN",
+ "phpDocumentor",
+ "phpdoc",
+ "reflection",
+ "static analysis"
+ ],
+ "time": "2017-09-11T18:02:19+00:00"
+ },
+ {
+ "name": "phpdocumentor/reflection-docblock",
+ "version": "4.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+ "reference": "94fd0001232e47129dd3504189fa1c7225010d08"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08",
+ "reference": "94fd0001232e47129dd3504189fa1c7225010d08",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0",
+ "phpdocumentor/reflection-common": "^1.0.0",
+ "phpdocumentor/type-resolver": "^0.4.0",
+ "webmozart/assert": "^1.0"
+ },
+ "require-dev": {
+ "doctrine/instantiator": "~1.0.5",
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^6.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ],
+ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+ "time": "2017-11-30T07:14:17+00:00"
+ },
+ {
+ "name": "phpdocumentor/type-resolver",
+ "version": "0.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/TypeResolver.git",
+ "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7",
+ "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.5 || ^7.0",
+ "phpdocumentor/reflection-common": "^1.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^0.9.4",
+ "phpunit/phpunit": "^5.2||^4.8.24"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ],
+ "time": "2017-07-14T14:27:02+00:00"
+ },
+ {
+ "name": "phpspec/prophecy",
+ "version": "1.8.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpspec/prophecy.git",
+ "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
+ "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.2",
+ "php": "^5.3|^7.0",
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
+ "sebastian/comparator": "^1.1|^2.0|^3.0",
+ "sebastian/recursion-context": "^1.0|^2.0|^3.0"
+ },
+ "require-dev": {
+ "phpspec/phpspec": "^2.5|^3.2",
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.8.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Prophecy\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com",
+ "homepage": "http://everzet.com"
+ },
+ {
+ "name": "Marcello Duarte",
+ "email": "marcello.duarte@gmail.com"
+ }
+ ],
+ "description": "Highly opinionated mocking framework for PHP 5.3+",
+ "homepage": "https://github.com/phpspec/prophecy",
+ "keywords": [
+ "Double",
+ "Dummy",
+ "fake",
+ "mock",
+ "spy",
+ "stub"
+ ],
+ "time": "2018-08-05T17:53:17+00:00"
+ },
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "4.0.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d",
+ "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-xmlwriter": "*",
+ "php": "^5.6 || ^7.0",
+ "phpunit/php-file-iterator": "^1.3",
+ "phpunit/php-text-template": "^1.2",
+ "phpunit/php-token-stream": "^1.4.2 || ^2.0",
+ "sebastian/code-unit-reverse-lookup": "^1.0",
+ "sebastian/environment": "^1.3.2 || ^2.0",
+ "sebastian/version": "^1.0 || ^2.0"
+ },
+ "require-dev": {
+ "ext-xdebug": "^2.1.4",
+ "phpunit/phpunit": "^5.7"
+ },
+ "suggest": {
+ "ext-xdebug": "^2.5.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+ "keywords": [
+ "coverage",
+ "testing",
+ "xunit"
+ ],
+ "time": "2017-04-02T07:44:40+00:00"
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "1.4.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4",
+ "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+ "keywords": [
+ "filesystem",
+ "iterator"
+ ],
+ "time": "2017-11-27T13:52:08+00:00"
+ },
+ {
+ "name": "phpunit/php-text-template",
+ "version": "1.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Simple template engine.",
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+ "keywords": [
+ "template"
+ ],
+ "time": "2015-06-21T13:50:34+00:00"
+ },
+ {
+ "name": "phpunit/php-timer",
+ "version": "1.0.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
+ "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Utility class for timing",
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
+ "keywords": [
+ "timer"
+ ],
+ "time": "2017-02-26T11:10:40+00:00"
+ },
+ {
+ "name": "phpunit/php-token-stream",
+ "version": "2.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+ "reference": "791198a2c6254db10131eecfe8c06670700904db"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db",
+ "reference": "791198a2c6254db10131eecfe8c06670700904db",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": "^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.2.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Wrapper around PHP's tokenizer extension.",
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
+ "keywords": [
+ "tokenizer"
+ ],
+ "time": "2017-11-27T05:48:46+00:00"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "5.7.27",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c",
+ "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "myclabs/deep-copy": "~1.3",
+ "php": "^5.6 || ^7.0",
+ "phpspec/prophecy": "^1.6.2",
+ "phpunit/php-code-coverage": "^4.0.4",
+ "phpunit/php-file-iterator": "~1.4",
+ "phpunit/php-text-template": "~1.2",
+ "phpunit/php-timer": "^1.0.6",
+ "phpunit/phpunit-mock-objects": "^3.2",
+ "sebastian/comparator": "^1.2.4",
+ "sebastian/diff": "^1.4.3",
+ "sebastian/environment": "^1.3.4 || ^2.0",
+ "sebastian/exporter": "~2.0",
+ "sebastian/global-state": "^1.1",
+ "sebastian/object-enumerator": "~2.0",
+ "sebastian/resource-operations": "~1.0",
+ "sebastian/version": "^1.0.6|^2.0.1",
+ "symfony/yaml": "~2.1|~3.0|~4.0"
+ },
+ "conflict": {
+ "phpdocumentor/reflection-docblock": "3.0.2"
+ },
+ "require-dev": {
+ "ext-pdo": "*"
+ },
+ "suggest": {
+ "ext-xdebug": "*",
+ "phpunit/php-invoker": "~1.1"
+ },
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.7.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "The PHP Unit Testing framework.",
+ "homepage": "https://phpunit.de/",
+ "keywords": [
+ "phpunit",
+ "testing",
+ "xunit"
+ ],
+ "time": "2018-02-01T05:50:59+00:00"
+ },
+ {
+ "name": "phpunit/phpunit-mock-objects",
+ "version": "3.4.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
+ "reference": "a23b761686d50a560cc56233b9ecf49597cc9118"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/a23b761686d50a560cc56233b9ecf49597cc9118",
+ "reference": "a23b761686d50a560cc56233b9ecf49597cc9118",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.2",
+ "php": "^5.6 || ^7.0",
+ "phpunit/php-text-template": "^1.2",
+ "sebastian/exporter": "^1.2 || ^2.0"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<5.4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.4"
+ },
+ "suggest": {
+ "ext-soap": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Mock Object library for PHPUnit",
+ "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
+ "keywords": [
+ "mock",
+ "xunit"
+ ],
+ "time": "2017-06-30T09:13:00+00:00"
+ },
+ {
+ "name": "sebastian/code-unit-reverse-lookup",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+ "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
+ "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7 || ^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Looks up which function or method a line of code belongs to",
+ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+ "time": "2017-03-04T06:30:41+00:00"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "1.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
+ "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "sebastian/diff": "~1.2",
+ "sebastian/exporter": "~1.2 || ~2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides the functionality to compare PHP values for equality",
+ "homepage": "http://www.github.com/sebastianbergmann/comparator",
+ "keywords": [
+ "comparator",
+ "compare",
+ "equality"
+ ],
+ "time": "2017-01-29T09:50:25+00:00"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "1.4.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4",
+ "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Diff implementation",
+ "homepage": "https://github.com/sebastianbergmann/diff",
+ "keywords": [
+ "diff"
+ ],
+ "time": "2017-05-22T07:24:03+00:00"
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
+ "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides functionality to handle HHVM/PHP environments",
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
+ "keywords": [
+ "Xdebug",
+ "environment",
+ "hhvm"
+ ],
+ "time": "2016-11-26T07:53:53+00:00"
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
+ "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "sebastian/recursion-context": "~2.0"
+ },
+ "require-dev": {
+ "ext-mbstring": "*",
+ "phpunit/phpunit": "~4.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
+ "keywords": [
+ "export",
+ "exporter"
+ ],
+ "time": "2016-11-19T08:54:04+00:00"
+ },
+ {
+ "name": "sebastian/global-state",
+ "version": "1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/global-state.git",
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.2"
+ },
+ "suggest": {
+ "ext-uopz": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Snapshotting of global state",
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
+ "keywords": [
+ "global state"
+ ],
+ "time": "2015-10-12T03:26:01+00:00"
+ },
+ {
+ "name": "sebastian/object-enumerator",
+ "version": "2.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+ "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7",
+ "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6",
+ "sebastian/recursion-context": "~2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+ "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+ "time": "2017-02-18T15:18:39+00:00"
+ },
+ {
+ "name": "sebastian/recursion-context",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
+ "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a",
+ "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides functionality to recursively process PHP variables",
+ "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
+ "time": "2016-11-19T07:33:16+00:00"
+ },
+ {
+ "name": "sebastian/resource-operations",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/resource-operations.git",
+ "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
+ "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides a list of PHP built-in functions that operate on resources",
+ "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+ "time": "2015-07-28T20:34:47+00:00"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "2.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
+ "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+ "homepage": "https://github.com/sebastianbergmann/version",
+ "time": "2016-10-03T07:35:21+00:00"
+ },
+ {
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.9.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "e3d826245268269cd66f8326bd8bc066687b4a19"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19",
+ "reference": "e3d826245268269cd66f8326bd8bc066687b4a19",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.9-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ },
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "time": "2018-08-06T14:22:27+00:00"
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "v4.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "46bc69aa91fc4ab78a96ce67873a6b0c148fd48c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/46bc69aa91fc4ab78a96ce67873a6b0c148fd48c",
+ "reference": "46bc69aa91fc4ab78a96ce67873a6b0c148fd48c",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1.3",
+ "symfony/polyfill-ctype": "~1.8"
+ },
+ "conflict": {
+ "symfony/console": "<3.4"
+ },
+ "require-dev": {
+ "symfony/console": "~3.4|~4.0"
+ },
+ "suggest": {
+ "symfony/console": "For validating YAML files using the lint command"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.1-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Yaml\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Yaml Component",
+ "homepage": "https://symfony.com",
+ "time": "2018-07-26T11:24:31+00:00"
+ },
+ {
+ "name": "webmozart/assert",
+ "version": "1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/webmozart/assert.git",
+ "reference": "0df1908962e7a3071564e857d86874dad1ef204a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a",
+ "reference": "0df1908962e7a3071564e857d86874dad1ef204a",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6",
+ "sebastian/version": "^1.0.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Webmozart\\Assert\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ }
+ ],
+ "description": "Assertions to validate method input/output with nice error messages.",
+ "keywords": [
+ "assert",
+ "check",
+ "validate"
+ ],
+ "time": "2018-01-29T19:49:41+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": [],
+ "platform-dev": []
+}
diff --git a/css/material.indigo-pink.min.css b/css/material.indigo-pink.min.css
new file mode 100755
index 0000000..ae552c7
--- /dev/null
+++ b/css/material.indigo-pink.min.css
@@ -0,0 +1,7789 @@
+/**
+ * material-design-lite - Material Design Components in CSS, JS and HTML
+ * @version v1.3.0
+ * @license Apache-2.0
+ * @copyright 2015 Google, Inc.
+ * @link https://github.com/google/material-design-lite
+ */
+
+@charset "UTF-8";
+html {
+ color: rgba(0, 0, 0, .87)
+}
+
+::-moz-selection {
+ background: #b3d4fc;
+ text-shadow: none
+}
+
+::selection {
+ background: #b3d4fc;
+ text-shadow: none
+}
+
+hr {
+ display: block;
+ height: 1px;
+ border: 0;
+ border-top: 1px solid #ccc;
+ margin: 1em 0;
+ padding: 0
+}
+
+audio,
+canvas,
+iframe,
+img,
+svg,
+video {
+ vertical-align: middle
+}
+
+fieldset {
+ border: 0;
+ margin: 0;
+ padding: 0
+}
+
+textarea {
+ resize: vertical
+}
+
+.browserupgrade {
+ margin: .2em 0;
+ background: #ccc;
+ color: #000;
+ padding: .2em 0
+}
+
+.hidden {
+ display: none !important
+}
+
+.visuallyhidden {
+ border: 0;
+ clip: rect(0 0 0 0);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ width: 1px
+}
+
+.visuallyhidden.focusable:active,
+.visuallyhidden.focusable:focus {
+ clip: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ position: static;
+ width: auto
+}
+
+.invisible {
+ visibility: hidden
+}
+
+.clearfix:before,
+.clearfix:after {
+ content: " ";
+ display: table
+}
+
+.clearfix:after {
+ clear: both
+}
+
+@media print {
+ *,
+ *:before,
+ *:after,
+ *:first-letter {
+ background: transparent !important;
+ color: #000 !important;
+ box-shadow: none !important
+ }
+ a,
+ a:visited {
+ text-decoration: underline
+ }
+ a[href]:after {
+ content: " (" attr(href)")"
+ }
+ abbr[title]:after {
+ content: " (" attr(title)")"
+ }
+ a[href^="#"]:after,
+ a[href^="javascript:"]:after {
+ content: ""
+ }
+ pre,
+ blockquote {
+ border: 1px solid #999;
+ page-break-inside: avoid
+ }
+ thead {
+ display: table-header-group
+ }
+ tr,
+ img {
+ page-break-inside: avoid
+ }
+ img {
+ max-width: 100% !important
+ }
+ p,
+ h2,
+ h3 {
+ orphans: 3;
+ widows: 3
+ }
+ h2,
+ h3 {
+ page-break-after: avoid
+ }
+}
+
+a,
+.mdl-accordion,
+.mdl-button,
+.mdl-card,
+.mdl-checkbox,
+.mdl-dropdown-menu,
+.mdl-icon-toggle,
+.mdl-item,
+.mdl-radio,
+.mdl-slider,
+.mdl-switch,
+.mdl-tabs__tab {
+ -webkit-tap-highlight-color: transparent;
+ -webkit-tap-highlight-color: rgba(255, 255, 255, 0)
+}
+
+html {
+ width: 100%;
+ height: 100%;
+ -ms-touch-action: manipulation;
+ touch-action: manipulation
+}
+
+body {
+ width: 100%;
+ min-height: 100%
+}
+
+main {
+ display: block
+}
+
+*[hidden] {
+ display: none !important
+}
+
+html,
+body {
+ font-family: "Helvetica", "Arial", sans-serif;
+ font-size: 14px;
+ font-weight: 400;
+ line-height: 20px
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p {
+ padding: 0
+}
+
+h1 small,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small {
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ font-weight: 400;
+ line-height: 1.35;
+ letter-spacing: -.02em;
+ opacity: .54;
+ font-size: .6em
+}
+
+h1 {
+ font-size: 56px;
+ line-height: 1.35;
+ letter-spacing: -.02em;
+ margin: 24px 0
+}
+
+h1,
+h2 {
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ font-weight: 400
+}
+
+h2 {
+ font-size: 45px;
+ line-height: 48px
+}
+
+h2,
+h3 {
+ margin: 24px 0
+}
+
+h3 {
+ font-size: 34px;
+ line-height: 40px
+}
+
+h3,
+h4 {
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ font-weight: 400
+}
+
+h4 {
+ font-size: 24px;
+ line-height: 32px;
+ -moz-osx-font-smoothing: grayscale;
+ margin: 24px 0 16px
+}
+
+h5 {
+ font-size: 20px;
+ font-weight: 500;
+ line-height: 1;
+ letter-spacing: .02em
+}
+
+h5,
+h6 {
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ margin: 24px 0 16px
+}
+
+h6 {
+ font-size: 16px;
+ letter-spacing: .04em
+}
+
+h6,
+p {
+ font-weight: 400;
+ line-height: 24px
+}
+
+p {
+ font-size: 14px;
+ letter-spacing: 0;
+ margin: 0 0 16px
+}
+
+a {
+ color: rgb(255, 64, 129);
+ font-weight: 500
+}
+
+blockquote {
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ position: relative;
+ font-size: 24px;
+ font-weight: 300;
+ font-style: italic;
+ line-height: 1.35;
+ letter-spacing: .08em
+}
+
+blockquote:before {
+ position: absolute;
+ left: -.5em;
+ content: '“'
+}
+
+blockquote:after {
+ content: '”';
+ margin-left: -.05em
+}
+
+mark {
+ background-color: #f4ff81
+}
+
+dt {
+ font-weight: 700
+}
+
+address {
+ font-size: 12px;
+ line-height: 1;
+ font-style: normal
+}
+
+address,
+ul,
+ol {
+ font-weight: 400;
+ letter-spacing: 0
+}
+
+ul,
+ol {
+ font-size: 14px;
+ line-height: 24px
+}
+
+.mdl-typography--display-4,
+.mdl-typography--display-4-color-contrast {
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ font-size: 112px;
+ font-weight: 300;
+ line-height: 1;
+ letter-spacing: -.04em
+}
+
+.mdl-typography--display-4-color-contrast {
+ opacity: .54
+}
+
+.mdl-typography--display-3,
+.mdl-typography--display-3-color-contrast {
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ font-size: 56px;
+ font-weight: 400;
+ line-height: 1.35;
+ letter-spacing: -.02em
+}
+
+.mdl-typography--display-3-color-contrast {
+ opacity: .54
+}
+
+.mdl-typography--display-2,
+.mdl-typography--display-2-color-contrast {
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ font-size: 45px;
+ font-weight: 400;
+ line-height: 48px
+}
+
+.mdl-typography--display-2-color-contrast {
+ opacity: .54
+}
+
+.mdl-typography--display-1,
+.mdl-typography--display-1-color-contrast {
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ font-size: 34px;
+ font-weight: 400;
+ line-height: 40px
+}
+
+.mdl-typography--display-1-color-contrast {
+ opacity: .54
+}
+
+.mdl-typography--headline,
+.mdl-typography--headline-color-contrast {
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ font-size: 24px;
+ font-weight: 400;
+ line-height: 32px;
+ -moz-osx-font-smoothing: grayscale
+}
+
+.mdl-typography--headline-color-contrast {
+ opacity: .87
+}
+
+.mdl-typography--title,
+.mdl-typography--title-color-contrast {
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ font-size: 20px;
+ font-weight: 500;
+ line-height: 1;
+ letter-spacing: .02em
+}
+
+.mdl-typography--title-color-contrast {
+ opacity: .87
+}
+
+.mdl-typography--subhead,
+.mdl-typography--subhead-color-contrast {
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ font-size: 16px;
+ font-weight: 400;
+ line-height: 24px;
+ letter-spacing: .04em
+}
+
+.mdl-typography--subhead-color-contrast {
+ opacity: .87
+}
+
+.mdl-typography--body-2,
+.mdl-typography--body-2-color-contrast {
+ font-size: 14px;
+ font-weight: 700;
+ line-height: 24px;
+ letter-spacing: 0
+}
+
+.mdl-typography--body-2-color-contrast {
+ opacity: .87
+}
+
+.mdl-typography--body-1,
+.mdl-typography--body-1-color-contrast {
+ font-size: 14px;
+ font-weight: 400;
+ line-height: 24px;
+ letter-spacing: 0
+}
+
+.mdl-typography--body-1-color-contrast {
+ opacity: .87
+}
+
+.mdl-typography--body-2-force-preferred-font,
+.mdl-typography--body-2-force-preferred-font-color-contrast {
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 24px;
+ letter-spacing: 0
+}
+
+.mdl-typography--body-2-force-preferred-font-color-contrast {
+ opacity: .87
+}
+
+.mdl-typography--body-1-force-preferred-font,
+.mdl-typography--body-1-force-preferred-font-color-contrast {
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ font-size: 14px;
+ font-weight: 400;
+ line-height: 24px;
+ letter-spacing: 0
+}
+
+.mdl-typography--body-1-force-preferred-font-color-contrast {
+ opacity: .87
+}
+
+.mdl-typography--caption,
+.mdl-typography--caption-force-preferred-font {
+ font-size: 12px;
+ font-weight: 400;
+ line-height: 1;
+ letter-spacing: 0
+}
+
+.mdl-typography--caption-force-preferred-font {
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif
+}
+
+.mdl-typography--caption-color-contrast,
+.mdl-typography--caption-force-preferred-font-color-contrast {
+ font-size: 12px;
+ font-weight: 400;
+ line-height: 1;
+ letter-spacing: 0;
+ opacity: .54
+}
+
+.mdl-typography--caption-force-preferred-font-color-contrast,
+.mdl-typography--menu {
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif
+}
+
+.mdl-typography--menu {
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 1;
+ letter-spacing: 0
+}
+
+.mdl-typography--menu-color-contrast {
+ opacity: .87
+}
+
+.mdl-typography--menu-color-contrast,
+.mdl-typography--button,
+.mdl-typography--button-color-contrast {
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 1;
+ letter-spacing: 0
+}
+
+.mdl-typography--button,
+.mdl-typography--button-color-contrast {
+ text-transform: uppercase
+}
+
+.mdl-typography--button-color-contrast {
+ opacity: .87
+}
+
+.mdl-typography--text-left {
+ text-align: left
+}
+
+.mdl-typography--text-right {
+ text-align: right
+}
+
+.mdl-typography--text-center {
+ text-align: center
+}
+
+.mdl-typography--text-justify {
+ text-align: justify
+}
+
+.mdl-typography--text-nowrap {
+ white-space: nowrap
+}
+
+.mdl-typography--text-lowercase {
+ text-transform: lowercase
+}
+
+.mdl-typography--text-uppercase {
+ text-transform: uppercase
+}
+
+.mdl-typography--text-capitalize {
+ text-transform: capitalize
+}
+
+.mdl-typography--font-thin {
+ font-weight: 200 !important
+}
+
+.mdl-typography--font-light {
+ font-weight: 300 !important
+}
+
+.mdl-typography--font-regular {
+ font-weight: 400 !important
+}
+
+.mdl-typography--font-medium {
+ font-weight: 500 !important
+}
+
+.mdl-typography--font-bold {
+ font-weight: 700 !important
+}
+
+.mdl-typography--font-black {
+ font-weight: 900 !important
+}
+
+.material-icons {
+ font-family: 'Material Icons';
+ font-weight: 400;
+ font-style: normal;
+ font-size: 24px;
+ line-height: 1;
+ letter-spacing: normal;
+ text-transform: none;
+ display: inline-block;
+ word-wrap: normal;
+ -moz-font-feature-settings: 'liga';
+ font-feature-settings: 'liga';
+ -webkit-font-feature-settings: 'liga';
+ -webkit-font-smoothing: antialiased
+}
+
+.mdl-color-text--red {
+ color: #f44336 !important
+}
+
+.mdl-color--red {
+ background-color: #f44336 !important
+}
+
+.mdl-color-text--red-50 {
+ color: #ffebee !important
+}
+
+.mdl-color--red-50 {
+ background-color: #ffebee !important
+}
+
+.mdl-color-text--red-100 {
+ color: #ffcdd2 !important
+}
+
+.mdl-color--red-100 {
+ background-color: #ffcdd2 !important
+}
+
+.mdl-color-text--red-200 {
+ color: #ef9a9a !important
+}
+
+.mdl-color--red-200 {
+ background-color: #ef9a9a !important
+}
+
+.mdl-color-text--red-300 {
+ color: #e57373 !important
+}
+
+.mdl-color--red-300 {
+ background-color: #e57373 !important
+}
+
+.mdl-color-text--red-400 {
+ color: #ef5350 !important
+}
+
+.mdl-color--red-400 {
+ background-color: #ef5350 !important
+}
+
+.mdl-color-text--red-500 {
+ color: #f44336 !important
+}
+
+.mdl-color--red-500 {
+ background-color: #f44336 !important
+}
+
+.mdl-color-text--red-600 {
+ color: #e53935 !important
+}
+
+.mdl-color--red-600 {
+ background-color: #e53935 !important
+}
+
+.mdl-color-text--red-700 {
+ color: #d32f2f !important
+}
+
+.mdl-color--red-700 {
+ background-color: #d32f2f !important
+}
+
+.mdl-color-text--red-800 {
+ color: #c62828 !important
+}
+
+.mdl-color--red-800 {
+ background-color: #c62828 !important
+}
+
+.mdl-color-text--red-900 {
+ color: #b71c1c !important
+}
+
+.mdl-color--red-900 {
+ background-color: #b71c1c !important
+}
+
+.mdl-color-text--red-A100 {
+ color: #ff8a80 !important
+}
+
+.mdl-color--red-A100 {
+ background-color: #ff8a80 !important
+}
+
+.mdl-color-text--red-A200 {
+ color: #ff5252 !important
+}
+
+.mdl-color--red-A200 {
+ background-color: #ff5252 !important
+}
+
+.mdl-color-text--red-A400 {
+ color: #ff1744 !important
+}
+
+.mdl-color--red-A400 {
+ background-color: #ff1744 !important
+}
+
+.mdl-color-text--red-A700 {
+ color: #d50000 !important
+}
+
+.mdl-color--red-A700 {
+ background-color: #d50000 !important
+}
+
+.mdl-color-text--pink {
+ color: #e91e63 !important
+}
+
+.mdl-color--pink {
+ background-color: #e91e63 !important
+}
+
+.mdl-color-text--pink-50 {
+ color: #fce4ec !important
+}
+
+.mdl-color--pink-50 {
+ background-color: #fce4ec !important
+}
+
+.mdl-color-text--pink-100 {
+ color: #f8bbd0 !important
+}
+
+.mdl-color--pink-100 {
+ background-color: #f8bbd0 !important
+}
+
+.mdl-color-text--pink-200 {
+ color: #f48fb1 !important
+}
+
+.mdl-color--pink-200 {
+ background-color: #f48fb1 !important
+}
+
+.mdl-color-text--pink-300 {
+ color: #f06292 !important
+}
+
+.mdl-color--pink-300 {
+ background-color: #f06292 !important
+}
+
+.mdl-color-text--pink-400 {
+ color: #ec407a !important
+}
+
+.mdl-color--pink-400 {
+ background-color: #ec407a !important
+}
+
+.mdl-color-text--pink-500 {
+ color: #e91e63 !important
+}
+
+.mdl-color--pink-500 {
+ background-color: #e91e63 !important
+}
+
+.mdl-color-text--pink-600 {
+ color: #d81b60 !important
+}
+
+.mdl-color--pink-600 {
+ background-color: #d81b60 !important
+}
+
+.mdl-color-text--pink-700 {
+ color: #c2185b !important
+}
+
+.mdl-color--pink-700 {
+ background-color: #c2185b !important
+}
+
+.mdl-color-text--pink-800 {
+ color: #ad1457 !important
+}
+
+.mdl-color--pink-800 {
+ background-color: #ad1457 !important
+}
+
+.mdl-color-text--pink-900 {
+ color: #880e4f !important
+}
+
+.mdl-color--pink-900 {
+ background-color: #880e4f !important
+}
+
+.mdl-color-text--pink-A100 {
+ color: #ff80ab !important
+}
+
+.mdl-color--pink-A100 {
+ background-color: #ff80ab !important
+}
+
+.mdl-color-text--pink-A200 {
+ color: #ff4081 !important
+}
+
+.mdl-color--pink-A200 {
+ background-color: #ff4081 !important
+}
+
+.mdl-color-text--pink-A400 {
+ color: #f50057 !important
+}
+
+.mdl-color--pink-A400 {
+ background-color: #f50057 !important
+}
+
+.mdl-color-text--pink-A700 {
+ color: #c51162 !important
+}
+
+.mdl-color--pink-A700 {
+ background-color: #c51162 !important
+}
+
+.mdl-color-text--purple {
+ color: #9c27b0 !important
+}
+
+.mdl-color--purple {
+ background-color: #9c27b0 !important
+}
+
+.mdl-color-text--purple-50 {
+ color: #f3e5f5 !important
+}
+
+.mdl-color--purple-50 {
+ background-color: #f3e5f5 !important
+}
+
+.mdl-color-text--purple-100 {
+ color: #e1bee7 !important
+}
+
+.mdl-color--purple-100 {
+ background-color: #e1bee7 !important
+}
+
+.mdl-color-text--purple-200 {
+ color: #ce93d8 !important
+}
+
+.mdl-color--purple-200 {
+ background-color: #ce93d8 !important
+}
+
+.mdl-color-text--purple-300 {
+ color: #ba68c8 !important
+}
+
+.mdl-color--purple-300 {
+ background-color: #ba68c8 !important
+}
+
+.mdl-color-text--purple-400 {
+ color: #ab47bc !important
+}
+
+.mdl-color--purple-400 {
+ background-color: #ab47bc !important
+}
+
+.mdl-color-text--purple-500 {
+ color: #9c27b0 !important
+}
+
+.mdl-color--purple-500 {
+ background-color: #9c27b0 !important
+}
+
+.mdl-color-text--purple-600 {
+ color: #8e24aa !important
+}
+
+.mdl-color--purple-600 {
+ background-color: #8e24aa !important
+}
+
+.mdl-color-text--purple-700 {
+ color: #7b1fa2 !important
+}
+
+.mdl-color--purple-700 {
+ background-color: #7b1fa2 !important
+}
+
+.mdl-color-text--purple-800 {
+ color: #6a1b9a !important
+}
+
+.mdl-color--purple-800 {
+ background-color: #6a1b9a !important
+}
+
+.mdl-color-text--purple-900 {
+ color: #4a148c !important
+}
+
+.mdl-color--purple-900 {
+ background-color: #4a148c !important
+}
+
+.mdl-color-text--purple-A100 {
+ color: #ea80fc !important
+}
+
+.mdl-color--purple-A100 {
+ background-color: #ea80fc !important
+}
+
+.mdl-color-text--purple-A200 {
+ color: #e040fb !important
+}
+
+.mdl-color--purple-A200 {
+ background-color: #e040fb !important
+}
+
+.mdl-color-text--purple-A400 {
+ color: #d500f9 !important
+}
+
+.mdl-color--purple-A400 {
+ background-color: #d500f9 !important
+}
+
+.mdl-color-text--purple-A700 {
+ color: #a0f !important
+}
+
+.mdl-color--purple-A700 {
+ background-color: #a0f !important
+}
+
+.mdl-color-text--deep-purple {
+ color: #673ab7 !important
+}
+
+.mdl-color--deep-purple {
+ background-color: #673ab7 !important
+}
+
+.mdl-color-text--deep-purple-50 {
+ color: #ede7f6 !important
+}
+
+.mdl-color--deep-purple-50 {
+ background-color: #ede7f6 !important
+}
+
+.mdl-color-text--deep-purple-100 {
+ color: #d1c4e9 !important
+}
+
+.mdl-color--deep-purple-100 {
+ background-color: #d1c4e9 !important
+}
+
+.mdl-color-text--deep-purple-200 {
+ color: #b39ddb !important
+}
+
+.mdl-color--deep-purple-200 {
+ background-color: #b39ddb !important
+}
+
+.mdl-color-text--deep-purple-300 {
+ color: #9575cd !important
+}
+
+.mdl-color--deep-purple-300 {
+ background-color: #9575cd !important
+}
+
+.mdl-color-text--deep-purple-400 {
+ color: #7e57c2 !important
+}
+
+.mdl-color--deep-purple-400 {
+ background-color: #7e57c2 !important
+}
+
+.mdl-color-text--deep-purple-500 {
+ color: #673ab7 !important
+}
+
+.mdl-color--deep-purple-500 {
+ background-color: #673ab7 !important
+}
+
+.mdl-color-text--deep-purple-600 {
+ color: #5e35b1 !important
+}
+
+.mdl-color--deep-purple-600 {
+ background-color: #5e35b1 !important
+}
+
+.mdl-color-text--deep-purple-700 {
+ color: #512da8 !important
+}
+
+.mdl-color--deep-purple-700 {
+ background-color: #512da8 !important
+}
+
+.mdl-color-text--deep-purple-800 {
+ color: #4527a0 !important
+}
+
+.mdl-color--deep-purple-800 {
+ background-color: #4527a0 !important
+}
+
+.mdl-color-text--deep-purple-900 {
+ color: #311b92 !important
+}
+
+.mdl-color--deep-purple-900 {
+ background-color: #311b92 !important
+}
+
+.mdl-color-text--deep-purple-A100 {
+ color: #b388ff !important
+}
+
+.mdl-color--deep-purple-A100 {
+ background-color: #b388ff !important
+}
+
+.mdl-color-text--deep-purple-A200 {
+ color: #7c4dff !important
+}
+
+.mdl-color--deep-purple-A200 {
+ background-color: #7c4dff !important
+}
+
+.mdl-color-text--deep-purple-A400 {
+ color: #651fff !important
+}
+
+.mdl-color--deep-purple-A400 {
+ background-color: #651fff !important
+}
+
+.mdl-color-text--deep-purple-A700 {
+ color: #6200ea !important
+}
+
+.mdl-color--deep-purple-A700 {
+ background-color: #6200ea !important
+}
+
+.mdl-color-text--indigo {
+ color: #3f51b5 !important
+}
+
+.mdl-color--indigo {
+ background-color: #3f51b5 !important
+}
+
+.mdl-color-text--indigo-50 {
+ color: #e8eaf6 !important
+}
+
+.mdl-color--indigo-50 {
+ background-color: #e8eaf6 !important
+}
+
+.mdl-color-text--indigo-100 {
+ color: #c5cae9 !important
+}
+
+.mdl-color--indigo-100 {
+ background-color: #c5cae9 !important
+}
+
+.mdl-color-text--indigo-200 {
+ color: #9fa8da !important
+}
+
+.mdl-color--indigo-200 {
+ background-color: #9fa8da !important
+}
+
+.mdl-color-text--indigo-300 {
+ color: #7986cb !important
+}
+
+.mdl-color--indigo-300 {
+ background-color: #7986cb !important
+}
+
+.mdl-color-text--indigo-400 {
+ color: #5c6bc0 !important
+}
+
+.mdl-color--indigo-400 {
+ background-color: #5c6bc0 !important
+}
+
+.mdl-color-text--indigo-500 {
+ color: #3f51b5 !important
+}
+
+.mdl-color--indigo-500 {
+ background-color: #3f51b5 !important
+}
+
+.mdl-color-text--indigo-600 {
+ color: #3949ab !important
+}
+
+.mdl-color--indigo-600 {
+ background-color: #3949ab !important
+}
+
+.mdl-color-text--indigo-700 {
+ color: #303f9f !important
+}
+
+.mdl-color--indigo-700 {
+ background-color: #303f9f !important
+}
+
+.mdl-color-text--indigo-800 {
+ color: #283593 !important
+}
+
+.mdl-color--indigo-800 {
+ background-color: #283593 !important
+}
+
+.mdl-color-text--indigo-900 {
+ color: #1a237e !important
+}
+
+.mdl-color--indigo-900 {
+ background-color: #1a237e !important
+}
+
+.mdl-color-text--indigo-A100 {
+ color: #8c9eff !important
+}
+
+.mdl-color--indigo-A100 {
+ background-color: #8c9eff !important
+}
+
+.mdl-color-text--indigo-A200 {
+ color: #536dfe !important
+}
+
+.mdl-color--indigo-A200 {
+ background-color: #536dfe !important
+}
+
+.mdl-color-text--indigo-A400 {
+ color: #3d5afe !important
+}
+
+.mdl-color--indigo-A400 {
+ background-color: #3d5afe !important
+}
+
+.mdl-color-text--indigo-A700 {
+ color: #304ffe !important
+}
+
+.mdl-color--indigo-A700 {
+ background-color: #304ffe !important
+}
+
+.mdl-color-text--blue {
+ color: #2196f3 !important
+}
+
+.mdl-color--blue {
+ background-color: #2196f3 !important
+}
+
+.mdl-color-text--blue-50 {
+ color: #e3f2fd !important
+}
+
+.mdl-color--blue-50 {
+ background-color: #e3f2fd !important
+}
+
+.mdl-color-text--blue-100 {
+ color: #bbdefb !important
+}
+
+.mdl-color--blue-100 {
+ background-color: #bbdefb !important
+}
+
+.mdl-color-text--blue-200 {
+ color: #90caf9 !important
+}
+
+.mdl-color--blue-200 {
+ background-color: #90caf9 !important
+}
+
+.mdl-color-text--blue-300 {
+ color: #64b5f6 !important
+}
+
+.mdl-color--blue-300 {
+ background-color: #64b5f6 !important
+}
+
+.mdl-color-text--blue-400 {
+ color: #42a5f5 !important
+}
+
+.mdl-color--blue-400 {
+ background-color: #42a5f5 !important
+}
+
+.mdl-color-text--blue-500 {
+ color: #2196f3 !important
+}
+
+.mdl-color--blue-500 {
+ background-color: #2196f3 !important
+}
+
+.mdl-color-text--blue-600 {
+ color: #1e88e5 !important
+}
+
+.mdl-color--blue-600 {
+ background-color: #1e88e5 !important
+}
+
+.mdl-color-text--blue-700 {
+ color: #1976d2 !important
+}
+
+.mdl-color--blue-700 {
+ background-color: #1976d2 !important
+}
+
+.mdl-color-text--blue-800 {
+ color: #1565c0 !important
+}
+
+.mdl-color--blue-800 {
+ background-color: #1565c0 !important
+}
+
+.mdl-color-text--blue-900 {
+ color: #0d47a1 !important
+}
+
+.mdl-color--blue-900 {
+ background-color: #0d47a1 !important
+}
+
+.mdl-color-text--blue-A100 {
+ color: #82b1ff !important
+}
+
+.mdl-color--blue-A100 {
+ background-color: #82b1ff !important
+}
+
+.mdl-color-text--blue-A200 {
+ color: #448aff !important
+}
+
+.mdl-color--blue-A200 {
+ background-color: #448aff !important
+}
+
+.mdl-color-text--blue-A400 {
+ color: #2979ff !important
+}
+
+.mdl-color--blue-A400 {
+ background-color: #2979ff !important
+}
+
+.mdl-color-text--blue-A700 {
+ color: #2962ff !important
+}
+
+.mdl-color--blue-A700 {
+ background-color: #2962ff !important
+}
+
+.mdl-color-text--light-blue {
+ color: #03a9f4 !important
+}
+
+.mdl-color--light-blue {
+ background-color: #03a9f4 !important
+}
+
+.mdl-color-text--light-blue-50 {
+ color: #e1f5fe !important
+}
+
+.mdl-color--light-blue-50 {
+ background-color: #e1f5fe !important
+}
+
+.mdl-color-text--light-blue-100 {
+ color: #b3e5fc !important
+}
+
+.mdl-color--light-blue-100 {
+ background-color: #b3e5fc !important
+}
+
+.mdl-color-text--light-blue-200 {
+ color: #81d4fa !important
+}
+
+.mdl-color--light-blue-200 {
+ background-color: #81d4fa !important
+}
+
+.mdl-color-text--light-blue-300 {
+ color: #4fc3f7 !important
+}
+
+.mdl-color--light-blue-300 {
+ background-color: #4fc3f7 !important
+}
+
+.mdl-color-text--light-blue-400 {
+ color: #29b6f6 !important
+}
+
+.mdl-color--light-blue-400 {
+ background-color: #29b6f6 !important
+}
+
+.mdl-color-text--light-blue-500 {
+ color: #03a9f4 !important
+}
+
+.mdl-color--light-blue-500 {
+ background-color: #03a9f4 !important
+}
+
+.mdl-color-text--light-blue-600 {
+ color: #039be5 !important
+}
+
+.mdl-color--light-blue-600 {
+ background-color: #039be5 !important
+}
+
+.mdl-color-text--light-blue-700 {
+ color: #0288d1 !important
+}
+
+.mdl-color--light-blue-700 {
+ background-color: #0288d1 !important
+}
+
+.mdl-color-text--light-blue-800 {
+ color: #0277bd !important
+}
+
+.mdl-color--light-blue-800 {
+ background-color: #0277bd !important
+}
+
+.mdl-color-text--light-blue-900 {
+ color: #01579b !important
+}
+
+.mdl-color--light-blue-900 {
+ background-color: #01579b !important
+}
+
+.mdl-color-text--light-blue-A100 {
+ color: #80d8ff !important
+}
+
+.mdl-color--light-blue-A100 {
+ background-color: #80d8ff !important
+}
+
+.mdl-color-text--light-blue-A200 {
+ color: #40c4ff !important
+}
+
+.mdl-color--light-blue-A200 {
+ background-color: #40c4ff !important
+}
+
+.mdl-color-text--light-blue-A400 {
+ color: #00b0ff !important
+}
+
+.mdl-color--light-blue-A400 {
+ background-color: #00b0ff !important
+}
+
+.mdl-color-text--light-blue-A700 {
+ color: #0091ea !important
+}
+
+.mdl-color--light-blue-A700 {
+ background-color: #0091ea !important
+}
+
+.mdl-color-text--cyan {
+ color: #00bcd4 !important
+}
+
+.mdl-color--cyan {
+ background-color: #00bcd4 !important
+}
+
+.mdl-color-text--cyan-50 {
+ color: #e0f7fa !important
+}
+
+.mdl-color--cyan-50 {
+ background-color: #e0f7fa !important
+}
+
+.mdl-color-text--cyan-100 {
+ color: #b2ebf2 !important
+}
+
+.mdl-color--cyan-100 {
+ background-color: #b2ebf2 !important
+}
+
+.mdl-color-text--cyan-200 {
+ color: #80deea !important
+}
+
+.mdl-color--cyan-200 {
+ background-color: #80deea !important
+}
+
+.mdl-color-text--cyan-300 {
+ color: #4dd0e1 !important
+}
+
+.mdl-color--cyan-300 {
+ background-color: #4dd0e1 !important
+}
+
+.mdl-color-text--cyan-400 {
+ color: #26c6da !important
+}
+
+.mdl-color--cyan-400 {
+ background-color: #26c6da !important
+}
+
+.mdl-color-text--cyan-500 {
+ color: #00bcd4 !important
+}
+
+.mdl-color--cyan-500 {
+ background-color: #00bcd4 !important
+}
+
+.mdl-color-text--cyan-600 {
+ color: #00acc1 !important
+}
+
+.mdl-color--cyan-600 {
+ background-color: #00acc1 !important
+}
+
+.mdl-color-text--cyan-700 {
+ color: #0097a7 !important
+}
+
+.mdl-color--cyan-700 {
+ background-color: #0097a7 !important
+}
+
+.mdl-color-text--cyan-800 {
+ color: #00838f !important
+}
+
+.mdl-color--cyan-800 {
+ background-color: #00838f !important
+}
+
+.mdl-color-text--cyan-900 {
+ color: #006064 !important
+}
+
+.mdl-color--cyan-900 {
+ background-color: #006064 !important
+}
+
+.mdl-color-text--cyan-A100 {
+ color: #84ffff !important
+}
+
+.mdl-color--cyan-A100 {
+ background-color: #84ffff !important
+}
+
+.mdl-color-text--cyan-A200 {
+ color: #18ffff !important
+}
+
+.mdl-color--cyan-A200 {
+ background-color: #18ffff !important
+}
+
+.mdl-color-text--cyan-A400 {
+ color: #00e5ff !important
+}
+
+.mdl-color--cyan-A400 {
+ background-color: #00e5ff !important
+}
+
+.mdl-color-text--cyan-A700 {
+ color: #00b8d4 !important
+}
+
+.mdl-color--cyan-A700 {
+ background-color: #00b8d4 !important
+}
+
+.mdl-color-text--teal {
+ color: #009688 !important
+}
+
+.mdl-color--teal {
+ background-color: #009688 !important
+}
+
+.mdl-color-text--teal-50 {
+ color: #e0f2f1 !important
+}
+
+.mdl-color--teal-50 {
+ background-color: #e0f2f1 !important
+}
+
+.mdl-color-text--teal-100 {
+ color: #b2dfdb !important
+}
+
+.mdl-color--teal-100 {
+ background-color: #b2dfdb !important
+}
+
+.mdl-color-text--teal-200 {
+ color: #80cbc4 !important
+}
+
+.mdl-color--teal-200 {
+ background-color: #80cbc4 !important
+}
+
+.mdl-color-text--teal-300 {
+ color: #4db6ac !important
+}
+
+.mdl-color--teal-300 {
+ background-color: #4db6ac !important
+}
+
+.mdl-color-text--teal-400 {
+ color: #26a69a !important
+}
+
+.mdl-color--teal-400 {
+ background-color: #26a69a !important
+}
+
+.mdl-color-text--teal-500 {
+ color: #009688 !important
+}
+
+.mdl-color--teal-500 {
+ background-color: #009688 !important
+}
+
+.mdl-color-text--teal-600 {
+ color: #00897b !important
+}
+
+.mdl-color--teal-600 {
+ background-color: #00897b !important
+}
+
+.mdl-color-text--teal-700 {
+ color: #00796b !important
+}
+
+.mdl-color--teal-700 {
+ background-color: #00796b !important
+}
+
+.mdl-color-text--teal-800 {
+ color: #00695c !important
+}
+
+.mdl-color--teal-800 {
+ background-color: #00695c !important
+}
+
+.mdl-color-text--teal-900 {
+ color: #004d40 !important
+}
+
+.mdl-color--teal-900 {
+ background-color: #004d40 !important
+}
+
+.mdl-color-text--teal-A100 {
+ color: #a7ffeb !important
+}
+
+.mdl-color--teal-A100 {
+ background-color: #a7ffeb !important
+}
+
+.mdl-color-text--teal-A200 {
+ color: #64ffda !important
+}
+
+.mdl-color--teal-A200 {
+ background-color: #64ffda !important
+}
+
+.mdl-color-text--teal-A400 {
+ color: #1de9b6 !important
+}
+
+.mdl-color--teal-A400 {
+ background-color: #1de9b6 !important
+}
+
+.mdl-color-text--teal-A700 {
+ color: #00bfa5 !important
+}
+
+.mdl-color--teal-A700 {
+ background-color: #00bfa5 !important
+}
+
+.mdl-color-text--green {
+ color: #4caf50 !important
+}
+
+.mdl-color--green {
+ background-color: #4caf50 !important
+}
+
+.mdl-color-text--green-50 {
+ color: #e8f5e9 !important
+}
+
+.mdl-color--green-50 {
+ background-color: #e8f5e9 !important
+}
+
+.mdl-color-text--green-100 {
+ color: #c8e6c9 !important
+}
+
+.mdl-color--green-100 {
+ background-color: #c8e6c9 !important
+}
+
+.mdl-color-text--green-200 {
+ color: #a5d6a7 !important
+}
+
+.mdl-color--green-200 {
+ background-color: #a5d6a7 !important
+}
+
+.mdl-color-text--green-300 {
+ color: #81c784 !important
+}
+
+.mdl-color--green-300 {
+ background-color: #81c784 !important
+}
+
+.mdl-color-text--green-400 {
+ color: #66bb6a !important
+}
+
+.mdl-color--green-400 {
+ background-color: #66bb6a !important
+}
+
+.mdl-color-text--green-500 {
+ color: #4caf50 !important
+}
+
+.mdl-color--green-500 {
+ background-color: #4caf50 !important
+}
+
+.mdl-color-text--green-600 {
+ color: #43a047 !important
+}
+
+.mdl-color--green-600 {
+ background-color: #43a047 !important
+}
+
+.mdl-color-text--green-700 {
+ color: #388e3c !important
+}
+
+.mdl-color--green-700 {
+ background-color: #388e3c !important
+}
+
+.mdl-color-text--green-800 {
+ color: #2e7d32 !important
+}
+
+.mdl-color--green-800 {
+ background-color: #2e7d32 !important
+}
+
+.mdl-color-text--green-900 {
+ color: #1b5e20 !important
+}
+
+.mdl-color--green-900 {
+ background-color: #1b5e20 !important
+}
+
+.mdl-color-text--green-A100 {
+ color: #b9f6ca !important
+}
+
+.mdl-color--green-A100 {
+ background-color: #b9f6ca !important
+}
+
+.mdl-color-text--green-A200 {
+ color: #69f0ae !important
+}
+
+.mdl-color--green-A200 {
+ background-color: #69f0ae !important
+}
+
+.mdl-color-text--green-A400 {
+ color: #00e676 !important
+}
+
+.mdl-color--green-A400 {
+ background-color: #00e676 !important
+}
+
+.mdl-color-text--green-A700 {
+ color: #00c853 !important
+}
+
+.mdl-color--green-A700 {
+ background-color: #00c853 !important
+}
+
+.mdl-color-text--light-green {
+ color: #8bc34a !important
+}
+
+.mdl-color--light-green {
+ background-color: #8bc34a !important
+}
+
+.mdl-color-text--light-green-50 {
+ color: #f1f8e9 !important
+}
+
+.mdl-color--light-green-50 {
+ background-color: #f1f8e9 !important
+}
+
+.mdl-color-text--light-green-100 {
+ color: #dcedc8 !important
+}
+
+.mdl-color--light-green-100 {
+ background-color: #dcedc8 !important
+}
+
+.mdl-color-text--light-green-200 {
+ color: #c5e1a5 !important
+}
+
+.mdl-color--light-green-200 {
+ background-color: #c5e1a5 !important
+}
+
+.mdl-color-text--light-green-300 {
+ color: #aed581 !important
+}
+
+.mdl-color--light-green-300 {
+ background-color: #aed581 !important
+}
+
+.mdl-color-text--light-green-400 {
+ color: #9ccc65 !important
+}
+
+.mdl-color--light-green-400 {
+ background-color: #9ccc65 !important
+}
+
+.mdl-color-text--light-green-500 {
+ color: #8bc34a !important
+}
+
+.mdl-color--light-green-500 {
+ background-color: #8bc34a !important
+}
+
+.mdl-color-text--light-green-600 {
+ color: #7cb342 !important
+}
+
+.mdl-color--light-green-600 {
+ background-color: #7cb342 !important
+}
+
+.mdl-color-text--light-green-700 {
+ color: #689f38 !important
+}
+
+.mdl-color--light-green-700 {
+ background-color: #689f38 !important
+}
+
+.mdl-color-text--light-green-800 {
+ color: #558b2f !important
+}
+
+.mdl-color--light-green-800 {
+ background-color: #558b2f !important
+}
+
+.mdl-color-text--light-green-900 {
+ color: #33691e !important
+}
+
+.mdl-color--light-green-900 {
+ background-color: #33691e !important
+}
+
+.mdl-color-text--light-green-A100 {
+ color: #ccff90 !important
+}
+
+.mdl-color--light-green-A100 {
+ background-color: #ccff90 !important
+}
+
+.mdl-color-text--light-green-A200 {
+ color: #b2ff59 !important
+}
+
+.mdl-color--light-green-A200 {
+ background-color: #b2ff59 !important
+}
+
+.mdl-color-text--light-green-A400 {
+ color: #76ff03 !important
+}
+
+.mdl-color--light-green-A400 {
+ background-color: #76ff03 !important
+}
+
+.mdl-color-text--light-green-A700 {
+ color: #64dd17 !important
+}
+
+.mdl-color--light-green-A700 {
+ background-color: #64dd17 !important
+}
+
+.mdl-color-text--lime {
+ color: #cddc39 !important
+}
+
+.mdl-color--lime {
+ background-color: #cddc39 !important
+}
+
+.mdl-color-text--lime-50 {
+ color: #f9fbe7 !important
+}
+
+.mdl-color--lime-50 {
+ background-color: #f9fbe7 !important
+}
+
+.mdl-color-text--lime-100 {
+ color: #f0f4c3 !important
+}
+
+.mdl-color--lime-100 {
+ background-color: #f0f4c3 !important
+}
+
+.mdl-color-text--lime-200 {
+ color: #e6ee9c !important
+}
+
+.mdl-color--lime-200 {
+ background-color: #e6ee9c !important
+}
+
+.mdl-color-text--lime-300 {
+ color: #dce775 !important
+}
+
+.mdl-color--lime-300 {
+ background-color: #dce775 !important
+}
+
+.mdl-color-text--lime-400 {
+ color: #d4e157 !important
+}
+
+.mdl-color--lime-400 {
+ background-color: #d4e157 !important
+}
+
+.mdl-color-text--lime-500 {
+ color: #cddc39 !important
+}
+
+.mdl-color--lime-500 {
+ background-color: #cddc39 !important
+}
+
+.mdl-color-text--lime-600 {
+ color: #c0ca33 !important
+}
+
+.mdl-color--lime-600 {
+ background-color: #c0ca33 !important
+}
+
+.mdl-color-text--lime-700 {
+ color: #afb42b !important
+}
+
+.mdl-color--lime-700 {
+ background-color: #afb42b !important
+}
+
+.mdl-color-text--lime-800 {
+ color: #9e9d24 !important
+}
+
+.mdl-color--lime-800 {
+ background-color: #9e9d24 !important
+}
+
+.mdl-color-text--lime-900 {
+ color: #827717 !important
+}
+
+.mdl-color--lime-900 {
+ background-color: #827717 !important
+}
+
+.mdl-color-text--lime-A100 {
+ color: #f4ff81 !important
+}
+
+.mdl-color--lime-A100 {
+ background-color: #f4ff81 !important
+}
+
+.mdl-color-text--lime-A200 {
+ color: #eeff41 !important
+}
+
+.mdl-color--lime-A200 {
+ background-color: #eeff41 !important
+}
+
+.mdl-color-text--lime-A400 {
+ color: #c6ff00 !important
+}
+
+.mdl-color--lime-A400 {
+ background-color: #c6ff00 !important
+}
+
+.mdl-color-text--lime-A700 {
+ color: #aeea00 !important
+}
+
+.mdl-color--lime-A700 {
+ background-color: #aeea00 !important
+}
+
+.mdl-color-text--yellow {
+ color: #ffeb3b !important
+}
+
+.mdl-color--yellow {
+ background-color: #ffeb3b !important
+}
+
+.mdl-color-text--yellow-50 {
+ color: #fffde7 !important
+}
+
+.mdl-color--yellow-50 {
+ background-color: #fffde7 !important
+}
+
+.mdl-color-text--yellow-100 {
+ color: #fff9c4 !important
+}
+
+.mdl-color--yellow-100 {
+ background-color: #fff9c4 !important
+}
+
+.mdl-color-text--yellow-200 {
+ color: #fff59d !important
+}
+
+.mdl-color--yellow-200 {
+ background-color: #fff59d !important
+}
+
+.mdl-color-text--yellow-300 {
+ color: #fff176 !important
+}
+
+.mdl-color--yellow-300 {
+ background-color: #fff176 !important
+}
+
+.mdl-color-text--yellow-400 {
+ color: #ffee58 !important
+}
+
+.mdl-color--yellow-400 {
+ background-color: #ffee58 !important
+}
+
+.mdl-color-text--yellow-500 {
+ color: #ffeb3b !important
+}
+
+.mdl-color--yellow-500 {
+ background-color: #ffeb3b !important
+}
+
+.mdl-color-text--yellow-600 {
+ color: #fdd835 !important
+}
+
+.mdl-color--yellow-600 {
+ background-color: #fdd835 !important
+}
+
+.mdl-color-text--yellow-700 {
+ color: #fbc02d !important
+}
+
+.mdl-color--yellow-700 {
+ background-color: #fbc02d !important
+}
+
+.mdl-color-text--yellow-800 {
+ color: #f9a825 !important
+}
+
+.mdl-color--yellow-800 {
+ background-color: #f9a825 !important
+}
+
+.mdl-color-text--yellow-900 {
+ color: #f57f17 !important
+}
+
+.mdl-color--yellow-900 {
+ background-color: #f57f17 !important
+}
+
+.mdl-color-text--yellow-A100 {
+ color: #ffff8d !important
+}
+
+.mdl-color--yellow-A100 {
+ background-color: #ffff8d !important
+}
+
+.mdl-color-text--yellow-A200 {
+ color: #ff0 !important
+}
+
+.mdl-color--yellow-A200 {
+ background-color: #ff0 !important
+}
+
+.mdl-color-text--yellow-A400 {
+ color: #ffea00 !important
+}
+
+.mdl-color--yellow-A400 {
+ background-color: #ffea00 !important
+}
+
+.mdl-color-text--yellow-A700 {
+ color: #ffd600 !important
+}
+
+.mdl-color--yellow-A700 {
+ background-color: #ffd600 !important
+}
+
+.mdl-color-text--amber {
+ color: #ffc107 !important
+}
+
+.mdl-color--amber {
+ background-color: #ffc107 !important
+}
+
+.mdl-color-text--amber-50 {
+ color: #fff8e1 !important
+}
+
+.mdl-color--amber-50 {
+ background-color: #fff8e1 !important
+}
+
+.mdl-color-text--amber-100 {
+ color: #ffecb3 !important
+}
+
+.mdl-color--amber-100 {
+ background-color: #ffecb3 !important
+}
+
+.mdl-color-text--amber-200 {
+ color: #ffe082 !important
+}
+
+.mdl-color--amber-200 {
+ background-color: #ffe082 !important
+}
+
+.mdl-color-text--amber-300 {
+ color: #ffd54f !important
+}
+
+.mdl-color--amber-300 {
+ background-color: #ffd54f !important
+}
+
+.mdl-color-text--amber-400 {
+ color: #ffca28 !important
+}
+
+.mdl-color--amber-400 {
+ background-color: #ffca28 !important
+}
+
+.mdl-color-text--amber-500 {
+ color: #ffc107 !important
+}
+
+.mdl-color--amber-500 {
+ background-color: #ffc107 !important
+}
+
+.mdl-color-text--amber-600 {
+ color: #ffb300 !important
+}
+
+.mdl-color--amber-600 {
+ background-color: #ffb300 !important
+}
+
+.mdl-color-text--amber-700 {
+ color: #ffa000 !important
+}
+
+.mdl-color--amber-700 {
+ background-color: #ffa000 !important
+}
+
+.mdl-color-text--amber-800 {
+ color: #ff8f00 !important
+}
+
+.mdl-color--amber-800 {
+ background-color: #ff8f00 !important
+}
+
+.mdl-color-text--amber-900 {
+ color: #ff6f00 !important
+}
+
+.mdl-color--amber-900 {
+ background-color: #ff6f00 !important
+}
+
+.mdl-color-text--amber-A100 {
+ color: #ffe57f !important
+}
+
+.mdl-color--amber-A100 {
+ background-color: #ffe57f !important
+}
+
+.mdl-color-text--amber-A200 {
+ color: #ffd740 !important
+}
+
+.mdl-color--amber-A200 {
+ background-color: #ffd740 !important
+}
+
+.mdl-color-text--amber-A400 {
+ color: #ffc400 !important
+}
+
+.mdl-color--amber-A400 {
+ background-color: #ffc400 !important
+}
+
+.mdl-color-text--amber-A700 {
+ color: #ffab00 !important
+}
+
+.mdl-color--amber-A700 {
+ background-color: #ffab00 !important
+}
+
+.mdl-color-text--orange {
+ color: #ff9800 !important
+}
+
+.mdl-color--orange {
+ background-color: #ff9800 !important
+}
+
+.mdl-color-text--orange-50 {
+ color: #fff3e0 !important
+}
+
+.mdl-color--orange-50 {
+ background-color: #fff3e0 !important
+}
+
+.mdl-color-text--orange-100 {
+ color: #ffe0b2 !important
+}
+
+.mdl-color--orange-100 {
+ background-color: #ffe0b2 !important
+}
+
+.mdl-color-text--orange-200 {
+ color: #ffcc80 !important
+}
+
+.mdl-color--orange-200 {
+ background-color: #ffcc80 !important
+}
+
+.mdl-color-text--orange-300 {
+ color: #ffb74d !important
+}
+
+.mdl-color--orange-300 {
+ background-color: #ffb74d !important
+}
+
+.mdl-color-text--orange-400 {
+ color: #ffa726 !important
+}
+
+.mdl-color--orange-400 {
+ background-color: #ffa726 !important
+}
+
+.mdl-color-text--orange-500 {
+ color: #ff9800 !important
+}
+
+.mdl-color--orange-500 {
+ background-color: #ff9800 !important
+}
+
+.mdl-color-text--orange-600 {
+ color: #fb8c00 !important
+}
+
+.mdl-color--orange-600 {
+ background-color: #fb8c00 !important
+}
+
+.mdl-color-text--orange-700 {
+ color: #f57c00 !important
+}
+
+.mdl-color--orange-700 {
+ background-color: #f57c00 !important
+}
+
+.mdl-color-text--orange-800 {
+ color: #ef6c00 !important
+}
+
+.mdl-color--orange-800 {
+ background-color: #ef6c00 !important
+}
+
+.mdl-color-text--orange-900 {
+ color: #e65100 !important
+}
+
+.mdl-color--orange-900 {
+ background-color: #e65100 !important
+}
+
+.mdl-color-text--orange-A100 {
+ color: #ffd180 !important
+}
+
+.mdl-color--orange-A100 {
+ background-color: #ffd180 !important
+}
+
+.mdl-color-text--orange-A200 {
+ color: #ffab40 !important
+}
+
+.mdl-color--orange-A200 {
+ background-color: #ffab40 !important
+}
+
+.mdl-color-text--orange-A400 {
+ color: #ff9100 !important
+}
+
+.mdl-color--orange-A400 {
+ background-color: #ff9100 !important
+}
+
+.mdl-color-text--orange-A700 {
+ color: #ff6d00 !important
+}
+
+.mdl-color--orange-A700 {
+ background-color: #ff6d00 !important
+}
+
+.mdl-color-text--deep-orange {
+ color: #ff5722 !important
+}
+
+.mdl-color--deep-orange {
+ background-color: #ff5722 !important
+}
+
+.mdl-color-text--deep-orange-50 {
+ color: #fbe9e7 !important
+}
+
+.mdl-color--deep-orange-50 {
+ background-color: #fbe9e7 !important
+}
+
+.mdl-color-text--deep-orange-100 {
+ color: #ffccbc !important
+}
+
+.mdl-color--deep-orange-100 {
+ background-color: #ffccbc !important
+}
+
+.mdl-color-text--deep-orange-200 {
+ color: #ffab91 !important
+}
+
+.mdl-color--deep-orange-200 {
+ background-color: #ffab91 !important
+}
+
+.mdl-color-text--deep-orange-300 {
+ color: #ff8a65 !important
+}
+
+.mdl-color--deep-orange-300 {
+ background-color: #ff8a65 !important
+}
+
+.mdl-color-text--deep-orange-400 {
+ color: #ff7043 !important
+}
+
+.mdl-color--deep-orange-400 {
+ background-color: #ff7043 !important
+}
+
+.mdl-color-text--deep-orange-500 {
+ color: #ff5722 !important
+}
+
+.mdl-color--deep-orange-500 {
+ background-color: #ff5722 !important
+}
+
+.mdl-color-text--deep-orange-600 {
+ color: #f4511e !important
+}
+
+.mdl-color--deep-orange-600 {
+ background-color: #f4511e !important
+}
+
+.mdl-color-text--deep-orange-700 {
+ color: #e64a19 !important
+}
+
+.mdl-color--deep-orange-700 {
+ background-color: #e64a19 !important
+}
+
+.mdl-color-text--deep-orange-800 {
+ color: #d84315 !important
+}
+
+.mdl-color--deep-orange-800 {
+ background-color: #d84315 !important
+}
+
+.mdl-color-text--deep-orange-900 {
+ color: #bf360c !important
+}
+
+.mdl-color--deep-orange-900 {
+ background-color: #bf360c !important
+}
+
+.mdl-color-text--deep-orange-A100 {
+ color: #ff9e80 !important
+}
+
+.mdl-color--deep-orange-A100 {
+ background-color: #ff9e80 !important
+}
+
+.mdl-color-text--deep-orange-A200 {
+ color: #ff6e40 !important
+}
+
+.mdl-color--deep-orange-A200 {
+ background-color: #ff6e40 !important
+}
+
+.mdl-color-text--deep-orange-A400 {
+ color: #ff3d00 !important
+}
+
+.mdl-color--deep-orange-A400 {
+ background-color: #ff3d00 !important
+}
+
+.mdl-color-text--deep-orange-A700 {
+ color: #dd2c00 !important
+}
+
+.mdl-color--deep-orange-A700 {
+ background-color: #dd2c00 !important
+}
+
+.mdl-color-text--brown {
+ color: #795548 !important
+}
+
+.mdl-color--brown {
+ background-color: #795548 !important
+}
+
+.mdl-color-text--brown-50 {
+ color: #efebe9 !important
+}
+
+.mdl-color--brown-50 {
+ background-color: #efebe9 !important
+}
+
+.mdl-color-text--brown-100 {
+ color: #d7ccc8 !important
+}
+
+.mdl-color--brown-100 {
+ background-color: #d7ccc8 !important
+}
+
+.mdl-color-text--brown-200 {
+ color: #bcaaa4 !important
+}
+
+.mdl-color--brown-200 {
+ background-color: #bcaaa4 !important
+}
+
+.mdl-color-text--brown-300 {
+ color: #a1887f !important
+}
+
+.mdl-color--brown-300 {
+ background-color: #a1887f !important
+}
+
+.mdl-color-text--brown-400 {
+ color: #8d6e63 !important
+}
+
+.mdl-color--brown-400 {
+ background-color: #8d6e63 !important
+}
+
+.mdl-color-text--brown-500 {
+ color: #795548 !important
+}
+
+.mdl-color--brown-500 {
+ background-color: #795548 !important
+}
+
+.mdl-color-text--brown-600 {
+ color: #6d4c41 !important
+}
+
+.mdl-color--brown-600 {
+ background-color: #6d4c41 !important
+}
+
+.mdl-color-text--brown-700 {
+ color: #5d4037 !important
+}
+
+.mdl-color--brown-700 {
+ background-color: #5d4037 !important
+}
+
+.mdl-color-text--brown-800 {
+ color: #4e342e !important
+}
+
+.mdl-color--brown-800 {
+ background-color: #4e342e !important
+}
+
+.mdl-color-text--brown-900 {
+ color: #3e2723 !important
+}
+
+.mdl-color--brown-900 {
+ background-color: #3e2723 !important
+}
+
+.mdl-color-text--grey {
+ color: #9e9e9e !important
+}
+
+.mdl-color--grey {
+ background-color: #9e9e9e !important
+}
+
+.mdl-color-text--grey-50 {
+ color: #fafafa !important
+}
+
+.mdl-color--grey-50 {
+ background-color: #fafafa !important
+}
+
+.mdl-color-text--grey-100 {
+ color: #f5f5f5 !important
+}
+
+.mdl-color--grey-100 {
+ background-color: #f5f5f5 !important
+}
+
+.mdl-color-text--grey-200 {
+ color: #eee !important
+}
+
+.mdl-color--grey-200 {
+ background-color: #eee !important
+}
+
+.mdl-color-text--grey-300 {
+ color: #e0e0e0 !important
+}
+
+.mdl-color--grey-300 {
+ background-color: #e0e0e0 !important
+}
+
+.mdl-color-text--grey-400 {
+ color: #bdbdbd !important
+}
+
+.mdl-color--grey-400 {
+ background-color: #bdbdbd !important
+}
+
+.mdl-color-text--grey-500 {
+ color: #9e9e9e !important
+}
+
+.mdl-color--grey-500 {
+ background-color: #9e9e9e !important
+}
+
+.mdl-color-text--grey-600 {
+ color: #757575 !important
+}
+
+.mdl-color--grey-600 {
+ background-color: #757575 !important
+}
+
+.mdl-color-text--grey-700 {
+ color: #616161 !important
+}
+
+.mdl-color--grey-700 {
+ background-color: #616161 !important
+}
+
+.mdl-color-text--grey-800 {
+ color: #424242 !important
+}
+
+.mdl-color--grey-800 {
+ background-color: #424242 !important
+}
+
+.mdl-color-text--grey-900 {
+ color: #212121 !important
+}
+
+.mdl-color--grey-900 {
+ background-color: #212121 !important
+}
+
+.mdl-color-text--blue-grey {
+ color: #607d8b !important
+}
+
+.mdl-color--blue-grey {
+ background-color: #607d8b !important
+}
+
+.mdl-color-text--blue-grey-50 {
+ color: #eceff1 !important
+}
+
+.mdl-color--blue-grey-50 {
+ background-color: #eceff1 !important
+}
+
+.mdl-color-text--blue-grey-100 {
+ color: #cfd8dc !important
+}
+
+.mdl-color--blue-grey-100 {
+ background-color: #cfd8dc !important
+}
+
+.mdl-color-text--blue-grey-200 {
+ color: #b0bec5 !important
+}
+
+.mdl-color--blue-grey-200 {
+ background-color: #b0bec5 !important
+}
+
+.mdl-color-text--blue-grey-300 {
+ color: #90a4ae !important
+}
+
+.mdl-color--blue-grey-300 {
+ background-color: #90a4ae !important
+}
+
+.mdl-color-text--blue-grey-400 {
+ color: #78909c !important
+}
+
+.mdl-color--blue-grey-400 {
+ background-color: #78909c !important
+}
+
+.mdl-color-text--blue-grey-500 {
+ color: #607d8b !important
+}
+
+.mdl-color--blue-grey-500 {
+ background-color: #607d8b !important
+}
+
+.mdl-color-text--blue-grey-600 {
+ color: #546e7a !important
+}
+
+.mdl-color--blue-grey-600 {
+ background-color: #546e7a !important
+}
+
+.mdl-color-text--blue-grey-700 {
+ color: #455a64 !important
+}
+
+.mdl-color--blue-grey-700 {
+ background-color: #455a64 !important
+}
+
+.mdl-color-text--blue-grey-800 {
+ color: #37474f !important
+}
+
+.mdl-color--blue-grey-800 {
+ background-color: #37474f !important
+}
+
+.mdl-color-text--blue-grey-900 {
+ color: #263238 !important
+}
+
+.mdl-color--blue-grey-900 {
+ background-color: #263238 !important
+}
+
+.mdl-color--black {
+ background-color: #000 !important
+}
+
+.mdl-color-text--black {
+ color: #000 !important
+}
+
+.mdl-color--white {
+ background-color: #fff !important
+}
+
+.mdl-color-text--white {
+ color: #fff !important
+}
+
+.mdl-color--primary {
+ background-color: rgb(63, 81, 181) !important
+}
+
+.mdl-color--primary-contrast {
+ background-color: rgb(255, 255, 255) !important
+}
+
+.mdl-color--primary-dark {
+ background-color: rgb(48, 63, 159) !important
+}
+
+.mdl-color--accent {
+ background-color: rgb(255, 64, 129) !important
+}
+
+.mdl-color--accent-contrast {
+ background-color: rgb(255, 255, 255) !important
+}
+
+.mdl-color-text--primary {
+ color: rgb(63, 81, 181) !important
+}
+
+.mdl-color-text--primary-contrast {
+ color: rgb(255, 255, 255) !important
+}
+
+.mdl-color-text--primary-dark {
+ color: rgb(48, 63, 159) !important
+}
+
+.mdl-color-text--accent {
+ color: rgb(255, 64, 129) !important
+}
+
+.mdl-color-text--accent-contrast {
+ color: rgb(255, 255, 255) !important
+}
+
+.mdl-ripple {
+ background: #000;
+ border-radius: 50%;
+ height: 50px;
+ left: 0;
+ opacity: 0;
+ pointer-events: none;
+ position: absolute;
+ top: 0;
+ -webkit-transform: translate(-50%, -50%);
+ transform: translate(-50%, -50%);
+ width: 50px;
+ overflow: hidden
+}
+
+.mdl-ripple.is-animating {
+ transition: transform .3s cubic-bezier(0, 0, .2, 1), width .3s cubic-bezier(0, 0, .2, 1), height .3s cubic-bezier(0, 0, .2, 1), opacity .6s cubic-bezier(0, 0, .2, 1);
+ transition: transform .3s cubic-bezier(0, 0, .2, 1), width .3s cubic-bezier(0, 0, .2, 1), height .3s cubic-bezier(0, 0, .2, 1), opacity .6s cubic-bezier(0, 0, .2, 1), -webkit-transform .3s cubic-bezier(0, 0, .2, 1)
+}
+
+.mdl-ripple.is-visible {
+ opacity: .3
+}
+
+.mdl-animation--default,
+.mdl-animation--fast-out-slow-in {
+ transition-timing-function: cubic-bezier(.4, 0, .2, 1)
+}
+
+.mdl-animation--linear-out-slow-in {
+ transition-timing-function: cubic-bezier(0, 0, .2, 1)
+}
+
+.mdl-animation--fast-out-linear-in {
+ transition-timing-function: cubic-bezier(.4, 0, 1, 1)
+}
+
+.mdl-badge {
+ position: relative;
+ white-space: nowrap;
+ margin-right: 24px
+}
+
+.mdl-badge:not([data-badge]) {
+ margin-right: auto
+}
+
+.mdl-badge[data-badge]:after {
+ content: attr(data-badge);
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: row;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-flex-wrap: wrap;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-justify-content: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-align-content: center;
+ -ms-flex-line-pack: center;
+ align-content: center;
+ -webkit-align-items: center;
+ -ms-flex-align: center;
+ align-items: center;
+ position: absolute;
+ top: -11px;
+ right: -24px;
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ font-weight: 600;
+ font-size: 12px;
+ width: 22px;
+ height: 22px;
+ border-radius: 50%;
+ background: rgb(255, 64, 129);
+ color: rgb(255, 255, 255)
+}
+
+.mdl-button .mdl-badge[data-badge]:after {
+ top: -10px;
+ right: -5px
+}
+
+.mdl-badge.mdl-badge--no-background[data-badge]:after {
+ color: rgb(255, 64, 129);
+ background: rgba(255, 255, 255, .2);
+ box-shadow: 0 0 1px gray
+}
+
+.mdl-badge.mdl-badge--overlap {
+ margin-right: 10px
+}
+
+.mdl-badge.mdl-badge--overlap:after {
+ right: -10px
+}
+
+.mdl-button {
+ background: 0 0;
+ border: none;
+ border-radius: 2px;
+ color: #000;
+ position: relative;
+ height: 36px;
+ margin: 0;
+ min-width: 64px;
+ padding: 0 16px;
+ display: inline-block;
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ font-size: 14px;
+ font-weight: 500;
+ text-transform: uppercase;
+ letter-spacing: 0;
+ overflow: hidden;
+ will-change: box-shadow;
+ transition: box-shadow .2s cubic-bezier(.4, 0, 1, 1), background-color .2s cubic-bezier(.4, 0, .2, 1), color .2s cubic-bezier(.4, 0, .2, 1);
+ outline: none;
+ cursor: pointer;
+ text-decoration: none;
+ text-align: center;
+ line-height: 36px;
+ vertical-align: middle
+}
+
+.mdl-button::-moz-focus-inner {
+ border: 0
+}
+
+.mdl-button:hover {
+ background-color: rgba(158, 158, 158, .2)
+}
+
+.mdl-button:focus:not(:active) {
+ background-color: rgba(0, 0, 0, .12)
+}
+
+.mdl-button:active {
+ background-color: rgba(158, 158, 158, .4)
+}
+
+.mdl-button.mdl-button--colored {
+ color: rgb(63, 81, 181)
+}
+
+.mdl-button.mdl-button--colored:focus:not(:active) {
+ background-color: rgba(0, 0, 0, .12)
+}
+
+input.mdl-button[type="submit"] {
+ -webkit-appearance: none
+}
+
+.mdl-button--raised {
+ background: rgba(158, 158, 158, .2);
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12)
+}
+
+.mdl-button--raised:active {
+ box-shadow: 0 4px 5px 0 rgba(0, 0, 0, .14), 0 1px 10px 0 rgba(0, 0, 0, .12), 0 2px 4px -1px rgba(0, 0, 0, .2);
+ background-color: rgba(158, 158, 158, .4)
+}
+
+.mdl-button--raised:focus:not(:active) {
+ box-shadow: 0 0 8px rgba(0, 0, 0, .18), 0 8px 16px rgba(0, 0, 0, .36);
+ background-color: rgba(158, 158, 158, .4)
+}
+
+.mdl-button--raised.mdl-button--colored {
+ background: rgb(63, 81, 181);
+ color: rgb(255, 255, 255)
+}
+
+.mdl-button--raised.mdl-button--colored:hover {
+ background-color: rgb(63, 81, 181)
+}
+
+.mdl-button--raised.mdl-button--colored:active {
+ background-color: rgb(63, 81, 181)
+}
+
+.mdl-button--raised.mdl-button--colored:focus:not(:active) {
+ background-color: rgb(63, 81, 181)
+}
+
+.mdl-button--raised.mdl-button--colored .mdl-ripple {
+ background: rgb(255, 255, 255)
+}
+
+.mdl-button--fab {
+ border-radius: 50%;
+ font-size: 24px;
+ height: 56px;
+ margin: auto;
+ min-width: 56px;
+ width: 56px;
+ padding: 0;
+ overflow: hidden;
+ background: rgba(158, 158, 158, .2);
+ box-shadow: 0 1px 1.5px 0 rgba(0, 0, 0, .12), 0 1px 1px 0 rgba(0, 0, 0, .24);
+ position: relative;
+ line-height: normal
+}
+
+.mdl-button--fab .material-icons {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ -webkit-transform: translate(-12px, -12px);
+ transform: translate(-12px, -12px);
+ line-height: 24px;
+ width: 24px
+}
+
+.mdl-button--fab.mdl-button--mini-fab {
+ height: 40px;
+ min-width: 40px;
+ width: 40px
+}
+
+.mdl-button--fab .mdl-button__ripple-container {
+ border-radius: 50%;
+ -webkit-mask-image: -webkit-radial-gradient(circle, #fff, #000)
+}
+
+.mdl-button--fab:active {
+ box-shadow: 0 4px 5px 0 rgba(0, 0, 0, .14), 0 1px 10px 0 rgba(0, 0, 0, .12), 0 2px 4px -1px rgba(0, 0, 0, .2);
+ background-color: rgba(158, 158, 158, .4)
+}
+
+.mdl-button--fab:focus:not(:active) {
+ box-shadow: 0 0 8px rgba(0, 0, 0, .18), 0 8px 16px rgba(0, 0, 0, .36);
+ background-color: rgba(158, 158, 158, .4)
+}
+
+.mdl-button--fab.mdl-button--colored {
+ background: rgb(255, 64, 129);
+ color: rgb(255, 255, 255)
+}
+
+.mdl-button--fab.mdl-button--colored:hover {
+ background-color: rgb(255, 64, 129)
+}
+
+.mdl-button--fab.mdl-button--colored:focus:not(:active) {
+ background-color: rgb(255, 64, 129)
+}
+
+.mdl-button--fab.mdl-button--colored:active {
+ background-color: rgb(255, 64, 129)
+}
+
+.mdl-button--fab.mdl-button--colored .mdl-ripple {
+ background: rgb(255, 255, 255)
+}
+
+.mdl-button--icon {
+ border-radius: 50%;
+ font-size: 24px;
+ height: 32px;
+ margin-left: 0;
+ margin-right: 0;
+ min-width: 32px;
+ width: 32px;
+ padding: 0;
+ overflow: hidden;
+ color: inherit;
+ line-height: normal
+}
+
+.mdl-button--icon .material-icons {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ -webkit-transform: translate(-12px, -12px);
+ transform: translate(-12px, -12px);
+ line-height: 24px;
+ width: 24px
+}
+
+.mdl-button--icon.mdl-button--mini-icon {
+ height: 24px;
+ min-width: 24px;
+ width: 24px
+}
+
+.mdl-button--icon.mdl-button--mini-icon .material-icons {
+ top: 0;
+ left: 0
+}
+
+.mdl-button--icon .mdl-button__ripple-container {
+ border-radius: 50%;
+ -webkit-mask-image: -webkit-radial-gradient(circle, #fff, #000)
+}
+
+.mdl-button__ripple-container {
+ display: block;
+ height: 100%;
+ left: 0;
+ position: absolute;
+ top: 0;
+ width: 100%;
+ z-index: 0;
+ overflow: hidden
+}
+
+.mdl-button[disabled] .mdl-button__ripple-container .mdl-ripple,
+.mdl-button.mdl-button--disabled .mdl-button__ripple-container .mdl-ripple {
+ background-color: transparent
+}
+
+.mdl-button--primary.mdl-button--primary {
+ color: rgb(63, 81, 181)
+}
+
+.mdl-button--primary.mdl-button--primary .mdl-ripple {
+ background: rgb(255, 255, 255)
+}
+
+.mdl-button--primary.mdl-button--primary.mdl-button--raised,
+.mdl-button--primary.mdl-button--primary.mdl-button--fab {
+ color: rgb(255, 255, 255);
+ background-color: rgb(63, 81, 181)
+}
+
+.mdl-button--accent.mdl-button--accent {
+ color: rgb(255, 64, 129)
+}
+
+.mdl-button--accent.mdl-button--accent .mdl-ripple {
+ background: rgb(255, 255, 255)
+}
+
+.mdl-button--accent.mdl-button--accent.mdl-button--raised,
+.mdl-button--accent.mdl-button--accent.mdl-button--fab {
+ color: rgb(255, 255, 255);
+ background-color: rgb(255, 64, 129)
+}
+
+.mdl-button[disabled][disabled],
+.mdl-button.mdl-button--disabled.mdl-button--disabled {
+ color: rgba(0, 0, 0, .26);
+ cursor: default;
+ background-color: transparent
+}
+
+.mdl-button--fab[disabled][disabled],
+.mdl-button--fab.mdl-button--disabled.mdl-button--disabled {
+ background-color: rgba(0, 0, 0, .12);
+ color: rgba(0, 0, 0, .26)
+}
+
+.mdl-button--raised[disabled][disabled],
+.mdl-button--raised.mdl-button--disabled.mdl-button--disabled {
+ background-color: rgba(0, 0, 0, .12);
+ color: rgba(0, 0, 0, .26);
+ box-shadow: none
+}
+
+.mdl-button--colored[disabled][disabled],
+.mdl-button--colored.mdl-button--disabled.mdl-button--disabled {
+ color: rgba(0, 0, 0, .26)
+}
+
+.mdl-button .material-icons {
+ vertical-align: middle
+}
+
+.mdl-card {
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: column;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ font-size: 16px;
+ font-weight: 400;
+ min-height: 200px;
+ overflow: hidden;
+ width: 330px;
+ z-index: 1;
+ position: relative;
+ background: #fff;
+ border-radius: 2px;
+ box-sizing: border-box
+}
+
+.mdl-card__media {
+ background-color: rgb(255, 64, 129);
+ background-repeat: repeat;
+ background-position: 50% 50%;
+ background-size: cover;
+ background-origin: padding-box;
+ background-attachment: scroll;
+ box-sizing: border-box
+}
+
+.mdl-card__title {
+ -webkit-align-items: center;
+ -ms-flex-align: center;
+ align-items: center;
+ color: #000;
+ display: block;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-justify-content: stretch;
+ -ms-flex-pack: stretch;
+ justify-content: stretch;
+ line-height: normal;
+ padding: 16px;
+ -webkit-perspective-origin: 165px 56px;
+ perspective-origin: 165px 56px;
+ -webkit-transform-origin: 165px 56px;
+ transform-origin: 165px 56px;
+ box-sizing: border-box
+}
+
+.mdl-card__title.mdl-card--border {
+ border-bottom: 1px solid rgba(0, 0, 0, .1)
+}
+
+.mdl-card__title-text {
+ -webkit-align-self: flex-end;
+ -ms-flex-item-align: end;
+ align-self: flex-end;
+ color: inherit;
+ display: block;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ font-size: 24px;
+ font-weight: 300;
+ line-height: normal;
+ overflow: hidden;
+ -webkit-transform-origin: 149px 48px;
+ transform-origin: 149px 48px;
+ margin: 0
+}
+
+.mdl-card__subtitle-text {
+ font-size: 14px;
+ color: rgba(0, 0, 0, .54);
+ margin: 0
+}
+
+.mdl-card__supporting-text {
+ color: rgba(0, 0, 0, .54);
+ font-size: 1rem;
+ line-height: 18px;
+ overflow: hidden;
+ padding: 16px;
+ width: 90%
+}
+
+.mdl-card__supporting-text.mdl-card--border {
+ border-bottom: 1px solid rgba(0, 0, 0, .1)
+}
+
+.mdl-card__actions {
+ font-size: 16px;
+ line-height: normal;
+ width: 100%;
+ background-color: transparent;
+ padding: 8px;
+ box-sizing: border-box
+}
+
+.mdl-card__actions.mdl-card--border {
+ border-top: 1px solid rgba(0, 0, 0, .1)
+}
+
+.mdl-card--expand {
+ -webkit-flex-grow: 1;
+ -ms-flex-positive: 1;
+ flex-grow: 1
+}
+
+.mdl-card__menu {
+ position: absolute;
+ right: 16px;
+ top: 16px
+}
+
+.mdl-checkbox {
+ position: relative;
+ z-index: 1;
+ vertical-align: middle;
+ display: inline-block;
+ box-sizing: border-box;
+ width: 100%;
+ height: 24px;
+ margin: 0;
+ padding: 0
+}
+
+.mdl-checkbox.is-upgraded {
+ padding-left: 24px
+}
+
+.mdl-checkbox__input {
+ line-height: 24px
+}
+
+.mdl-checkbox.is-upgraded .mdl-checkbox__input {
+ position: absolute;
+ width: 0;
+ height: 0;
+ margin: 0;
+ padding: 0;
+ opacity: 0;
+ -ms-appearance: none;
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ appearance: none;
+ border: none
+}
+
+.mdl-checkbox__box-outline {
+ position: absolute;
+ top: 3px;
+ left: 0;
+ display: inline-block;
+ box-sizing: border-box;
+ width: 16px;
+ height: 16px;
+ margin: 0;
+ cursor: pointer;
+ overflow: hidden;
+ border: 2px solid rgba(0, 0, 0, .54);
+ border-radius: 2px;
+ z-index: 2
+}
+
+.mdl-checkbox.is-checked .mdl-checkbox__box-outline {
+ border: 2px solid rgb(63, 81, 181)
+}
+
+fieldset[disabled] .mdl-checkbox .mdl-checkbox__box-outline,
+.mdl-checkbox.is-disabled .mdl-checkbox__box-outline {
+ border: 2px solid rgba(0, 0, 0, .26);
+ cursor: auto
+}
+
+.mdl-checkbox__focus-helper {
+ position: absolute;
+ top: 3px;
+ left: 0;
+ display: inline-block;
+ box-sizing: border-box;
+ width: 16px;
+ height: 16px;
+ border-radius: 50%;
+ background-color: transparent
+}
+
+.mdl-checkbox.is-focused .mdl-checkbox__focus-helper {
+ box-shadow: 0 0 0 8px rgba(0, 0, 0, .1);
+ background-color: rgba(0, 0, 0, .1)
+}
+
+.mdl-checkbox.is-focused.is-checked .mdl-checkbox__focus-helper {
+ box-shadow: 0 0 0 8px rgba(63, 81, 181, .26);
+ background-color: rgba(63, 81, 181, .26)
+}
+
+.mdl-checkbox__tick-outline {
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 100%;
+ width: 100%;
+ -webkit-mask: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8ZGVmcz4KICAgIDxjbGlwUGF0aCBpZD0iY2xpcCI+CiAgICAgIDxwYXRoCiAgICAgICAgIGQ9Ik0gMCwwIDAsMSAxLDEgMSwwIDAsMCB6IE0gMC44NTM0Mzc1LDAuMTY3MTg3NSAwLjk1OTY4NzUsMC4yNzMxMjUgMC40MjkzNzUsMC44MDM0Mzc1IDAuMzIzMTI1LDAuOTA5Njg3NSAwLjIxNzE4NzUsMC44MDM0Mzc1IDAuMDQwMzEyNSwwLjYyNjg3NSAwLjE0NjU2MjUsMC41MjA2MjUgMC4zMjMxMjUsMC42OTc1IDAuODUzNDM3NSwwLjE2NzE4NzUgeiIKICAgICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KICAgIDwvY2xpcFBhdGg+CiAgICA8bWFzayBpZD0ibWFzayIgbWFza1VuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgbWFza0NvbnRlbnRVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giPgogICAgICA8cGF0aAogICAgICAgICBkPSJNIDAsMCAwLDEgMSwxIDEsMCAwLDAgeiBNIDAuODUzNDM3NSwwLjE2NzE4NzUgMC45NTk2ODc1LDAuMjczMTI1IDAuNDI5Mzc1LDAuODAzNDM3NSAwLjMyMzEyNSwwLjkwOTY4NzUgMC4yMTcxODc1LDAuODAzNDM3NSAwLjA0MDMxMjUsMC42MjY4NzUgMC4xNDY1NjI1LDAuNTIwNjI1IDAuMzIzMTI1LDAuNjk3NSAwLjg1MzQzNzUsMC4xNjcxODc1IHoiCiAgICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmUiIC8+CiAgICA8L21hc2s+CiAgPC9kZWZzPgogIDxyZWN0CiAgICAgd2lkdGg9IjEiCiAgICAgaGVpZ2h0PSIxIgogICAgIHg9IjAiCiAgICAgeT0iMCIKICAgICBjbGlwLXBhdGg9InVybCgjY2xpcCkiCiAgICAgc3R5bGU9ImZpbGw6IzAwMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KPC9zdmc+Cg==");
+ mask: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8ZGVmcz4KICAgIDxjbGlwUGF0aCBpZD0iY2xpcCI+CiAgICAgIDxwYXRoCiAgICAgICAgIGQ9Ik0gMCwwIDAsMSAxLDEgMSwwIDAsMCB6IE0gMC44NTM0Mzc1LDAuMTY3MTg3NSAwLjk1OTY4NzUsMC4yNzMxMjUgMC40MjkzNzUsMC44MDM0Mzc1IDAuMzIzMTI1LDAuOTA5Njg3NSAwLjIxNzE4NzUsMC44MDM0Mzc1IDAuMDQwMzEyNSwwLjYyNjg3NSAwLjE0NjU2MjUsMC41MjA2MjUgMC4zMjMxMjUsMC42OTc1IDAuODUzNDM3NSwwLjE2NzE4NzUgeiIKICAgICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KICAgIDwvY2xpcFBhdGg+CiAgICA8bWFzayBpZD0ibWFzayIgbWFza1VuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgbWFza0NvbnRlbnRVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giPgogICAgICA8cGF0aAogICAgICAgICBkPSJNIDAsMCAwLDEgMSwxIDEsMCAwLDAgeiBNIDAuODUzNDM3NSwwLjE2NzE4NzUgMC45NTk2ODc1LDAuMjczMTI1IDAuNDI5Mzc1LDAuODAzNDM3NSAwLjMyMzEyNSwwLjkwOTY4NzUgMC4yMTcxODc1LDAuODAzNDM3NSAwLjA0MDMxMjUsMC42MjY4NzUgMC4xNDY1NjI1LDAuNTIwNjI1IDAuMzIzMTI1LDAuNjk3NSAwLjg1MzQzNzUsMC4xNjcxODc1IHoiCiAgICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmUiIC8+CiAgICA8L21hc2s+CiAgPC9kZWZzPgogIDxyZWN0CiAgICAgd2lkdGg9IjEiCiAgICAgaGVpZ2h0PSIxIgogICAgIHg9IjAiCiAgICAgeT0iMCIKICAgICBjbGlwLXBhdGg9InVybCgjY2xpcCkiCiAgICAgc3R5bGU9ImZpbGw6IzAwMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZSIgLz4KPC9zdmc+Cg==");
+ background: 0 0;
+ transition-duration: .28s;
+ transition-timing-function: cubic-bezier(.4, 0, .2, 1);
+ transition-property: background
+}
+
+.mdl-checkbox.is-checked .mdl-checkbox__tick-outline {
+ background: rgb(63, 81, 181)url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K")
+}
+
+fieldset[disabled] .mdl-checkbox.is-checked .mdl-checkbox__tick-outline,
+.mdl-checkbox.is-checked.is-disabled .mdl-checkbox__tick-outline {
+ background: rgba(0, 0, 0, .26)url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K")
+}
+
+.mdl-checkbox__label {
+ position: relative;
+ cursor: pointer;
+ font-size: 16px;
+ line-height: 24px;
+ margin: 0
+}
+
+fieldset[disabled] .mdl-checkbox .mdl-checkbox__label,
+.mdl-checkbox.is-disabled .mdl-checkbox__label {
+ color: rgba(0, 0, 0, .26);
+ cursor: auto
+}
+
+.mdl-checkbox__ripple-container {
+ position: absolute;
+ z-index: 2;
+ top: -6px;
+ left: -10px;
+ box-sizing: border-box;
+ width: 36px;
+ height: 36px;
+ border-radius: 50%;
+ cursor: pointer;
+ overflow: hidden;
+ -webkit-mask-image: -webkit-radial-gradient(circle, #fff, #000)
+}
+
+.mdl-checkbox__ripple-container .mdl-ripple {
+ background: rgb(63, 81, 181)
+}
+
+fieldset[disabled] .mdl-checkbox .mdl-checkbox__ripple-container,
+.mdl-checkbox.is-disabled .mdl-checkbox__ripple-container {
+ cursor: auto
+}
+
+fieldset[disabled] .mdl-checkbox .mdl-checkbox__ripple-container .mdl-ripple,
+.mdl-checkbox.is-disabled .mdl-checkbox__ripple-container .mdl-ripple {
+ background: 0 0
+}
+
+.mdl-chip {
+ height: 32px;
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ line-height: 32px;
+ padding: 0 12px;
+ border: 0;
+ border-radius: 16px;
+ background-color: #dedede;
+ display: inline-block;
+ color: rgba(0, 0, 0, .87);
+ margin: 2px 0;
+ font-size: 0;
+ white-space: nowrap
+}
+
+.mdl-chip__text {
+ font-size: 13px;
+ vertical-align: middle;
+ display: inline-block
+}
+
+.mdl-chip__action {
+ height: 24px;
+ width: 24px;
+ background: 0 0;
+ opacity: .54;
+ cursor: pointer;
+ padding: 0;
+ margin: 0 0 0 4px;
+ font-size: 13px;
+ text-decoration: none;
+ color: rgba(0, 0, 0, .87);
+ border: none;
+ outline: none
+}
+
+.mdl-chip__action,
+.mdl-chip__contact {
+ display: inline-block;
+ vertical-align: middle;
+ overflow: hidden;
+ text-align: center
+}
+
+.mdl-chip__contact {
+ height: 32px;
+ width: 32px;
+ border-radius: 16px;
+ margin-right: 8px;
+ font-size: 18px;
+ line-height: 32px
+}
+
+.mdl-chip:focus {
+ outline: 0;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12)
+}
+
+.mdl-chip:active {
+ background-color: #d6d6d6
+}
+
+.mdl-chip--deletable {
+ padding-right: 4px
+}
+
+.mdl-chip--contact {
+ padding-left: 0
+}
+
+.mdl-data-table {
+ position: relative;
+ border: 1px solid rgba(0, 0, 0, .12);
+ border-collapse: collapse;
+ white-space: nowrap;
+ font-size: 13px;
+ background-color: #fff
+}
+
+.mdl-data-table thead {
+ padding-bottom: 3px
+}
+
+.mdl-data-table thead .mdl-data-table__select {
+ margin-top: 0
+}
+
+.mdl-data-table tbody tr {
+ position: relative;
+ height: 48px;
+ transition-duration: .28s;
+ transition-timing-function: cubic-bezier(.4, 0, .2, 1);
+ transition-property: background-color
+}
+
+.mdl-data-table tbody tr.is-selected {
+ background-color: #e0e0e0
+}
+
+.mdl-data-table tbody tr:hover {
+ background-color: #eee
+}
+
+.mdl-data-table td {
+ text-align: right
+}
+
+.mdl-data-table th {
+ padding: 0 18px 12px 18px;
+ text-align: right
+}
+
+.mdl-data-table td:first-of-type,
+.mdl-data-table th:first-of-type {
+ padding-left: 24px
+}
+
+.mdl-data-table td:last-of-type,
+.mdl-data-table th:last-of-type {
+ padding-right: 24px
+}
+
+.mdl-data-table td {
+ position: relative;
+ height: 48px;
+ border-top: 1px solid rgba(0, 0, 0, .12);
+ border-bottom: 1px solid rgba(0, 0, 0, .12);
+ padding: 12px 18px;
+ box-sizing: border-box
+}
+
+.mdl-data-table td,
+.mdl-data-table td .mdl-data-table__select {
+ vertical-align: middle
+}
+
+.mdl-data-table th {
+ position: relative;
+ vertical-align: bottom;
+ text-overflow: ellipsis;
+ font-weight: 700;
+ line-height: 24px;
+ letter-spacing: 0;
+ height: 48px;
+ font-size: 12px;
+ color: rgba(0, 0, 0, .54);
+ padding-bottom: 8px;
+ box-sizing: border-box
+}
+
+.mdl-data-table th.mdl-data-table__header--sorted-ascending,
+.mdl-data-table th.mdl-data-table__header--sorted-descending {
+ color: rgba(0, 0, 0, .87)
+}
+
+.mdl-data-table th.mdl-data-table__header--sorted-ascending:before,
+.mdl-data-table th.mdl-data-table__header--sorted-descending:before {
+ font-family: 'Material Icons';
+ font-weight: 400;
+ font-style: normal;
+ line-height: 1;
+ letter-spacing: normal;
+ text-transform: none;
+ display: inline-block;
+ word-wrap: normal;
+ -moz-font-feature-settings: 'liga';
+ font-feature-settings: 'liga';
+ -webkit-font-feature-settings: 'liga';
+ -webkit-font-smoothing: antialiased;
+ font-size: 16px;
+ content: "\e5d8";
+ margin-right: 5px;
+ vertical-align: sub
+}
+
+.mdl-data-table th.mdl-data-table__header--sorted-ascending:hover,
+.mdl-data-table th.mdl-data-table__header--sorted-descending:hover {
+ cursor: pointer
+}
+
+.mdl-data-table th.mdl-data-table__header--sorted-ascending:hover:before,
+.mdl-data-table th.mdl-data-table__header--sorted-descending:hover:before {
+ color: rgba(0, 0, 0, .26)
+}
+
+.mdl-data-table th.mdl-data-table__header--sorted-descending:before {
+ content: "\e5db"
+}
+
+.mdl-data-table__select {
+ width: 16px
+}
+
+.mdl-data-table__cell--non-numeric.mdl-data-table__cell--non-numeric {
+ text-align: left
+}
+
+.mdl-dialog {
+ border: none;
+ box-shadow: 0 9px 46px 8px rgba(0, 0, 0, .14), 0 11px 15px -7px rgba(0, 0, 0, .12), 0 24px 38px 3px rgba(0, 0, 0, .2);
+ width: 280px
+}
+
+.mdl-dialog__title {
+ padding: 24px 24px 0;
+ margin: 0;
+ font-size: 2.5rem
+}
+
+.mdl-dialog__actions {
+ padding: 8px 8px 8px 24px;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: row-reverse;
+ -ms-flex-direction: row-reverse;
+ flex-direction: row-reverse;
+ -webkit-flex-wrap: wrap;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap
+}
+
+.mdl-dialog__actions>* {
+ margin-right: 8px;
+ height: 36px
+}
+
+.mdl-dialog__actions>*:first-child {
+ margin-right: 0
+}
+
+.mdl-dialog__actions--full-width {
+ padding: 0 0 8px
+}
+
+.mdl-dialog__actions--full-width>* {
+ height: 48px;
+ -webkit-flex: 0 0 100%;
+ -ms-flex: 0 0 100%;
+ flex: 0 0 100%;
+ padding-right: 16px;
+ margin-right: 0;
+ text-align: right
+}
+
+.mdl-dialog__content {
+ padding: 20px 24px 24px;
+ color: rgba(0, 0, 0, .54)
+}
+
+.mdl-mega-footer {
+ padding: 16px 40px;
+ color: #9e9e9e;
+ background-color: #424242
+}
+
+.mdl-mega-footer--top-section:after,
+.mdl-mega-footer--middle-section:after,
+.mdl-mega-footer--bottom-section:after,
+.mdl-mega-footer__top-section:after,
+.mdl-mega-footer__middle-section:after,
+.mdl-mega-footer__bottom-section:after {
+ content: '';
+ display: block;
+ clear: both
+}
+
+.mdl-mega-footer--left-section,
+.mdl-mega-footer__left-section,
+.mdl-mega-footer--right-section,
+.mdl-mega-footer__right-section {
+ margin-bottom: 16px
+}
+
+.mdl-mega-footer--right-section a,
+.mdl-mega-footer__right-section a {
+ display: block;
+ margin-bottom: 16px;
+ color: inherit;
+ text-decoration: none
+}
+
+@media screen and (min-width:760px) {
+ .mdl-mega-footer--left-section,
+ .mdl-mega-footer__left-section {
+ float: left
+ }
+ .mdl-mega-footer--right-section,
+ .mdl-mega-footer__right-section {
+ float: right
+ }
+ .mdl-mega-footer--right-section a,
+ .mdl-mega-footer__right-section a {
+ display: inline-block;
+ margin-left: 16px;
+ line-height: 36px;
+ vertical-align: middle
+ }
+}
+
+.mdl-mega-footer--social-btn,
+.mdl-mega-footer__social-btn {
+ width: 36px;
+ height: 36px;
+ padding: 0;
+ margin: 0;
+ background-color: #9e9e9e;
+ border: none
+}
+
+.mdl-mega-footer--drop-down-section,
+.mdl-mega-footer__drop-down-section {
+ display: block;
+ position: relative
+}
+
+@media screen and (min-width:760px) {
+ .mdl-mega-footer--drop-down-section,
+ .mdl-mega-footer__drop-down-section {
+ width: 33%
+ }
+ .mdl-mega-footer--drop-down-section:nth-child(1),
+ .mdl-mega-footer--drop-down-section:nth-child(2),
+ .mdl-mega-footer__drop-down-section:nth-child(1),
+ .mdl-mega-footer__drop-down-section:nth-child(2) {
+ float: left
+ }
+ .mdl-mega-footer--drop-down-section:nth-child(3),
+ .mdl-mega-footer__drop-down-section:nth-child(3) {
+ float: right
+ }
+ .mdl-mega-footer--drop-down-section:nth-child(3):after,
+ .mdl-mega-footer__drop-down-section:nth-child(3):after {
+ clear: right
+ }
+ .mdl-mega-footer--drop-down-section:nth-child(4),
+ .mdl-mega-footer__drop-down-section:nth-child(4) {
+ clear: right;
+ float: right
+ }
+ .mdl-mega-footer--middle-section:after,
+ .mdl-mega-footer__middle-section:after {
+ content: '';
+ display: block;
+ clear: both
+ }
+ .mdl-mega-footer--bottom-section,
+ .mdl-mega-footer__bottom-section {
+ padding-top: 0
+ }
+}
+
+@media screen and (min-width:900px) {
+ .mdl-mega-footer--drop-down-section,
+ .mdl-mega-footer--drop-down-section:nth-child(3),
+ .mdl-mega-footer--drop-down-section:nth-child(4),
+ .mdl-mega-footer__drop-down-section,
+ .mdl-mega-footer__drop-down-section:nth-child(3),
+ .mdl-mega-footer__drop-down-section:nth-child(4) {
+ width: 24%;
+ float: left
+ }
+}
+
+.mdl-mega-footer--heading-checkbox,
+.mdl-mega-footer__heading-checkbox {
+ position: absolute;
+ width: 100%;
+ height: 55.8px;
+ padding: 32px;
+ margin: -16px 0 0;
+ cursor: pointer;
+ z-index: 1;
+ opacity: 0
+}
+
+.mdl-mega-footer--heading-checkbox+.mdl-mega-footer--heading:after,
+.mdl-mega-footer--heading-checkbox+.mdl-mega-footer__heading:after,
+.mdl-mega-footer__heading-checkbox+.mdl-mega-footer--heading:after,
+.mdl-mega-footer__heading-checkbox+.mdl-mega-footer__heading:after {
+ font-family: 'Material Icons';
+ content: '\E5CE'
+}
+
+.mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer--link-list,
+.mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer__link-list,
+.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list,
+.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list,
+.mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer--link-list,
+.mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer__link-list,
+.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list,
+.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list {
+ display: none
+}
+
+.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading:after,
+.mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading:after,
+.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading:after,
+.mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading:after {
+ font-family: 'Material Icons';
+ content: '\E5CF'
+}
+
+.mdl-mega-footer--heading,
+.mdl-mega-footer__heading {
+ position: relative;
+ width: 100%;
+ padding-right: 39.8px;
+ margin-bottom: 16px;
+ box-sizing: border-box;
+ font-size: 14px;
+ line-height: 23.8px;
+ font-weight: 500;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ color: #e0e0e0
+}
+
+.mdl-mega-footer--heading:after,
+.mdl-mega-footer__heading:after {
+ content: '';
+ position: absolute;
+ top: 0;
+ right: 0;
+ display: block;
+ width: 23.8px;
+ height: 23.8px;
+ background-size: cover
+}
+
+.mdl-mega-footer--link-list,
+.mdl-mega-footer__link-list {
+ list-style: none;
+ padding: 0;
+ margin: 0 0 32px
+}
+
+.mdl-mega-footer--link-list:after,
+.mdl-mega-footer__link-list:after {
+ clear: both;
+ display: block;
+ content: ''
+}
+
+.mdl-mega-footer--link-list li,
+.mdl-mega-footer__link-list li {
+ font-size: 14px;
+ font-weight: 400;
+ letter-spacing: 0;
+ line-height: 20px
+}
+
+.mdl-mega-footer--link-list a,
+.mdl-mega-footer__link-list a {
+ color: inherit;
+ text-decoration: none;
+ white-space: nowrap
+}
+
+@media screen and (min-width:760px) {
+ .mdl-mega-footer--heading-checkbox,
+ .mdl-mega-footer__heading-checkbox {
+ display: none
+ }
+ .mdl-mega-footer--heading-checkbox+.mdl-mega-footer--heading:after,
+ .mdl-mega-footer--heading-checkbox+.mdl-mega-footer__heading:after,
+ .mdl-mega-footer__heading-checkbox+.mdl-mega-footer--heading:after,
+ .mdl-mega-footer__heading-checkbox+.mdl-mega-footer__heading:after {
+ content: ''
+ }
+ .mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer--link-list,
+ .mdl-mega-footer--heading-checkbox:checked~.mdl-mega-footer__link-list,
+ .mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list,
+ .mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list,
+ .mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer--link-list,
+ .mdl-mega-footer__heading-checkbox:checked~.mdl-mega-footer__link-list,
+ .mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading+.mdl-mega-footer__link-list,
+ .mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading+.mdl-mega-footer--link-list {
+ display: block
+ }
+ .mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer--heading:after,
+ .mdl-mega-footer--heading-checkbox:checked+.mdl-mega-footer__heading:after,
+ .mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer--heading:after,
+ .mdl-mega-footer__heading-checkbox:checked+.mdl-mega-footer__heading:after {
+ content: ''
+ }
+}
+
+.mdl-mega-footer--bottom-section,
+.mdl-mega-footer__bottom-section {
+ padding-top: 16px;
+ margin-bottom: 16px
+}
+
+.mdl-logo {
+ margin-bottom: 16px;
+ color: #fff
+}
+
+.mdl-mega-footer--bottom-section .mdl-mega-footer--link-list li,
+.mdl-mega-footer__bottom-section .mdl-mega-footer__link-list li {
+ float: left;
+ margin-bottom: 0;
+ margin-right: 16px
+}
+
+@media screen and (min-width:760px) {
+ .mdl-logo {
+ float: left;
+ margin-bottom: 0;
+ margin-right: 16px
+ }
+}
+
+.mdl-mini-footer {
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-flow: row wrap;
+ -ms-flex-flow: row wrap;
+ flex-flow: row wrap;
+ -webkit-justify-content: space-between;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ padding: 32px 16px;
+ color: #9e9e9e;
+ background-color: #424242
+}
+
+.mdl-mini-footer:after {
+ content: '';
+ display: block
+}
+
+.mdl-mini-footer .mdl-logo {
+ line-height: 36px
+}
+
+.mdl-mini-footer--link-list,
+.mdl-mini-footer__link-list {
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-flow: row nowrap;
+ -ms-flex-flow: row nowrap;
+ flex-flow: row nowrap;
+ list-style: none;
+ margin: 0;
+ padding: 0
+}
+
+.mdl-mini-footer--link-list li,
+.mdl-mini-footer__link-list li {
+ margin-bottom: 0;
+ margin-right: 16px
+}
+
+@media screen and (min-width:760px) {
+ .mdl-mini-footer--link-list li,
+ .mdl-mini-footer__link-list li {
+ line-height: 36px
+ }
+}
+
+.mdl-mini-footer--link-list a,
+.mdl-mini-footer__link-list a {
+ color: inherit;
+ text-decoration: none;
+ white-space: nowrap
+}
+
+.mdl-mini-footer--left-section,
+.mdl-mini-footer__left-section {
+ display: inline-block;
+ -webkit-order: 0;
+ -ms-flex-order: 0;
+ order: 0
+}
+
+.mdl-mini-footer--right-section,
+.mdl-mini-footer__right-section {
+ display: inline-block;
+ -webkit-order: 1;
+ -ms-flex-order: 1;
+ order: 1
+}
+
+.mdl-mini-footer--social-btn,
+.mdl-mini-footer__social-btn {
+ width: 36px;
+ height: 36px;
+ padding: 0;
+ margin: 0;
+ background-color: #9e9e9e;
+ border: none
+}
+
+.mdl-icon-toggle {
+ position: relative;
+ z-index: 1;
+ vertical-align: middle;
+ display: inline-block;
+ height: 32px;
+ margin: 0;
+ padding: 0
+}
+
+.mdl-icon-toggle__input {
+ line-height: 32px
+}
+
+.mdl-icon-toggle.is-upgraded .mdl-icon-toggle__input {
+ position: absolute;
+ width: 0;
+ height: 0;
+ margin: 0;
+ padding: 0;
+ opacity: 0;
+ -ms-appearance: none;
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ appearance: none;
+ border: none
+}
+
+.mdl-icon-toggle__label {
+ display: inline-block;
+ position: relative;
+ cursor: pointer;
+ height: 32px;
+ width: 32px;
+ min-width: 32px;
+ color: #616161;
+ border-radius: 50%;
+ padding: 0;
+ margin-left: 0;
+ margin-right: 0;
+ text-align: center;
+ background-color: transparent;
+ will-change: background-color;
+ transition: background-color .2s cubic-bezier(.4, 0, .2, 1), color .2s cubic-bezier(.4, 0, .2, 1)
+}
+
+.mdl-icon-toggle__label.material-icons {
+ line-height: 32px;
+ font-size: 24px
+}
+
+.mdl-icon-toggle.is-checked .mdl-icon-toggle__label {
+ color: rgb(63, 81, 181)
+}
+
+.mdl-icon-toggle.is-disabled .mdl-icon-toggle__label {
+ color: rgba(0, 0, 0, .26);
+ cursor: auto;
+ transition: none
+}
+
+.mdl-icon-toggle.is-focused .mdl-icon-toggle__label {
+ background-color: rgba(0, 0, 0, .12)
+}
+
+.mdl-icon-toggle.is-focused.is-checked .mdl-icon-toggle__label {
+ background-color: rgba(63, 81, 181, .26)
+}
+
+.mdl-icon-toggle__ripple-container {
+ position: absolute;
+ z-index: 2;
+ top: -2px;
+ left: -2px;
+ box-sizing: border-box;
+ width: 36px;
+ height: 36px;
+ border-radius: 50%;
+ cursor: pointer;
+ overflow: hidden;
+ -webkit-mask-image: -webkit-radial-gradient(circle, #fff, #000)
+}
+
+.mdl-icon-toggle__ripple-container .mdl-ripple {
+ background: #616161
+}
+
+.mdl-icon-toggle.is-disabled .mdl-icon-toggle__ripple-container {
+ cursor: auto
+}
+
+.mdl-icon-toggle.is-disabled .mdl-icon-toggle__ripple-container .mdl-ripple {
+ background: 0 0
+}
+
+.mdl-list {
+ display: block;
+ padding: 8px 0;
+ list-style: none
+}
+
+.mdl-list__item {
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ font-size: 16px;
+ font-weight: 400;
+ letter-spacing: .04em;
+ line-height: 1;
+ min-height: 48px;
+ -webkit-flex-direction: row;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-flex-wrap: nowrap;
+ -ms-flex-wrap: nowrap;
+ flex-wrap: nowrap;
+ padding: 16px;
+ cursor: default;
+ color: rgba(0, 0, 0, .87);
+ overflow: hidden
+}
+
+.mdl-list__item,
+.mdl-list__item .mdl-list__item-primary-content {
+ box-sizing: border-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-align-items: center;
+ -ms-flex-align: center;
+ align-items: center
+}
+
+.mdl-list__item .mdl-list__item-primary-content {
+ -webkit-order: 0;
+ -ms-flex-order: 0;
+ order: 0;
+ -webkit-flex-grow: 2;
+ -ms-flex-positive: 2;
+ flex-grow: 2;
+ text-decoration: none
+}
+
+.mdl-list__item .mdl-list__item-primary-content .mdl-list__item-icon {
+ margin-right: 32px
+}
+
+.mdl-list__item .mdl-list__item-primary-content .mdl-list__item-avatar {
+ margin-right: 16px
+}
+
+.mdl-list__item .mdl-list__item-secondary-content {
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-flow: column;
+ -ms-flex-flow: column;
+ flex-flow: column;
+ -webkit-align-items: flex-end;
+ -ms-flex-align: end;
+ align-items: flex-end;
+ margin-left: 16px
+}
+
+.mdl-list__item .mdl-list__item-secondary-content .mdl-list__item-secondary-action label {
+ display: inline
+}
+
+.mdl-list__item .mdl-list__item-secondary-content .mdl-list__item-secondary-info {
+ font-size: 12px;
+ font-weight: 400;
+ line-height: 1;
+ letter-spacing: 0;
+ color: rgba(0, 0, 0, .54)
+}
+
+.mdl-list__item .mdl-list__item-secondary-content .mdl-list__item-sub-header {
+ padding: 0 0 0 16px
+}
+
+.mdl-list__item-icon,
+.mdl-list__item-icon.material-icons {
+ height: 24px;
+ width: 24px;
+ font-size: 24px;
+ box-sizing: border-box;
+ color: #757575
+}
+
+.mdl-list__item-avatar,
+.mdl-list__item-avatar.material-icons {
+ height: 40px;
+ width: 40px;
+ box-sizing: border-box;
+ border-radius: 50%;
+ background-color: #757575;
+ font-size: 40px;
+ color: #fff
+}
+
+.mdl-list__item--two-line {
+ height: 72px
+}
+
+.mdl-list__item--two-line .mdl-list__item-primary-content {
+ height: 36px;
+ line-height: 20px;
+ display: block
+}
+
+.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-avatar {
+ float: left
+}
+
+.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-icon {
+ float: left;
+ margin-top: 6px
+}
+
+.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-secondary-content {
+ height: 36px
+}
+
+.mdl-list__item--two-line .mdl-list__item-primary-content .mdl-list__item-sub-title {
+ font-size: 14px;
+ font-weight: 400;
+ letter-spacing: 0;
+ line-height: 18px;
+ color: rgba(0, 0, 0, .54);
+ display: block;
+ padding: 0
+}
+
+.mdl-list__item--three-line {
+ height: 88px
+}
+
+.mdl-list__item--three-line .mdl-list__item-primary-content {
+ height: 52px;
+ line-height: 20px;
+ display: block
+}
+
+.mdl-list__item--three-line .mdl-list__item-primary-content .mdl-list__item-avatar,
+.mdl-list__item--three-line .mdl-list__item-primary-content .mdl-list__item-icon {
+ float: left
+}
+
+.mdl-list__item--three-line .mdl-list__item-secondary-content {
+ height: 52px
+}
+
+.mdl-list__item--three-line .mdl-list__item-text-body {
+ font-size: 14px;
+ font-weight: 400;
+ letter-spacing: 0;
+ line-height: 18px;
+ height: 52px;
+ color: rgba(0, 0, 0, .54);
+ display: block;
+ padding: 0
+}
+
+.mdl-menu__container {
+ display: block;
+ margin: 0;
+ padding: 0;
+ border: none;
+ position: absolute;
+ overflow: visible;
+ height: 0;
+ width: 0;
+ visibility: hidden;
+ z-index: -1
+}
+
+.mdl-menu__container.is-visible,
+.mdl-menu__container.is-animating {
+ z-index: 999;
+ visibility: visible
+}
+
+.mdl-menu__outline {
+ display: block;
+ background: #fff;
+ margin: 0;
+ padding: 0;
+ border: none;
+ border-radius: 2px;
+ position: absolute;
+ top: 0;
+ left: 0;
+ overflow: hidden;
+ opacity: 0;
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ -webkit-transform-origin: 0 0;
+ transform-origin: 0 0;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
+ will-change: transform;
+ transition: transform .3s cubic-bezier(.4, 0, .2, 1), opacity .2s cubic-bezier(.4, 0, .2, 1);
+ transition: transform .3s cubic-bezier(.4, 0, .2, 1), opacity .2s cubic-bezier(.4, 0, .2, 1), -webkit-transform .3s cubic-bezier(.4, 0, .2, 1);
+ z-index: -1
+}
+
+.mdl-menu__container.is-visible .mdl-menu__outline {
+ opacity: 1;
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ z-index: 999
+}
+
+.mdl-menu__outline.mdl-menu--bottom-right {
+ -webkit-transform-origin: 100% 0;
+ transform-origin: 100% 0
+}
+
+.mdl-menu__outline.mdl-menu--top-left {
+ -webkit-transform-origin: 0 100%;
+ transform-origin: 0 100%
+}
+
+.mdl-menu__outline.mdl-menu--top-right {
+ -webkit-transform-origin: 100% 100%;
+ transform-origin: 100% 100%
+}
+
+.mdl-menu {
+ position: absolute;
+ list-style: none;
+ top: 0;
+ left: 0;
+ height: auto;
+ width: auto;
+ min-width: 124px;
+ padding: 8px 0;
+ margin: 0;
+ opacity: 0;
+ clip: rect(0 0 0 0);
+ z-index: -1
+}
+
+.mdl-menu__container.is-visible .mdl-menu {
+ opacity: 1;
+ z-index: 999
+}
+
+.mdl-menu.is-animating {
+ transition: opacity .2s cubic-bezier(.4, 0, .2, 1), clip .3s cubic-bezier(.4, 0, .2, 1)
+}
+
+.mdl-menu.mdl-menu--bottom-right {
+ left: auto;
+ right: 0
+}
+
+.mdl-menu.mdl-menu--top-left {
+ top: auto;
+ bottom: 0
+}
+
+.mdl-menu.mdl-menu--top-right {
+ top: auto;
+ left: auto;
+ bottom: 0;
+ right: 0
+}
+
+.mdl-menu.mdl-menu--unaligned {
+ top: auto;
+ left: auto
+}
+
+.mdl-menu__item {
+ display: block;
+ border: none;
+ color: rgba(0, 0, 0, .87);
+ background-color: transparent;
+ text-align: left;
+ margin: 0;
+ padding: 0 16px;
+ outline-color: #bdbdbd;
+ position: relative;
+ overflow: hidden;
+ font-size: 14px;
+ font-weight: 400;
+ letter-spacing: 0;
+ text-decoration: none;
+ cursor: pointer;
+ height: 48px;
+ line-height: 48px;
+ white-space: nowrap;
+ opacity: 0;
+ transition: opacity .2s cubic-bezier(.4, 0, .2, 1);
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none
+}
+
+.mdl-menu__container.is-visible .mdl-menu__item {
+ opacity: 1
+}
+
+.mdl-menu__item::-moz-focus-inner {
+ border: 0
+}
+
+.mdl-menu__item--full-bleed-divider {
+ border-bottom: 1px solid rgba(0, 0, 0, .12)
+}
+
+.mdl-menu__item[disabled],
+.mdl-menu__item[data-mdl-disabled] {
+ color: #bdbdbd;
+ background-color: transparent;
+ cursor: auto
+}
+
+.mdl-menu__item[disabled]:hover,
+.mdl-menu__item[data-mdl-disabled]:hover {
+ background-color: transparent
+}
+
+.mdl-menu__item[disabled]:focus,
+.mdl-menu__item[data-mdl-disabled]:focus {
+ background-color: transparent
+}
+
+.mdl-menu__item[disabled] .mdl-ripple,
+.mdl-menu__item[data-mdl-disabled] .mdl-ripple {
+ background: 0 0
+}
+
+.mdl-menu__item:hover {
+ background-color: #eee
+}
+
+.mdl-menu__item:focus {
+ outline: none;
+ background-color: #eee
+}
+
+.mdl-menu__item:active {
+ background-color: #e0e0e0
+}
+
+.mdl-menu__item--ripple-container {
+ display: block;
+ height: 100%;
+ left: 0;
+ position: absolute;
+ top: 0;
+ width: 100%;
+ z-index: 0;
+ overflow: hidden
+}
+
+.mdl-progress {
+ display: block;
+ position: relative;
+ height: 4px;
+ width: 500px;
+ max-width: 100%
+}
+
+.mdl-progress>.bar {
+ display: block;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ width: 0%;
+ transition: width .2s cubic-bezier(.4, 0, .2, 1)
+}
+
+.mdl-progress>.progressbar {
+ background-color: rgb(63, 81, 181);
+ z-index: 1;
+ left: 0
+}
+
+.mdl-progress>.bufferbar {
+ background-image: linear-gradient(to right, rgba(255, 255, 255, .7), rgba(255, 255, 255, .7)), linear-gradient(to right, rgb(63, 81, 181), rgb(63, 81, 181));
+ z-index: 0;
+ left: 0
+}
+
+.mdl-progress>.auxbar {
+ right: 0
+}
+
+@supports (-webkit-appearance:none) {
+ .mdl-progress:not(.mdl-progress--indeterminate):not(.mdl-progress--indeterminate)>.auxbar,
+ .mdl-progress:not(.mdl-progress__indeterminate):not(.mdl-progress__indeterminate)>.auxbar {
+ background-image: linear-gradient(to right, rgba(255, 255, 255, .7), rgba(255, 255, 255, .7)), linear-gradient(to right, rgb(63, 81, 181), rgb(63, 81, 181));
+ -webkit-mask: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgd2lkdGg9IjEyIiBoZWlnaHQ9IjQiIHZpZXdQb3J0PSIwIDAgMTIgNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxlbGxpcHNlIGN4PSIyIiBjeT0iMiIgcng9IjIiIHJ5PSIyIj4KICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9ImN4IiBmcm9tPSIyIiB0bz0iLTEwIiBkdXI9IjAuNnMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPgogIDwvZWxsaXBzZT4KICA8ZWxsaXBzZSBjeD0iMTQiIGN5PSIyIiByeD0iMiIgcnk9IjIiIGNsYXNzPSJsb2FkZXIiPgogICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0iY3giIGZyb209IjE0IiB0bz0iMiIgZHVyPSIwLjZzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4KICA8L2VsbGlwc2U+Cjwvc3ZnPgo=");
+ mask: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgd2lkdGg9IjEyIiBoZWlnaHQ9IjQiIHZpZXdQb3J0PSIwIDAgMTIgNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxlbGxpcHNlIGN4PSIyIiBjeT0iMiIgcng9IjIiIHJ5PSIyIj4KICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9ImN4IiBmcm9tPSIyIiB0bz0iLTEwIiBkdXI9IjAuNnMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPgogIDwvZWxsaXBzZT4KICA8ZWxsaXBzZSBjeD0iMTQiIGN5PSIyIiByeD0iMiIgcnk9IjIiIGNsYXNzPSJsb2FkZXIiPgogICAgPGFuaW1hdGUgYXR0cmlidXRlTmFtZT0iY3giIGZyb209IjE0IiB0bz0iMiIgZHVyPSIwLjZzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4KICA8L2VsbGlwc2U+Cjwvc3ZnPgo=")
+ }
+}
+
+.mdl-progress:not(.mdl-progress--indeterminate)>.auxbar,
+.mdl-progress:not(.mdl-progress__indeterminate)>.auxbar {
+ background-image: linear-gradient(to right, rgba(255, 255, 255, .9), rgba(255, 255, 255, .9)), linear-gradient(to right, rgb(63, 81, 181), rgb(63, 81, 181))
+}
+
+.mdl-progress.mdl-progress--indeterminate>.bar1,
+.mdl-progress.mdl-progress__indeterminate>.bar1 {
+ -webkit-animation-name: indeterminate1;
+ animation-name: indeterminate1
+}
+
+.mdl-progress.mdl-progress--indeterminate>.bar1,
+.mdl-progress.mdl-progress__indeterminate>.bar1,
+.mdl-progress.mdl-progress--indeterminate>.bar3,
+.mdl-progress.mdl-progress__indeterminate>.bar3 {
+ background-color: rgb(63, 81, 181);
+ -webkit-animation-duration: 2s;
+ animation-duration: 2s;
+ -webkit-animation-iteration-count: infinite;
+ animation-iteration-count: infinite;
+ -webkit-animation-timing-function: linear;
+ animation-timing-function: linear
+}
+
+.mdl-progress.mdl-progress--indeterminate>.bar3,
+.mdl-progress.mdl-progress__indeterminate>.bar3 {
+ background-image: none;
+ -webkit-animation-name: indeterminate2;
+ animation-name: indeterminate2
+}
+
+@-webkit-keyframes indeterminate1 {
+ 0% {
+ left: 0%;
+ width: 0%
+ }
+ 50% {
+ left: 25%;
+ width: 75%
+ }
+ 75% {
+ left: 100%;
+ width: 0%
+ }
+}
+
+@keyframes indeterminate1 {
+ 0% {
+ left: 0%;
+ width: 0%
+ }
+ 50% {
+ left: 25%;
+ width: 75%
+ }
+ 75% {
+ left: 100%;
+ width: 0%
+ }
+}
+
+@-webkit-keyframes indeterminate2 {
+ 0%,
+ 50% {
+ left: 0%;
+ width: 0%
+ }
+ 75% {
+ left: 0%;
+ width: 25%
+ }
+ 100% {
+ left: 100%;
+ width: 0%
+ }
+}
+
+@keyframes indeterminate2 {
+ 0%,
+ 50% {
+ left: 0%;
+ width: 0%
+ }
+ 75% {
+ left: 0%;
+ width: 25%
+ }
+ 100% {
+ left: 100%;
+ width: 0%
+ }
+}
+
+.mdl-navigation {
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-wrap: nowrap;
+ -ms-flex-wrap: nowrap;
+ flex-wrap: nowrap;
+ box-sizing: border-box
+}
+
+.mdl-navigation__link {
+ color: #424242;
+ text-decoration: none;
+ margin: 0;
+ font-size: 14px;
+ font-weight: 400;
+ line-height: 24px;
+ letter-spacing: 0;
+ opacity: .87
+}
+
+.mdl-navigation__link .material-icons {
+ vertical-align: middle
+}
+
+.mdl-layout {
+ width: 100%;
+ height: 100%;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: column;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ overflow-y: auto;
+ overflow-x: hidden;
+ position: relative;
+ -webkit-overflow-scrolling: touch
+}
+
+.mdl-layout.is-small-screen .mdl-layout--large-screen-only {
+ display: none
+}
+
+.mdl-layout:not(.is-small-screen) .mdl-layout--small-screen-only {
+ display: none
+}
+
+.mdl-layout__container {
+ position: absolute;
+ width: 100%;
+ height: 100%
+}
+
+.mdl-layout__title,
+.mdl-layout-title {
+ display: block;
+ position: relative;
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ font-size: 20px;
+ line-height: 1;
+ letter-spacing: .02em;
+ font-weight: 400;
+ box-sizing: border-box
+}
+
+.mdl-layout-spacer {
+ -webkit-flex-grow: 1;
+ -ms-flex-positive: 1;
+ flex-grow: 1
+}
+
+.mdl-layout__drawer {
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: column;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-flex-wrap: nowrap;
+ -ms-flex-wrap: nowrap;
+ flex-wrap: nowrap;
+ width: 240px;
+ height: 100%;
+ max-height: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
+ box-sizing: border-box;
+ border-right: 1px solid #e0e0e0;
+ background: #fafafa;
+ -webkit-transform: translateX(-250px);
+ transform: translateX(-250px);
+ -webkit-transform-style: preserve-3d;
+ transform-style: preserve-3d;
+ will-change: transform;
+ transition-duration: .2s;
+ transition-timing-function: cubic-bezier(.4, 0, .2, 1);
+ transition-property: transform;
+ transition-property: transform, -webkit-transform;
+ color: #424242;
+ overflow: visible;
+ overflow-y: auto;
+ z-index: 5
+}
+
+.mdl-layout__drawer.is-visible {
+ -webkit-transform: translateX(0);
+ transform: translateX(0)
+}
+
+.mdl-layout__drawer.is-visible~.mdl-layout__content.mdl-layout__content {
+ overflow: hidden
+}
+
+.mdl-layout__drawer>* {
+ -webkit-flex-shrink: 0;
+ -ms-flex-negative: 0;
+ flex-shrink: 0
+}
+
+.mdl-layout__drawer>.mdl-layout__title,
+.mdl-layout__drawer>.mdl-layout-title {
+ line-height: 64px;
+ padding-left: 40px
+}
+
+@media screen and (max-width:900px) {
+ .mdl-layout__drawer>.mdl-layout__title,
+ .mdl-layout__drawer>.mdl-layout-title {
+ line-height: 56px;
+ padding-left: 16px
+ }
+}
+
+.mdl-layout__drawer .mdl-navigation {
+ -webkit-flex-direction: column;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-align-items: stretch;
+ -ms-flex-align: stretch;
+ align-items: stretch;
+ padding-top: 16px
+}
+
+.mdl-layout__drawer .mdl-navigation .mdl-navigation__link {
+ display: block;
+ -webkit-flex-shrink: 0;
+ -ms-flex-negative: 0;
+ flex-shrink: 0;
+ padding: 16px 40px;
+ margin: 0;
+ color: #757575
+}
+
+@media screen and (max-width:900px) {
+ .mdl-layout__drawer .mdl-navigation .mdl-navigation__link {
+ padding: 16px
+ }
+}
+
+.mdl-layout__drawer .mdl-navigation .mdl-navigation__link:hover {
+ background-color: #e0e0e0
+}
+
+.mdl-layout__drawer .mdl-navigation .mdl-navigation__link--current {
+ background-color: #e0e0e0;
+ color: #000
+}
+
+@media screen and (min-width:901px) {
+ .mdl-layout--fixed-drawer>.mdl-layout__drawer {
+ -webkit-transform: translateX(0);
+ transform: translateX(0)
+ }
+}
+
+.mdl-layout__drawer-button {
+ display: block;
+ position: absolute;
+ height: 48px;
+ width: 48px;
+ border: 0;
+ -webkit-flex-shrink: 0;
+ -ms-flex-negative: 0;
+ flex-shrink: 0;
+ overflow: hidden;
+ text-align: center;
+ cursor: pointer;
+ font-size: 26px;
+ line-height: 56px;
+ font-family: Helvetica, Arial, sans-serif;
+ margin: 8px 12px;
+ top: 0;
+ left: 0;
+ color: rgb(255, 255, 255);
+ z-index: 4
+}
+
+.mdl-layout__header .mdl-layout__drawer-button {
+ position: absolute;
+ color: rgb(255, 255, 255);
+ background-color: inherit
+}
+
+@media screen and (max-width:900px) {
+ .mdl-layout__header .mdl-layout__drawer-button {
+ margin: 4px
+ }
+}
+
+@media screen and (max-width:900px) {
+ .mdl-layout__drawer-button {
+ margin: 4px;
+ color: rgba(0, 0, 0, .5)
+ }
+}
+
+@media screen and (min-width:901px) {
+ .mdl-layout__drawer-button {
+ line-height: 54px
+ }
+ .mdl-layout--no-desktop-drawer-button .mdl-layout__drawer-button,
+ .mdl-layout--fixed-drawer>.mdl-layout__drawer-button,
+ .mdl-layout--no-drawer-button .mdl-layout__drawer-button {
+ display: none
+ }
+}
+
+.mdl-layout__header {
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: column;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-flex-wrap: nowrap;
+ -ms-flex-wrap: nowrap;
+ flex-wrap: nowrap;
+ -webkit-justify-content: flex-start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ box-sizing: border-box;
+ -webkit-flex-shrink: 0;
+ -ms-flex-negative: 0;
+ flex-shrink: 0;
+ width: 100%;
+ margin: 0;
+ padding: 0;
+ border: none;
+ min-height: 56px;
+ max-height: 1000px;
+ z-index: 3;
+ background-color: rgb(63, 81, 181);
+ color: rgb(255, 255, 255);
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
+ transition-duration: .2s;
+ transition-timing-function: cubic-bezier(.4, 0, .2, 1);
+ transition-property: max-height, box-shadow
+}
+
+@media screen and (max-width:900px) {
+ .mdl-layout__header {
+ min-height: 56px
+ }
+}
+
+.mdl-layout--fixed-drawer.is-upgraded:not(.is-small-screen)>.mdl-layout__header {
+ margin-left: 240px;
+ width: calc(100% - 240px)
+}
+
+@media screen and (min-width:901px) {
+ .mdl-layout--fixed-drawer>.mdl-layout__header .mdl-layout__header-row {
+ padding-left: 40px
+ }
+}
+
+.mdl-layout__header>.mdl-layout-icon {
+ position: absolute;
+ left: 40px;
+ top: 16px;
+ height: 32px;
+ width: 32px;
+ overflow: hidden;
+ z-index: 3;
+ display: block
+}
+
+@media screen and (max-width:900px) {
+ .mdl-layout__header>.mdl-layout-icon {
+ left: 16px;
+ top: 12px
+ }
+}
+
+.mdl-layout.has-drawer .mdl-layout__header>.mdl-layout-icon {
+ display: none
+}
+
+.mdl-layout__header.is-compact {
+ max-height: 64px
+}
+
+@media screen and (max-width:900px) {
+ .mdl-layout__header.is-compact {
+ max-height: 56px
+ }
+}
+
+.mdl-layout__header.is-compact.has-tabs {
+ height: 112px
+}
+
+@media screen and (max-width:900px) {
+ .mdl-layout__header.is-compact.has-tabs {
+ min-height: 104px
+ }
+}
+
+@media screen and (max-width:900px) {
+ .mdl-layout__header {
+ display: none
+ }
+ .mdl-layout--fixed-header>.mdl-layout__header {
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex
+ }
+}
+
+.mdl-layout__header--transparent.mdl-layout__header--transparent {
+ background-color: transparent;
+ box-shadow: none
+}
+
+.mdl-layout__header--seamed,
+.mdl-layout__header--scroll {
+ box-shadow: none
+}
+
+.mdl-layout__header--waterfall {
+ box-shadow: none;
+ overflow: hidden
+}
+
+.mdl-layout__header--waterfall.is-casting-shadow {
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12)
+}
+
+.mdl-layout__header--waterfall.mdl-layout__header--waterfall-hide-top {
+ -webkit-justify-content: flex-end;
+ -ms-flex-pack: end;
+ justify-content: flex-end
+}
+
+.mdl-layout__header-row {
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: row;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-flex-wrap: nowrap;
+ -ms-flex-wrap: nowrap;
+ flex-wrap: nowrap;
+ -webkit-flex-shrink: 0;
+ -ms-flex-negative: 0;
+ flex-shrink: 0;
+ box-sizing: border-box;
+ -webkit-align-self: stretch;
+ -ms-flex-item-align: stretch;
+ align-self: stretch;
+ -webkit-align-items: center;
+ -ms-flex-align: center;
+ align-items: center;
+ height: 56px;
+ margin: 0;
+ padding: 0 40px 0 80px
+}
+
+.mdl-layout--no-drawer-button .mdl-layout__header-row {
+ padding-left: 40px
+}
+
+@media screen and (min-width:901px) {
+ .mdl-layout--no-desktop-drawer-button .mdl-layout__header-row {
+ padding-left: 40px
+ }
+}
+
+@media screen and (max-width:900px) {
+ .mdl-layout__header-row {
+ height: 56px;
+ padding: 0 16px 0 72px
+ }
+ .mdl-layout--no-drawer-button .mdl-layout__header-row {
+ padding-left: 16px
+ }
+}
+
+.mdl-layout__header-row>* {
+ -webkit-flex-shrink: 0;
+ -ms-flex-negative: 0;
+ flex-shrink: 0
+}
+
+.mdl-layout__header--scroll .mdl-layout__header-row {
+ width: 100%
+}
+
+.mdl-layout__header-row .mdl-navigation {
+ margin: 0;
+ padding: 0;
+ height: 64px;
+ -webkit-flex-direction: row;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-align-items: center;
+ -ms-flex-align: center;
+ align-items: center
+}
+
+@media screen and (max-width:900px) {
+ .mdl-layout__header-row .mdl-navigation {
+ height: 56px
+ }
+}
+
+.mdl-layout__header-row .mdl-navigation__link {
+ display: block;
+ color: rgb(255, 255, 255);
+ line-height: 64px;
+ padding: 0 24px
+}
+
+@media screen and (max-width:900px) {
+ .mdl-layout__header-row .mdl-navigation__link {
+ line-height: 56px;
+ padding: 0 16px
+ }
+}
+
+.mdl-layout__obfuscator {
+ background-color: transparent;
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 100%;
+ width: 100%;
+ z-index: 4;
+ visibility: hidden;
+ transition-property: background-color;
+ transition-duration: .2s;
+ transition-timing-function: cubic-bezier(.4, 0, .2, 1)
+}
+
+.mdl-layout__obfuscator.is-visible {
+ background-color: rgba(0, 0, 0, .5);
+ visibility: visible
+}
+
+@supports (pointer-events:auto) {
+ .mdl-layout__obfuscator {
+ background-color: rgba(0, 0, 0, .5);
+ opacity: 0;
+ transition-property: opacity;
+ visibility: visible;
+ pointer-events: none
+ }
+ .mdl-layout__obfuscator.is-visible {
+ pointer-events: auto;
+ opacity: 1
+ }
+}
+
+.mdl-layout__content {
+ -ms-flex: 0 1 auto;
+ position: relative;
+ display: inline-block;
+ overflow-y: auto;
+ overflow-x: hidden;
+ -webkit-flex-grow: 1;
+ -ms-flex-positive: 1;
+ flex-grow: 1;
+ z-index: 1;
+ -webkit-overflow-scrolling: touch
+}
+
+.mdl-layout--fixed-drawer>.mdl-layout__content {
+ margin-left: 240px
+}
+
+.mdl-layout__container.has-scrolling-header .mdl-layout__content {
+ overflow: visible
+}
+
+@media screen and (max-width:900px) {
+ .mdl-layout--fixed-drawer>.mdl-layout__content {
+ margin-left: 0
+ }
+ .mdl-layout__container.has-scrolling-header .mdl-layout__content {
+ overflow-y: auto;
+ overflow-x: hidden
+ }
+}
+
+.mdl-layout__tab-bar {
+ height: 96px;
+ margin: 0;
+ width: calc(100% - 112px);
+ padding: 0 0 0 56px;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ background-color: rgb(63, 81, 181);
+ overflow-y: hidden;
+ overflow-x: scroll
+}
+
+.mdl-layout__tab-bar::-webkit-scrollbar {
+ display: none
+}
+
+.mdl-layout--no-drawer-button .mdl-layout__tab-bar {
+ padding-left: 16px;
+ width: calc(100% - 32px)
+}
+
+@media screen and (min-width:901px) {
+ .mdl-layout--no-desktop-drawer-button .mdl-layout__tab-bar {
+ padding-left: 16px;
+ width: calc(100% - 32px)
+ }
+}
+
+@media screen and (max-width:900px) {
+ .mdl-layout__tab-bar {
+ width: calc(100% - 60px);
+ padding: 0 0 0 60px
+ }
+ .mdl-layout--no-drawer-button .mdl-layout__tab-bar {
+ width: calc(100% - 8px);
+ padding-left: 4px
+ }
+}
+
+.mdl-layout--fixed-tabs .mdl-layout__tab-bar {
+ padding: 0;
+ overflow: hidden;
+ width: 100%
+}
+
+.mdl-layout__tab-bar-container {
+ position: relative;
+ height: 48px;
+ width: 100%;
+ border: none;
+ margin: 0;
+ z-index: 2;
+ -webkit-flex-grow: 0;
+ -ms-flex-positive: 0;
+ flex-grow: 0;
+ -webkit-flex-shrink: 0;
+ -ms-flex-negative: 0;
+ flex-shrink: 0;
+ overflow: hidden
+}
+
+.mdl-layout__container>.mdl-layout__tab-bar-container {
+ position: absolute;
+ top: 0;
+ left: 0
+}
+
+.mdl-layout__tab-bar-button {
+ display: inline-block;
+ position: absolute;
+ top: 0;
+ height: 48px;
+ width: 56px;
+ z-index: 4;
+ text-align: center;
+ background-color: rgb(63, 81, 181);
+ color: transparent;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none
+}
+
+.mdl-layout--no-desktop-drawer-button .mdl-layout__tab-bar-button,
+.mdl-layout--no-drawer-button .mdl-layout__tab-bar-button {
+ width: 16px
+}
+
+.mdl-layout--no-desktop-drawer-button .mdl-layout__tab-bar-button .material-icons,
+.mdl-layout--no-drawer-button .mdl-layout__tab-bar-button .material-icons {
+ position: relative;
+ left: -4px
+}
+
+@media screen and (max-width:900px) {
+ .mdl-layout__tab-bar-button {
+ width: 60px
+ }
+}
+
+.mdl-layout--fixed-tabs .mdl-layout__tab-bar-button {
+ display: none
+}
+
+.mdl-layout__tab-bar-button .material-icons {
+ line-height: 48px
+}
+
+.mdl-layout__tab-bar-button.is-active {
+ color: rgb(255, 255, 255)
+}
+
+.mdl-layout__tab-bar-left-button {
+ left: 0
+}
+
+.mdl-layout__tab-bar-right-button {
+ right: 0
+}
+
+.mdl-layout__tab {
+ margin: 0;
+ border: none;
+ padding: 0 24px;
+ float: left;
+ position: relative;
+ display: block;
+ -webkit-flex-grow: 0;
+ -ms-flex-positive: 0;
+ flex-grow: 0;
+ -webkit-flex-shrink: 0;
+ -ms-flex-negative: 0;
+ flex-shrink: 0;
+ text-decoration: none;
+ height: 48px;
+ line-height: 48px;
+ text-align: center;
+ font-weight: 500;
+ font-size: 14px;
+ text-transform: uppercase;
+ color: rgba(255, 255, 255, .6);
+ overflow: hidden
+}
+
+@media screen and (max-width:900px) {
+ .mdl-layout__tab {
+ padding: 0 12px
+ }
+}
+
+.mdl-layout--fixed-tabs .mdl-layout__tab {
+ float: none;
+ -webkit-flex-grow: 1;
+ -ms-flex-positive: 1;
+ flex-grow: 1;
+ padding: 0
+}
+
+.mdl-layout.is-upgraded .mdl-layout__tab.is-active {
+ color: rgb(255, 255, 255)
+}
+
+.mdl-layout.is-upgraded .mdl-layout__tab.is-active::after {
+ height: 2px;
+ width: 100%;
+ display: block;
+ content: " ";
+ bottom: 0;
+ left: 0;
+ position: absolute;
+ background: rgb(255, 64, 129);
+ -webkit-animation: border-expand .2s cubic-bezier(.4, 0, .4, 1).01s alternate forwards;
+ animation: border-expand .2s cubic-bezier(.4, 0, .4, 1).01s alternate forwards;
+ transition: all 1s cubic-bezier(.4, 0, 1, 1)
+}
+
+.mdl-layout__tab .mdl-layout__tab-ripple-container {
+ display: block;
+ position: absolute;
+ height: 100%;
+ width: 100%;
+ left: 0;
+ top: 0;
+ z-index: 1;
+ overflow: hidden
+}
+
+.mdl-layout__tab .mdl-layout__tab-ripple-container .mdl-ripple {
+ background-color: rgb(255, 255, 255)
+}
+
+.mdl-layout__tab-panel {
+ display: block
+}
+
+.mdl-layout.is-upgraded .mdl-layout__tab-panel {
+ display: none
+}
+
+.mdl-layout.is-upgraded .mdl-layout__tab-panel.is-active {
+ display: block
+}
+
+.mdl-radio {
+ position: relative;
+ font-size: 16px;
+ line-height: 24px;
+ display: inline-block;
+ vertical-align: middle;
+ box-sizing: border-box;
+ height: 24px;
+ margin: 0;
+ padding-left: 0
+}
+
+.mdl-radio.is-upgraded {
+ padding-left: 24px
+}
+
+.mdl-radio__button {
+ line-height: 24px
+}
+
+.mdl-radio.is-upgraded .mdl-radio__button {
+ position: absolute;
+ width: 0;
+ height: 0;
+ margin: 0;
+ padding: 0;
+ opacity: 0;
+ -ms-appearance: none;
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ appearance: none;
+ border: none
+}
+
+.mdl-radio__outer-circle {
+ position: absolute;
+ top: 4px;
+ left: 0;
+ display: inline-block;
+ box-sizing: border-box;
+ width: 16px;
+ height: 16px;
+ margin: 0;
+ cursor: pointer;
+ border: 2px solid rgba(0, 0, 0, .54);
+ border-radius: 50%;
+ z-index: 2
+}
+
+.mdl-radio.is-checked .mdl-radio__outer-circle {
+ border: 2px solid rgb(63, 81, 181)
+}
+
+.mdl-radio__outer-circle fieldset[disabled] .mdl-radio,
+.mdl-radio.is-disabled .mdl-radio__outer-circle {
+ border: 2px solid rgba(0, 0, 0, .26);
+ cursor: auto
+}
+
+.mdl-radio__inner-circle {
+ position: absolute;
+ z-index: 1;
+ margin: 0;
+ top: 8px;
+ left: 4px;
+ box-sizing: border-box;
+ width: 8px;
+ height: 8px;
+ cursor: pointer;
+ transition-duration: .28s;
+ transition-timing-function: cubic-bezier(.4, 0, .2, 1);
+ transition-property: transform;
+ transition-property: transform, -webkit-transform;
+ -webkit-transform: scale(0, 0);
+ transform: scale(0, 0);
+ border-radius: 50%;
+ background: rgb(63, 81, 181)
+}
+
+.mdl-radio.is-checked .mdl-radio__inner-circle {
+ -webkit-transform: scale(1, 1);
+ transform: scale(1, 1)
+}
+
+fieldset[disabled] .mdl-radio .mdl-radio__inner-circle,
+.mdl-radio.is-disabled .mdl-radio__inner-circle {
+ background: rgba(0, 0, 0, .26);
+ cursor: auto
+}
+
+.mdl-radio.is-focused .mdl-radio__inner-circle {
+ box-shadow: 0 0 0 10px rgba(0, 0, 0, .1)
+}
+
+.mdl-radio__label {
+ cursor: pointer
+}
+
+fieldset[disabled] .mdl-radio .mdl-radio__label,
+.mdl-radio.is-disabled .mdl-radio__label {
+ color: rgba(0, 0, 0, .26);
+ cursor: auto
+}
+
+.mdl-radio__ripple-container {
+ position: absolute;
+ z-index: 2;
+ top: -9px;
+ left: -13px;
+ box-sizing: border-box;
+ width: 42px;
+ height: 42px;
+ border-radius: 50%;
+ cursor: pointer;
+ overflow: hidden;
+ -webkit-mask-image: -webkit-radial-gradient(circle, #fff, #000)
+}
+
+.mdl-radio__ripple-container .mdl-ripple {
+ background: rgb(63, 81, 181)
+}
+
+fieldset[disabled] .mdl-radio .mdl-radio__ripple-container,
+.mdl-radio.is-disabled .mdl-radio__ripple-container {
+ cursor: auto
+}
+
+fieldset[disabled] .mdl-radio .mdl-radio__ripple-container .mdl-ripple,
+.mdl-radio.is-disabled .mdl-radio__ripple-container .mdl-ripple {
+ background: 0 0
+}
+
+_:-ms-input-placeholder,
+:root .mdl-slider.mdl-slider.is-upgraded {
+ -ms-appearance: none;
+ height: 32px;
+ margin: 0
+}
+
+.mdl-slider {
+ width: calc(100% - 40px);
+ margin: 0 20px
+}
+
+.mdl-slider.is-upgraded {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ height: 2px;
+ background: 0 0;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ outline: 0;
+ padding: 0;
+ color: rgb(63, 81, 181);
+ -webkit-align-self: center;
+ -ms-flex-item-align: center;
+ -ms-grid-row-align: center;
+ align-self: center;
+ z-index: 1;
+ cursor: pointer
+}
+
+.mdl-slider.is-upgraded::-moz-focus-outer {
+ border: 0
+}
+
+.mdl-slider.is-upgraded::-ms-tooltip {
+ display: none
+}
+
+.mdl-slider.is-upgraded::-webkit-slider-runnable-track {
+ background: 0 0
+}
+
+.mdl-slider.is-upgraded::-moz-range-track {
+ background: 0 0;
+ border: none
+}
+
+.mdl-slider.is-upgraded::-ms-track {
+ background: 0 0;
+ color: transparent;
+ height: 2px;
+ width: 100%;
+ border: none
+}
+
+.mdl-slider.is-upgraded::-ms-fill-lower {
+ padding: 0;
+ background: linear-gradient(to right, transparent, transparent 16px, rgb(63, 81, 181)16px, rgb(63, 81, 181)0)
+}
+
+.mdl-slider.is-upgraded::-ms-fill-upper {
+ padding: 0;
+ background: linear-gradient(to left, transparent, transparent 16px, rgba(0, 0, 0, .26)16px, rgba(0, 0, 0, .26)0)
+}
+
+.mdl-slider.is-upgraded::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ width: 12px;
+ height: 12px;
+ box-sizing: border-box;
+ border-radius: 50%;
+ background: rgb(63, 81, 181);
+ border: none;
+ transition: transform .18s cubic-bezier(.4, 0, .2, 1), border .18s cubic-bezier(.4, 0, .2, 1), box-shadow .18s cubic-bezier(.4, 0, .2, 1), background .28s cubic-bezier(.4, 0, .2, 1);
+ transition: transform .18s cubic-bezier(.4, 0, .2, 1), border .18s cubic-bezier(.4, 0, .2, 1), box-shadow .18s cubic-bezier(.4, 0, .2, 1), background .28s cubic-bezier(.4, 0, .2, 1), -webkit-transform .18s cubic-bezier(.4, 0, .2, 1)
+}
+
+.mdl-slider.is-upgraded::-moz-range-thumb {
+ -moz-appearance: none;
+ width: 12px;
+ height: 12px;
+ box-sizing: border-box;
+ border-radius: 50%;
+ background-image: none;
+ background: rgb(63, 81, 181);
+ border: none
+}
+
+.mdl-slider.is-upgraded:focus:not(:active)::-webkit-slider-thumb {
+ box-shadow: 0 0 0 10px rgba(63, 81, 181, .26)
+}
+
+.mdl-slider.is-upgraded:focus:not(:active)::-moz-range-thumb {
+ box-shadow: 0 0 0 10px rgba(63, 81, 181, .26)
+}
+
+.mdl-slider.is-upgraded:active::-webkit-slider-thumb {
+ background-image: none;
+ background: rgb(63, 81, 181);
+ -webkit-transform: scale(1.5);
+ transform: scale(1.5)
+}
+
+.mdl-slider.is-upgraded:active::-moz-range-thumb {
+ background-image: none;
+ background: rgb(63, 81, 181);
+ transform: scale(1.5)
+}
+
+.mdl-slider.is-upgraded::-ms-thumb {
+ width: 32px;
+ height: 32px;
+ border: none;
+ border-radius: 50%;
+ background: rgb(63, 81, 181);
+ transform: scale(.375);
+ transition: transform .18s cubic-bezier(.4, 0, .2, 1), background .28s cubic-bezier(.4, 0, .2, 1);
+ transition: transform .18s cubic-bezier(.4, 0, .2, 1), background .28s cubic-bezier(.4, 0, .2, 1), -webkit-transform .18s cubic-bezier(.4, 0, .2, 1)
+}
+
+.mdl-slider.is-upgraded:focus:not(:active)::-ms-thumb {
+ background: radial-gradient(circle closest-side, rgb(63, 81, 181)0%, rgb(63, 81, 181)37.5%, rgba(63, 81, 181, .26)37.5%, rgba(63, 81, 181, .26)100%);
+ transform: scale(1)
+}
+
+.mdl-slider.is-upgraded:active::-ms-thumb {
+ background: rgb(63, 81, 181);
+ transform: scale(.5625)
+}
+
+.mdl-slider.is-upgraded.is-lowest-value::-webkit-slider-thumb {
+ border: 2px solid rgba(0, 0, 0, .26);
+ background: 0 0
+}
+
+.mdl-slider.is-upgraded.is-lowest-value::-moz-range-thumb {
+ border: 2px solid rgba(0, 0, 0, .26);
+ background: 0 0
+}
+
+.mdl-slider.is-upgraded.is-lowest-value+.mdl-slider__background-flex>.mdl-slider__background-upper {
+ left: 6px
+}
+
+.mdl-slider.is-upgraded.is-lowest-value:focus:not(:active)::-webkit-slider-thumb {
+ box-shadow: 0 0 0 10px rgba(0, 0, 0, .12);
+ background: rgba(0, 0, 0, .12)
+}
+
+.mdl-slider.is-upgraded.is-lowest-value:focus:not(:active)::-moz-range-thumb {
+ box-shadow: 0 0 0 10px rgba(0, 0, 0, .12);
+ background: rgba(0, 0, 0, .12)
+}
+
+.mdl-slider.is-upgraded.is-lowest-value:active::-webkit-slider-thumb {
+ border: 1.6px solid rgba(0, 0, 0, .26);
+ -webkit-transform: scale(1.5);
+ transform: scale(1.5)
+}
+
+.mdl-slider.is-upgraded.is-lowest-value:active+.mdl-slider__background-flex>.mdl-slider__background-upper {
+ left: 9px
+}
+
+.mdl-slider.is-upgraded.is-lowest-value:active::-moz-range-thumb {
+ border: 1.5px solid rgba(0, 0, 0, .26);
+ transform: scale(1.5)
+}
+
+.mdl-slider.is-upgraded.is-lowest-value::-ms-thumb {
+ background: radial-gradient(circle closest-side, transparent 0%, transparent 66.67%, rgba(0, 0, 0, .26)66.67%, rgba(0, 0, 0, .26)100%)
+}
+
+.mdl-slider.is-upgraded.is-lowest-value:focus:not(:active)::-ms-thumb {
+ background: radial-gradient(circle closest-side, rgba(0, 0, 0, .12)0%, rgba(0, 0, 0, .12)25%, rgba(0, 0, 0, .26)25%, rgba(0, 0, 0, .26)37.5%, rgba(0, 0, 0, .12)37.5%, rgba(0, 0, 0, .12)100%);
+ transform: scale(1)
+}
+
+.mdl-slider.is-upgraded.is-lowest-value:active::-ms-thumb {
+ transform: scale(.5625);
+ background: radial-gradient(circle closest-side, transparent 0%, transparent 77.78%, rgba(0, 0, 0, .26)77.78%, rgba(0, 0, 0, .26)100%)
+}
+
+.mdl-slider.is-upgraded.is-lowest-value::-ms-fill-lower {
+ background: 0 0
+}
+
+.mdl-slider.is-upgraded.is-lowest-value::-ms-fill-upper {
+ margin-left: 6px
+}
+
+.mdl-slider.is-upgraded.is-lowest-value:active::-ms-fill-upper {
+ margin-left: 9px
+}
+
+.mdl-slider.is-upgraded:disabled:focus::-webkit-slider-thumb,
+.mdl-slider.is-upgraded:disabled:active::-webkit-slider-thumb,
+.mdl-slider.is-upgraded:disabled::-webkit-slider-thumb {
+ -webkit-transform: scale(.667);
+ transform: scale(.667);
+ background: rgba(0, 0, 0, .26)
+}
+
+.mdl-slider.is-upgraded:disabled:focus::-moz-range-thumb,
+.mdl-slider.is-upgraded:disabled:active::-moz-range-thumb,
+.mdl-slider.is-upgraded:disabled::-moz-range-thumb {
+ transform: scale(.667);
+ background: rgba(0, 0, 0, .26)
+}
+
+.mdl-slider.is-upgraded:disabled+.mdl-slider__background-flex>.mdl-slider__background-lower {
+ background-color: rgba(0, 0, 0, .26);
+ left: -6px
+}
+
+.mdl-slider.is-upgraded:disabled+.mdl-slider__background-flex>.mdl-slider__background-upper {
+ left: 6px
+}
+
+.mdl-slider.is-upgraded.is-lowest-value:disabled:focus::-webkit-slider-thumb,
+.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-webkit-slider-thumb,
+.mdl-slider.is-upgraded.is-lowest-value:disabled::-webkit-slider-thumb {
+ border: 3px solid rgba(0, 0, 0, .26);
+ background: 0 0;
+ -webkit-transform: scale(.667);
+ transform: scale(.667)
+}
+
+.mdl-slider.is-upgraded.is-lowest-value:disabled:focus::-moz-range-thumb,
+.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-moz-range-thumb,
+.mdl-slider.is-upgraded.is-lowest-value:disabled::-moz-range-thumb {
+ border: 3px solid rgba(0, 0, 0, .26);
+ background: 0 0;
+ transform: scale(.667)
+}
+
+.mdl-slider.is-upgraded.is-lowest-value:disabled:active+.mdl-slider__background-flex>.mdl-slider__background-upper {
+ left: 6px
+}
+
+.mdl-slider.is-upgraded:disabled:focus::-ms-thumb,
+.mdl-slider.is-upgraded:disabled:active::-ms-thumb,
+.mdl-slider.is-upgraded:disabled::-ms-thumb {
+ transform: scale(.25);
+ background: rgba(0, 0, 0, .26)
+}
+
+.mdl-slider.is-upgraded.is-lowest-value:disabled:focus::-ms-thumb,
+.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-ms-thumb,
+.mdl-slider.is-upgraded.is-lowest-value:disabled::-ms-thumb {
+ transform: scale(.25);
+ background: radial-gradient(circle closest-side, transparent 0%, transparent 50%, rgba(0, 0, 0, .26)50%, rgba(0, 0, 0, .26)100%)
+}
+
+.mdl-slider.is-upgraded:disabled::-ms-fill-lower {
+ margin-right: 6px;
+ background: linear-gradient(to right, transparent, transparent 25px, rgba(0, 0, 0, .26)25px, rgba(0, 0, 0, .26)0)
+}
+
+.mdl-slider.is-upgraded:disabled::-ms-fill-upper {
+ margin-left: 6px
+}
+
+.mdl-slider.is-upgraded.is-lowest-value:disabled:active::-ms-fill-upper {
+ margin-left: 6px
+}
+
+.mdl-slider__ie-container {
+ height: 18px;
+ overflow: visible;
+ border: none;
+ margin: none;
+ padding: none
+}
+
+.mdl-slider__container {
+ height: 18px;
+ position: relative;
+ -webkit-flex-direction: row;
+ -ms-flex-direction: row;
+ flex-direction: row
+}
+
+.mdl-slider__container,
+.mdl-slider__background-flex {
+ background: 0 0;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex
+}
+
+.mdl-slider__background-flex {
+ position: absolute;
+ height: 2px;
+ width: calc(100% - 52px);
+ top: 50%;
+ left: 0;
+ margin: 0 26px;
+ overflow: hidden;
+ border: 0;
+ padding: 0;
+ -webkit-transform: translate(0, -1px);
+ transform: translate(0, -1px)
+}
+
+.mdl-slider__background-lower {
+ background: rgb(63, 81, 181)
+}
+
+.mdl-slider__background-lower,
+.mdl-slider__background-upper {
+ -webkit-flex: 0;
+ -ms-flex: 0;
+ flex: 0;
+ position: relative;
+ border: 0;
+ padding: 0
+}
+
+.mdl-slider__background-upper {
+ background: rgba(0, 0, 0, .26);
+ transition: left .18s cubic-bezier(.4, 0, .2, 1)
+}
+
+.mdl-snackbar {
+ position: fixed;
+ bottom: 0;
+ left: 50%;
+ cursor: default;
+ background-color: #323232;
+ z-index: 3;
+ display: block;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-justify-content: space-between;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ will-change: transform;
+ -webkit-transform: translate(0, 80px);
+ transform: translate(0, 80px);
+ transition: transform .25s cubic-bezier(.4, 0, 1, 1);
+ transition: transform .25s cubic-bezier(.4, 0, 1, 1), -webkit-transform .25s cubic-bezier(.4, 0, 1, 1);
+ pointer-events: none
+}
+
+@media (max-width:479px) {
+ .mdl-snackbar {
+ width: 100%;
+ left: 0;
+ min-height: 48px;
+ max-height: 80px
+ }
+}
+
+@media (min-width:480px) {
+ .mdl-snackbar {
+ min-width: 288px;
+ max-width: 568px;
+ border-radius: 2px;
+ -webkit-transform: translate(-50%, 80px);
+ transform: translate(-50%, 80px)
+ }
+}
+
+.mdl-snackbar--active {
+ -webkit-transform: translate(0, 0);
+ transform: translate(0, 0);
+ pointer-events: auto;
+ transition: transform .25s cubic-bezier(0, 0, .2, 1);
+ transition: transform .25s cubic-bezier(0, 0, .2, 1), -webkit-transform .25s cubic-bezier(0, 0, .2, 1)
+}
+
+@media (min-width:480px) {
+ .mdl-snackbar--active {
+ -webkit-transform: translate(-50%, 0);
+ transform: translate(-50%, 0)
+ }
+}
+
+.mdl-snackbar__text {
+ padding: 14px 12px 14px 24px;
+ vertical-align: middle;
+ color: #fff;
+ float: left
+}
+
+.mdl-snackbar__action {
+ background: 0 0;
+ border: none;
+ color: rgb(255, 64, 129);
+ float: right;
+ padding: 14px 24px 14px 12px;
+ font-family: "Roboto", "Helvetica", "Arial", sans-serif;
+ font-size: 14px;
+ font-weight: 500;
+ text-transform: uppercase;
+ line-height: 1;
+ letter-spacing: 0;
+ overflow: hidden;
+ outline: none;
+ opacity: 0;
+ pointer-events: none;
+ cursor: pointer;
+ text-decoration: none;
+ text-align: center;
+ -webkit-align-self: center;
+ -ms-flex-item-align: center;
+ -ms-grid-row-align: center;
+ align-self: center
+}
+
+.mdl-snackbar__action::-moz-focus-inner {
+ border: 0
+}
+
+.mdl-snackbar__action:not([aria-hidden]) {
+ opacity: 1;
+ pointer-events: auto
+}
+
+.mdl-spinner {
+ display: inline-block;
+ position: relative;
+ width: 28px;
+ height: 28px
+}
+
+.mdl-spinner:not(.is-upgraded).is-active:after {
+ content: "Loading..."
+}
+
+.mdl-spinner.is-upgraded.is-active {
+ -webkit-animation: mdl-spinner__container-rotate 1568.23529412ms linear infinite;
+ animation: mdl-spinner__container-rotate 1568.23529412ms linear infinite
+}
+
+@-webkit-keyframes mdl-spinner__container-rotate {
+ to {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg)
+ }
+}
+
+@keyframes mdl-spinner__container-rotate {
+ to {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg)
+ }
+}
+
+.mdl-spinner__layer {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ opacity: 0
+}
+
+.mdl-spinner__layer-1 {
+ border-color: #42a5f5
+}
+
+.mdl-spinner--single-color .mdl-spinner__layer-1 {
+ border-color: rgb(63, 81, 181)
+}
+
+.mdl-spinner.is-active .mdl-spinner__layer-1 {
+ -webkit-animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4, 0, .2, 1)infinite both, mdl-spinner__layer-1-fade-in-out 5332ms cubic-bezier(.4, 0, .2, 1)infinite both;
+ animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4, 0, .2, 1)infinite both, mdl-spinner__layer-1-fade-in-out 5332ms cubic-bezier(.4, 0, .2, 1)infinite both
+}
+
+.mdl-spinner__layer-2 {
+ border-color: #f44336
+}
+
+.mdl-spinner--single-color .mdl-spinner__layer-2 {
+ border-color: rgb(63, 81, 181)
+}
+
+.mdl-spinner.is-active .mdl-spinner__layer-2 {
+ -webkit-animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4, 0, .2, 1)infinite both, mdl-spinner__layer-2-fade-in-out 5332ms cubic-bezier(.4, 0, .2, 1)infinite both;
+ animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4, 0, .2, 1)infinite both, mdl-spinner__layer-2-fade-in-out 5332ms cubic-bezier(.4, 0, .2, 1)infinite both
+}
+
+.mdl-spinner__layer-3 {
+ border-color: #fdd835
+}
+
+.mdl-spinner--single-color .mdl-spinner__layer-3 {
+ border-color: rgb(63, 81, 181)
+}
+
+.mdl-spinner.is-active .mdl-spinner__layer-3 {
+ -webkit-animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4, 0, .2, 1)infinite both, mdl-spinner__layer-3-fade-in-out 5332ms cubic-bezier(.4, 0, .2, 1)infinite both;
+ animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4, 0, .2, 1)infinite both, mdl-spinner__layer-3-fade-in-out 5332ms cubic-bezier(.4, 0, .2, 1)infinite both
+}
+
+.mdl-spinner__layer-4 {
+ border-color: #4caf50
+}
+
+.mdl-spinner--single-color .mdl-spinner__layer-4 {
+ border-color: rgb(63, 81, 181)
+}
+
+.mdl-spinner.is-active .mdl-spinner__layer-4 {
+ -webkit-animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4, 0, .2, 1)infinite both, mdl-spinner__layer-4-fade-in-out 5332ms cubic-bezier(.4, 0, .2, 1)infinite both;
+ animation: mdl-spinner__fill-unfill-rotate 5332ms cubic-bezier(.4, 0, .2, 1)infinite both, mdl-spinner__layer-4-fade-in-out 5332ms cubic-bezier(.4, 0, .2, 1)infinite both
+}
+
+@-webkit-keyframes mdl-spinner__fill-unfill-rotate {
+ 12.5% {
+ -webkit-transform: rotate(135deg);
+ transform: rotate(135deg)
+ }
+ 25% {
+ -webkit-transform: rotate(270deg);
+ transform: rotate(270deg)
+ }
+ 37.5% {
+ -webkit-transform: rotate(405deg);
+ transform: rotate(405deg)
+ }
+ 50% {
+ -webkit-transform: rotate(540deg);
+ transform: rotate(540deg)
+ }
+ 62.5% {
+ -webkit-transform: rotate(675deg);
+ transform: rotate(675deg)
+ }
+ 75% {
+ -webkit-transform: rotate(810deg);
+ transform: rotate(810deg)
+ }
+ 87.5% {
+ -webkit-transform: rotate(945deg);
+ transform: rotate(945deg)
+ }
+ to {
+ -webkit-transform: rotate(1080deg);
+ transform: rotate(1080deg)
+ }
+}
+
+@keyframes mdl-spinner__fill-unfill-rotate {
+ 12.5% {
+ -webkit-transform: rotate(135deg);
+ transform: rotate(135deg)
+ }
+ 25% {
+ -webkit-transform: rotate(270deg);
+ transform: rotate(270deg)
+ }
+ 37.5% {
+ -webkit-transform: rotate(405deg);
+ transform: rotate(405deg)
+ }
+ 50% {
+ -webkit-transform: rotate(540deg);
+ transform: rotate(540deg)
+ }
+ 62.5% {
+ -webkit-transform: rotate(675deg);
+ transform: rotate(675deg)
+ }
+ 75% {
+ -webkit-transform: rotate(810deg);
+ transform: rotate(810deg)
+ }
+ 87.5% {
+ -webkit-transform: rotate(945deg);
+ transform: rotate(945deg)
+ }
+ to {
+ -webkit-transform: rotate(1080deg);
+ transform: rotate(1080deg)
+ }
+}
+
+@-webkit-keyframes mdl-spinner__layer-1-fade-in-out {
+ from,
+ 25% {
+ opacity: .99
+ }
+ 26%,
+ 89% {
+ opacity: 0
+ }
+ 90%,
+ 100% {
+ opacity: .99
+ }
+}
+
+@keyframes mdl-spinner__layer-1-fade-in-out {
+ from,
+ 25% {
+ opacity: .99
+ }
+ 26%,
+ 89% {
+ opacity: 0
+ }
+ 90%,
+ 100% {
+ opacity: .99
+ }
+}
+
+@-webkit-keyframes mdl-spinner__layer-2-fade-in-out {
+ from,
+ 15% {
+ opacity: 0
+ }
+ 25%,
+ 50% {
+ opacity: .99
+ }
+ 51% {
+ opacity: 0
+ }
+}
+
+@keyframes mdl-spinner__layer-2-fade-in-out {
+ from,
+ 15% {
+ opacity: 0
+ }
+ 25%,
+ 50% {
+ opacity: .99
+ }
+ 51% {
+ opacity: 0
+ }
+}
+
+@-webkit-keyframes mdl-spinner__layer-3-fade-in-out {
+ from,
+ 40% {
+ opacity: 0
+ }
+ 50%,
+ 75% {
+ opacity: .99
+ }
+ 76% {
+ opacity: 0
+ }
+}
+
+@keyframes mdl-spinner__layer-3-fade-in-out {
+ from,
+ 40% {
+ opacity: 0
+ }
+ 50%,
+ 75% {
+ opacity: .99
+ }
+ 76% {
+ opacity: 0
+ }
+}
+
+@-webkit-keyframes mdl-spinner__layer-4-fade-in-out {
+ from,
+ 65% {
+ opacity: 0
+ }
+ 75%,
+ 90% {
+ opacity: .99
+ }
+ 100% {
+ opacity: 0
+ }
+}
+
+@keyframes mdl-spinner__layer-4-fade-in-out {
+ from,
+ 65% {
+ opacity: 0
+ }
+ 75%,
+ 90% {
+ opacity: .99
+ }
+ 100% {
+ opacity: 0
+ }
+}
+
+.mdl-spinner__gap-patch {
+ position: absolute;
+ box-sizing: border-box;
+ top: 0;
+ left: 45%;
+ width: 10%;
+ height: 100%;
+ overflow: hidden;
+ border-color: inherit
+}
+
+.mdl-spinner__gap-patch .mdl-spinner__circle {
+ width: 1000%;
+ left: -450%
+}
+
+.mdl-spinner__circle-clipper {
+ display: inline-block;
+ position: relative;
+ width: 50%;
+ height: 100%;
+ overflow: hidden;
+ border-color: inherit
+}
+
+.mdl-spinner__circle-clipper.mdl-spinner__left {
+ float: left
+}
+
+.mdl-spinner__circle-clipper.mdl-spinner__right {
+ float: right
+}
+
+.mdl-spinner__circle-clipper .mdl-spinner__circle {
+ width: 200%
+}
+
+.mdl-spinner__circle {
+ box-sizing: border-box;
+ height: 100%;
+ border-width: 3px;
+ border-style: solid;
+ border-color: inherit;
+ border-bottom-color: transparent !important;
+ border-radius: 50%;
+ -webkit-animation: none;
+ animation: none;
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0
+}
+
+.mdl-spinner__left .mdl-spinner__circle {
+ border-right-color: transparent !important;
+ -webkit-transform: rotate(129deg);
+ transform: rotate(129deg)
+}
+
+.mdl-spinner.is-active .mdl-spinner__left .mdl-spinner__circle {
+ -webkit-animation: mdl-spinner__left-spin 1333ms cubic-bezier(.4, 0, .2, 1)infinite both;
+ animation: mdl-spinner__left-spin 1333ms cubic-bezier(.4, 0, .2, 1)infinite both
+}
+
+.mdl-spinner__right .mdl-spinner__circle {
+ left: -100%;
+ border-left-color: transparent !important;
+ -webkit-transform: rotate(-129deg);
+ transform: rotate(-129deg)
+}
+
+.mdl-spinner.is-active .mdl-spinner__right .mdl-spinner__circle {
+ -webkit-animation: mdl-spinner__right-spin 1333ms cubic-bezier(.4, 0, .2, 1)infinite both;
+ animation: mdl-spinner__right-spin 1333ms cubic-bezier(.4, 0, .2, 1)infinite both
+}
+
+@-webkit-keyframes mdl-spinner__left-spin {
+ from {
+ -webkit-transform: rotate(130deg);
+ transform: rotate(130deg)
+ }
+ 50% {
+ -webkit-transform: rotate(-5deg);
+ transform: rotate(-5deg)
+ }
+ to {
+ -webkit-transform: rotate(130deg);
+ transform: rotate(130deg)
+ }
+}
+
+@keyframes mdl-spinner__left-spin {
+ from {
+ -webkit-transform: rotate(130deg);
+ transform: rotate(130deg)
+ }
+ 50% {
+ -webkit-transform: rotate(-5deg);
+ transform: rotate(-5deg)
+ }
+ to {
+ -webkit-transform: rotate(130deg);
+ transform: rotate(130deg)
+ }
+}
+
+@-webkit-keyframes mdl-spinner__right-spin {
+ from {
+ -webkit-transform: rotate(-130deg);
+ transform: rotate(-130deg)
+ }
+ 50% {
+ -webkit-transform: rotate(5deg);
+ transform: rotate(5deg)
+ }
+ to {
+ -webkit-transform: rotate(-130deg);
+ transform: rotate(-130deg)
+ }
+}
+
+@keyframes mdl-spinner__right-spin {
+ from {
+ -webkit-transform: rotate(-130deg);
+ transform: rotate(-130deg)
+ }
+ 50% {
+ -webkit-transform: rotate(5deg);
+ transform: rotate(5deg)
+ }
+ to {
+ -webkit-transform: rotate(-130deg);
+ transform: rotate(-130deg)
+ }
+}
+
+.mdl-switch {
+ position: relative;
+ z-index: 1;
+ vertical-align: middle;
+ display: inline-block;
+ box-sizing: border-box;
+ width: 100%;
+ height: 24px;
+ margin: 0;
+ padding: 0;
+ overflow: visible;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none
+}
+
+.mdl-switch.is-upgraded {
+ padding-left: 28px
+}
+
+.mdl-switch__input {
+ line-height: 24px
+}
+
+.mdl-switch.is-upgraded .mdl-switch__input {
+ position: absolute;
+ width: 0;
+ height: 0;
+ margin: 0;
+ padding: 0;
+ opacity: 0;
+ -ms-appearance: none;
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ appearance: none;
+ border: none
+}
+
+.mdl-switch__track {
+ background: rgba(0, 0, 0, .26);
+ position: absolute;
+ left: 0;
+ top: 5px;
+ height: 14px;
+ width: 36px;
+ border-radius: 14px;
+ cursor: pointer
+}
+
+.mdl-switch.is-checked .mdl-switch__track {
+ background: rgba(63, 81, 181, .5)
+}
+
+.mdl-switch__track fieldset[disabled] .mdl-switch,
+.mdl-switch.is-disabled .mdl-switch__track {
+ background: rgba(0, 0, 0, .12);
+ cursor: auto
+}
+
+.mdl-switch__thumb {
+ background: #fafafa;
+ position: absolute;
+ left: 0;
+ top: 2px;
+ height: 20px;
+ width: 20px;
+ border-radius: 50%;
+ cursor: pointer;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
+ transition-duration: .28s;
+ transition-timing-function: cubic-bezier(.4, 0, .2, 1);
+ transition-property: left
+}
+
+.mdl-switch.is-checked .mdl-switch__thumb {
+ background: rgb(63, 81, 181);
+ left: 16px;
+ box-shadow: 0 3px 4px 0 rgba(0, 0, 0, .14), 0 3px 3px -2px rgba(0, 0, 0, .2), 0 1px 8px 0 rgba(0, 0, 0, .12)
+}
+
+.mdl-switch__thumb fieldset[disabled] .mdl-switch,
+.mdl-switch.is-disabled .mdl-switch__thumb {
+ background: #bdbdbd;
+ cursor: auto
+}
+
+.mdl-switch__focus-helper {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ -webkit-transform: translate(-4px, -4px);
+ transform: translate(-4px, -4px);
+ display: inline-block;
+ box-sizing: border-box;
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ background-color: transparent
+}
+
+.mdl-switch.is-focused .mdl-switch__focus-helper {
+ box-shadow: 0 0 0 20px rgba(0, 0, 0, .1);
+ background-color: rgba(0, 0, 0, .1)
+}
+
+.mdl-switch.is-focused.is-checked .mdl-switch__focus-helper {
+ box-shadow: 0 0 0 20px rgba(63, 81, 181, .26);
+ background-color: rgba(63, 81, 181, .26)
+}
+
+.mdl-switch__label {
+ position: relative;
+ cursor: pointer;
+ font-size: 16px;
+ line-height: 24px;
+ margin: 0;
+ left: 24px
+}
+
+.mdl-switch__label fieldset[disabled] .mdl-switch,
+.mdl-switch.is-disabled .mdl-switch__label {
+ color: #bdbdbd;
+ cursor: auto
+}
+
+.mdl-switch__ripple-container {
+ position: absolute;
+ z-index: 2;
+ top: -12px;
+ left: -14px;
+ box-sizing: border-box;
+ width: 48px;
+ height: 48px;
+ border-radius: 50%;
+ cursor: pointer;
+ overflow: hidden;
+ -webkit-mask-image: -webkit-radial-gradient(circle, #fff, #000);
+ transition-duration: .4s;
+ transition-timing-function: step-end;
+ transition-property: left
+}
+
+.mdl-switch__ripple-container .mdl-ripple {
+ background: rgb(63, 81, 181)
+}
+
+.mdl-switch__ripple-container fieldset[disabled] .mdl-switch,
+.mdl-switch.is-disabled .mdl-switch__ripple-container {
+ cursor: auto
+}
+
+fieldset[disabled] .mdl-switch .mdl-switch__ripple-container .mdl-ripple,
+.mdl-switch.is-disabled .mdl-switch__ripple-container .mdl-ripple {
+ background: 0 0
+}
+
+.mdl-switch.is-checked .mdl-switch__ripple-container {
+ left: 2px
+}
+
+.mdl-tabs {
+ display: block;
+ width: 100%
+}
+
+.mdl-tabs__tab-bar {
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: row;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-justify-content: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-align-content: space-between;
+ -ms-flex-line-pack: justify;
+ align-content: space-between;
+ -webkit-align-items: flex-start;
+ -ms-flex-align: start;
+ align-items: flex-start;
+ height: 48px;
+ padding: 0;
+ margin: 0;
+ border-bottom: 1px solid #e0e0e0
+}
+
+.mdl-tabs__tab {
+ margin: 0;
+ border: none;
+ padding: 0 24px;
+ float: left;
+ position: relative;
+ display: block;
+ text-decoration: none;
+ height: 48px;
+ line-height: 48px;
+ text-align: center;
+ font-weight: 500;
+ font-size: 14px;
+ text-transform: uppercase;
+ color: rgba(0, 0, 0, .54);
+ overflow: hidden
+}
+
+.mdl-tabs.is-upgraded .mdl-tabs__tab.is-active {
+ color: rgba(0, 0, 0, .87)
+}
+
+.mdl-tabs.is-upgraded .mdl-tabs__tab.is-active:after {
+ height: 2px;
+ width: 100%;
+ display: block;
+ content: " ";
+ bottom: 0;
+ left: 0;
+ position: absolute;
+ background: rgb(63, 81, 181);
+ -webkit-animation: border-expand .2s cubic-bezier(.4, 0, .4, 1).01s alternate forwards;
+ animation: border-expand .2s cubic-bezier(.4, 0, .4, 1).01s alternate forwards;
+ transition: all 1s cubic-bezier(.4, 0, 1, 1)
+}
+
+.mdl-tabs__tab .mdl-tabs__ripple-container {
+ display: block;
+ position: absolute;
+ height: 100%;
+ width: 100%;
+ left: 0;
+ top: 0;
+ z-index: 1;
+ overflow: hidden
+}
+
+.mdl-tabs__tab .mdl-tabs__ripple-container .mdl-ripple {
+ background: rgb(63, 81, 181)
+}
+
+.mdl-tabs__panel {
+ display: block
+}
+
+.mdl-tabs.is-upgraded .mdl-tabs__panel {
+ display: none
+}
+
+.mdl-tabs.is-upgraded .mdl-tabs__panel.is-active {
+ display: block
+}
+
+@-webkit-keyframes border-expand {
+ 0% {
+ opacity: 0;
+ width: 0
+ }
+ 100% {
+ opacity: 1;
+ width: 100%
+ }
+}
+
+@keyframes border-expand {
+ 0% {
+ opacity: 0;
+ width: 0
+ }
+ 100% {
+ opacity: 1;
+ width: 100%
+ }
+}
+
+.mdl-textfield {
+ position: relative;
+ font-size: 16px;
+ display: inline-block;
+ box-sizing: border-box;
+ width: 300px;
+ max-width: 100%;
+ margin: 0;
+ padding: 20px 0
+}
+
+.mdl-textfield .mdl-button {
+ position: absolute;
+ bottom: 20px
+}
+
+.mdl-textfield--align-right {
+ text-align: right
+}
+
+.mdl-textfield--full-width {
+ width: 100%
+}
+
+.mdl-textfield--expandable {
+ min-width: 32px;
+ width: auto;
+ min-height: 32px
+}
+
+.mdl-textfield--expandable .mdl-button--icon {
+ top: 16px
+}
+
+.mdl-textfield__input {
+ border: none;
+ border-bottom: 1px solid rgba(0, 0, 0, .12);
+ display: block;
+ font-size: 16px;
+ font-family: "Helvetica", "Arial", sans-serif;
+ margin: 0;
+ padding: 4px 0;
+ width: 100%;
+ background: 0 0;
+ text-align: left;
+ color: inherit
+}
+
+.mdl-textfield__input[type="number"] {
+ -moz-appearance: textfield
+}
+
+.mdl-textfield__input[type="number"]::-webkit-inner-spin-button,
+.mdl-textfield__input[type="number"]::-webkit-outer-spin-button {
+ -webkit-appearance: none;
+ margin: 0
+}
+
+.mdl-textfield.is-focused .mdl-textfield__input {
+ outline: none
+}
+
+.mdl-textfield.is-invalid .mdl-textfield__input {
+ border-color: #d50000;
+ box-shadow: none
+}
+
+fieldset[disabled] .mdl-textfield .mdl-textfield__input,
+.mdl-textfield.is-disabled .mdl-textfield__input {
+ background-color: transparent;
+ border-bottom: 1px dotted rgba(0, 0, 0, .12);
+ color: rgba(0, 0, 0, .26)
+}
+
+.mdl-textfield textarea.mdl-textfield__input {
+ display: block
+}
+
+.mdl-textfield__label {
+ bottom: 0;
+ color: rgba(0, 0, 0, .26);
+ font-size: 16px;
+ left: 0;
+ right: 0;
+ pointer-events: none;
+ position: absolute;
+ display: block;
+ top: 24px;
+ width: 100%;
+ overflow: hidden;
+ white-space: nowrap;
+ text-align: left
+}
+
+.mdl-textfield.is-dirty .mdl-textfield__label,
+.mdl-textfield.has-placeholder .mdl-textfield__label {
+ visibility: hidden
+}
+
+.mdl-textfield--floating-label .mdl-textfield__label {
+ transition-duration: .2s;
+ transition-timing-function: cubic-bezier(.4, 0, .2, 1)
+}
+
+.mdl-textfield--floating-label.has-placeholder .mdl-textfield__label {
+ transition: none
+}
+
+fieldset[disabled] .mdl-textfield .mdl-textfield__label,
+.mdl-textfield.is-disabled.is-disabled .mdl-textfield__label {
+ color: rgba(0, 0, 0, .26)
+}
+
+.mdl-textfield--floating-label.is-focused .mdl-textfield__label,
+.mdl-textfield--floating-label.is-dirty .mdl-textfield__label,
+.mdl-textfield--floating-label.has-placeholder .mdl-textfield__label {
+ color: rgb(63, 81, 181);
+ font-size: 12px;
+ top: 4px;
+ visibility: visible
+}
+
+.mdl-textfield--floating-label.is-focused .mdl-textfield__expandable-holder .mdl-textfield__label,
+.mdl-textfield--floating-label.is-dirty .mdl-textfield__expandable-holder .mdl-textfield__label,
+.mdl-textfield--floating-label.has-placeholder .mdl-textfield__expandable-holder .mdl-textfield__label {
+ top: -16px
+}
+
+.mdl-textfield--floating-label.is-invalid .mdl-textfield__label {
+ color: #d50000;
+ font-size: 12px
+}
+
+.mdl-textfield__label:after {
+ background-color: rgb(63, 81, 181);
+ bottom: 20px;
+ content: '';
+ height: 2px;
+ left: 45%;
+ position: absolute;
+ transition-duration: .2s;
+ transition-timing-function: cubic-bezier(.4, 0, .2, 1);
+ visibility: hidden;
+ width: 10px
+}
+
+.mdl-textfield.is-focused .mdl-textfield__label:after {
+ left: 0;
+ visibility: visible;
+ width: 100%
+}
+
+.mdl-textfield.is-invalid .mdl-textfield__label:after {
+ background-color: #d50000
+}
+
+.mdl-textfield__error {
+ color: #d50000;
+ position: absolute;
+ font-size: 12px;
+ margin-top: 3px;
+ visibility: hidden;
+ display: block
+}
+
+.mdl-textfield.is-invalid .mdl-textfield__error {
+ visibility: visible
+}
+
+.mdl-textfield__expandable-holder {
+ display: inline-block;
+ position: relative;
+ margin-left: 32px;
+ transition-duration: .2s;
+ transition-timing-function: cubic-bezier(.4, 0, .2, 1);
+ display: inline-block;
+ max-width: .1px
+}
+
+.mdl-textfield.is-focused .mdl-textfield__expandable-holder,
+.mdl-textfield.is-dirty .mdl-textfield__expandable-holder {
+ max-width: 600px
+}
+
+.mdl-textfield__expandable-holder .mdl-textfield__label:after {
+ bottom: 0
+}
+
+.mdl-tooltip {
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ -webkit-transform-origin: top center;
+ transform-origin: top center;
+ z-index: 999;
+ background: rgba(97, 97, 97, .9);
+ border-radius: 2px;
+ color: #fff;
+ display: inline-block;
+ font-size: 10px;
+ font-weight: 500;
+ line-height: 14px;
+ max-width: 170px;
+ position: fixed;
+ top: -500px;
+ left: -500px;
+ padding: 8px;
+ text-align: center
+}
+
+.mdl-tooltip.is-active {
+ -webkit-animation: pulse 200ms cubic-bezier(0, 0, .2, 1)forwards;
+ animation: pulse 200ms cubic-bezier(0, 0, .2, 1)forwards
+}
+
+.mdl-tooltip--large {
+ line-height: 14px;
+ font-size: 14px;
+ padding: 16px
+}
+
+@-webkit-keyframes pulse {
+ 0% {
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ opacity: 0
+ }
+ 50% {
+ -webkit-transform: scale(.99);
+ transform: scale(.99)
+ }
+ 100% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ visibility: visible
+ }
+}
+
+@keyframes pulse {
+ 0% {
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ opacity: 0
+ }
+ 50% {
+ -webkit-transform: scale(.99);
+ transform: scale(.99)
+ }
+ 100% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ visibility: visible
+ }
+}
+
+.mdl-shadow--2dp {
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12)
+}
+
+.mdl-shadow--3dp {
+ box-shadow: 0 3px 4px 0 rgba(0, 0, 0, .14), 0 3px 3px -2px rgba(0, 0, 0, .2), 0 1px 8px 0 rgba(0, 0, 0, .12)
+}
+
+.mdl-shadow--4dp {
+ box-shadow: 0 4px 5px 0 rgba(0, 0, 0, .14), 0 1px 10px 0 rgba(0, 0, 0, .12), 0 2px 4px -1px rgba(0, 0, 0, .2)
+}
+
+.mdl-shadow--6dp {
+ box-shadow: 0 6px 10px 0 rgba(0, 0, 0, .14), 0 1px 18px 0 rgba(0, 0, 0, .12), 0 3px 5px -1px rgba(0, 0, 0, .2)
+}
+
+.mdl-shadow--8dp {
+ box-shadow: 0 8px 10px 1px rgba(0, 0, 0, .14), 0 3px 14px 2px rgba(0, 0, 0, .12), 0 5px 5px -3px rgba(0, 0, 0, .2)
+}
+
+.mdl-shadow--16dp {
+ box-shadow: 0 16px 24px 2px rgba(0, 0, 0, .14), 0 6px 30px 5px rgba(0, 0, 0, .12), 0 8px 10px -5px rgba(0, 0, 0, .2)
+}
+
+.mdl-shadow--24dp {
+ box-shadow: 0 9px 46px 8px rgba(0, 0, 0, .14), 0 11px 15px -7px rgba(0, 0, 0, .12), 0 24px 38px 3px rgba(0, 0, 0, .2)
+}
+
+.mdl-grid {
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-flow: row wrap;
+ -ms-flex-flow: row wrap;
+ flex-flow: row wrap;
+ margin: 0 auto;
+ -webkit-align-items: stretch;
+ -ms-flex-align: stretch;
+ align-items: stretch
+}
+
+.mdl-grid.mdl-grid--no-spacing {
+ padding: 0
+}
+
+.mdl-cell {
+ box-sizing: border-box
+}
+
+.mdl-cell--top {
+ -webkit-align-self: flex-start;
+ -ms-flex-item-align: start;
+ align-self: flex-start
+}
+
+.mdl-cell--middle {
+ -webkit-align-self: center;
+ -ms-flex-item-align: center;
+ -ms-grid-row-align: center;
+ align-self: center
+}
+
+.mdl-cell--bottom {
+ -webkit-align-self: flex-end;
+ -ms-flex-item-align: end;
+ align-self: flex-end
+}
+
+.mdl-cell--stretch {
+ -webkit-align-self: stretch;
+ -ms-flex-item-align: stretch;
+ -ms-grid-row-align: stretch;
+ align-self: stretch
+}
+
+.mdl-grid.mdl-grid--no-spacing>.mdl-cell {
+ margin: 0
+}
+
+.mdl-cell--order-1 {
+ -webkit-order: 1;
+ -ms-flex-order: 1;
+ order: 1
+}
+
+.mdl-cell--order-2 {
+ -webkit-order: 2;
+ -ms-flex-order: 2;
+ order: 2
+}
+
+.mdl-cell--order-3 {
+ -webkit-order: 3;
+ -ms-flex-order: 3;
+ order: 3
+}
+
+.mdl-cell--order-4 {
+ -webkit-order: 4;
+ -ms-flex-order: 4;
+ order: 4
+}
+
+.mdl-cell--order-5 {
+ -webkit-order: 5;
+ -ms-flex-order: 5;
+ order: 5
+}
+
+.mdl-cell--order-6 {
+ -webkit-order: 6;
+ -ms-flex-order: 6;
+ order: 6
+}
+
+.mdl-cell--order-7 {
+ -webkit-order: 7;
+ -ms-flex-order: 7;
+ order: 7
+}
+
+.mdl-cell--order-8 {
+ -webkit-order: 8;
+ -ms-flex-order: 8;
+ order: 8
+}
+
+.mdl-cell--order-9 {
+ -webkit-order: 9;
+ -ms-flex-order: 9;
+ order: 9
+}
+
+.mdl-cell--order-10 {
+ -webkit-order: 10;
+ -ms-flex-order: 10;
+ order: 10
+}
+
+.mdl-cell--order-11 {
+ -webkit-order: 11;
+ -ms-flex-order: 11;
+ order: 11
+}
+
+.mdl-cell--order-12 {
+ -webkit-order: 12;
+ -ms-flex-order: 12;
+ order: 12
+}
+
+@media (max-width:479px) {
+ .mdl-grid {
+ padding: 8px
+ }
+ .mdl-cell {
+ margin: 8px;
+ width: calc(100% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell {
+ width: 100%
+ }
+ .mdl-cell--hide-phone {
+ display: none !important
+ }
+ .mdl-cell--order-1-phone.mdl-cell--order-1-phone {
+ -webkit-order: 1;
+ -ms-flex-order: 1;
+ order: 1
+ }
+ .mdl-cell--order-2-phone.mdl-cell--order-2-phone {
+ -webkit-order: 2;
+ -ms-flex-order: 2;
+ order: 2
+ }
+ .mdl-cell--order-3-phone.mdl-cell--order-3-phone {
+ -webkit-order: 3;
+ -ms-flex-order: 3;
+ order: 3
+ }
+ .mdl-cell--order-4-phone.mdl-cell--order-4-phone {
+ -webkit-order: 4;
+ -ms-flex-order: 4;
+ order: 4
+ }
+ .mdl-cell--order-5-phone.mdl-cell--order-5-phone {
+ -webkit-order: 5;
+ -ms-flex-order: 5;
+ order: 5
+ }
+ .mdl-cell--order-6-phone.mdl-cell--order-6-phone {
+ -webkit-order: 6;
+ -ms-flex-order: 6;
+ order: 6
+ }
+ .mdl-cell--order-7-phone.mdl-cell--order-7-phone {
+ -webkit-order: 7;
+ -ms-flex-order: 7;
+ order: 7
+ }
+ .mdl-cell--order-8-phone.mdl-cell--order-8-phone {
+ -webkit-order: 8;
+ -ms-flex-order: 8;
+ order: 8
+ }
+ .mdl-cell--order-9-phone.mdl-cell--order-9-phone {
+ -webkit-order: 9;
+ -ms-flex-order: 9;
+ order: 9
+ }
+ .mdl-cell--order-10-phone.mdl-cell--order-10-phone {
+ -webkit-order: 10;
+ -ms-flex-order: 10;
+ order: 10
+ }
+ .mdl-cell--order-11-phone.mdl-cell--order-11-phone {
+ -webkit-order: 11;
+ -ms-flex-order: 11;
+ order: 11
+ }
+ .mdl-cell--order-12-phone.mdl-cell--order-12-phone {
+ -webkit-order: 12;
+ -ms-flex-order: 12;
+ order: 12
+ }
+ .mdl-cell--1-col,
+ .mdl-cell--1-col-phone.mdl-cell--1-col-phone {
+ width: calc(25% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--1-col,
+ .mdl-grid--no-spacing>.mdl-cell--1-col-phone.mdl-cell--1-col-phone {
+ width: 25%
+ }
+ .mdl-cell--2-col,
+ .mdl-cell--2-col-phone.mdl-cell--2-col-phone {
+ width: calc(50% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--2-col,
+ .mdl-grid--no-spacing>.mdl-cell--2-col-phone.mdl-cell--2-col-phone {
+ width: 50%
+ }
+ .mdl-cell--3-col,
+ .mdl-cell--3-col-phone.mdl-cell--3-col-phone {
+ width: calc(75% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--3-col,
+ .mdl-grid--no-spacing>.mdl-cell--3-col-phone.mdl-cell--3-col-phone {
+ width: 75%
+ }
+ .mdl-cell--4-col,
+ .mdl-cell--4-col-phone.mdl-cell--4-col-phone {
+ width: calc(100% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--4-col,
+ .mdl-grid--no-spacing>.mdl-cell--4-col-phone.mdl-cell--4-col-phone {
+ width: 100%
+ }
+ .mdl-cell--5-col,
+ .mdl-cell--5-col-phone.mdl-cell--5-col-phone {
+ width: calc(100% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--5-col,
+ .mdl-grid--no-spacing>.mdl-cell--5-col-phone.mdl-cell--5-col-phone {
+ width: 100%
+ }
+ .mdl-cell--6-col,
+ .mdl-cell--6-col-phone.mdl-cell--6-col-phone {
+ width: calc(100% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--6-col,
+ .mdl-grid--no-spacing>.mdl-cell--6-col-phone.mdl-cell--6-col-phone {
+ width: 100%
+ }
+ .mdl-cell--7-col,
+ .mdl-cell--7-col-phone.mdl-cell--7-col-phone {
+ width: calc(100% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--7-col,
+ .mdl-grid--no-spacing>.mdl-cell--7-col-phone.mdl-cell--7-col-phone {
+ width: 100%
+ }
+ .mdl-cell--8-col,
+ .mdl-cell--8-col-phone.mdl-cell--8-col-phone {
+ width: calc(100% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--8-col,
+ .mdl-grid--no-spacing>.mdl-cell--8-col-phone.mdl-cell--8-col-phone {
+ width: 100%
+ }
+ .mdl-cell--9-col,
+ .mdl-cell--9-col-phone.mdl-cell--9-col-phone {
+ width: calc(100% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--9-col,
+ .mdl-grid--no-spacing>.mdl-cell--9-col-phone.mdl-cell--9-col-phone {
+ width: 100%
+ }
+ .mdl-cell--10-col,
+ .mdl-cell--10-col-phone.mdl-cell--10-col-phone {
+ width: calc(100% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--10-col,
+ .mdl-grid--no-spacing>.mdl-cell--10-col-phone.mdl-cell--10-col-phone {
+ width: 100%
+ }
+ .mdl-cell--11-col,
+ .mdl-cell--11-col-phone.mdl-cell--11-col-phone {
+ width: calc(100% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--11-col,
+ .mdl-grid--no-spacing>.mdl-cell--11-col-phone.mdl-cell--11-col-phone {
+ width: 100%
+ }
+ .mdl-cell--12-col,
+ .mdl-cell--12-col-phone.mdl-cell--12-col-phone {
+ width: calc(100% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--12-col,
+ .mdl-grid--no-spacing>.mdl-cell--12-col-phone.mdl-cell--12-col-phone {
+ width: 100%
+ }
+ .mdl-cell--1-offset,
+ .mdl-cell--1-offset-phone.mdl-cell--1-offset-phone {
+ margin-left: calc(25% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset-phone.mdl-cell--1-offset-phone {
+ margin-left: 25%
+ }
+ .mdl-cell--2-offset,
+ .mdl-cell--2-offset-phone.mdl-cell--2-offset-phone {
+ margin-left: calc(50% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset-phone.mdl-cell--2-offset-phone {
+ margin-left: 50%
+ }
+ .mdl-cell--3-offset,
+ .mdl-cell--3-offset-phone.mdl-cell--3-offset-phone {
+ margin-left: calc(75% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset-phone.mdl-cell--3-offset-phone {
+ margin-left: 75%
+ }
+}
+
+@media (min-width:480px) and (max-width:839px) {
+ .mdl-grid {
+ padding: 8px
+ }
+ .mdl-cell {
+ margin: 8px;
+ width: calc(50% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell {
+ width: 50%
+ }
+ .mdl-cell--hide-tablet {
+ display: none !important
+ }
+ .mdl-cell--order-1-tablet.mdl-cell--order-1-tablet {
+ -webkit-order: 1;
+ -ms-flex-order: 1;
+ order: 1
+ }
+ .mdl-cell--order-2-tablet.mdl-cell--order-2-tablet {
+ -webkit-order: 2;
+ -ms-flex-order: 2;
+ order: 2
+ }
+ .mdl-cell--order-3-tablet.mdl-cell--order-3-tablet {
+ -webkit-order: 3;
+ -ms-flex-order: 3;
+ order: 3
+ }
+ .mdl-cell--order-4-tablet.mdl-cell--order-4-tablet {
+ -webkit-order: 4;
+ -ms-flex-order: 4;
+ order: 4
+ }
+ .mdl-cell--order-5-tablet.mdl-cell--order-5-tablet {
+ -webkit-order: 5;
+ -ms-flex-order: 5;
+ order: 5
+ }
+ .mdl-cell--order-6-tablet.mdl-cell--order-6-tablet {
+ -webkit-order: 6;
+ -ms-flex-order: 6;
+ order: 6
+ }
+ .mdl-cell--order-7-tablet.mdl-cell--order-7-tablet {
+ -webkit-order: 7;
+ -ms-flex-order: 7;
+ order: 7
+ }
+ .mdl-cell--order-8-tablet.mdl-cell--order-8-tablet {
+ -webkit-order: 8;
+ -ms-flex-order: 8;
+ order: 8
+ }
+ .mdl-cell--order-9-tablet.mdl-cell--order-9-tablet {
+ -webkit-order: 9;
+ -ms-flex-order: 9;
+ order: 9
+ }
+ .mdl-cell--order-10-tablet.mdl-cell--order-10-tablet {
+ -webkit-order: 10;
+ -ms-flex-order: 10;
+ order: 10
+ }
+ .mdl-cell--order-11-tablet.mdl-cell--order-11-tablet {
+ -webkit-order: 11;
+ -ms-flex-order: 11;
+ order: 11
+ }
+ .mdl-cell--order-12-tablet.mdl-cell--order-12-tablet {
+ -webkit-order: 12;
+ -ms-flex-order: 12;
+ order: 12
+ }
+ .mdl-cell--1-col,
+ .mdl-cell--1-col-tablet.mdl-cell--1-col-tablet {
+ width: calc(12.5% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--1-col,
+ .mdl-grid--no-spacing>.mdl-cell--1-col-tablet.mdl-cell--1-col-tablet {
+ width: 12.5%
+ }
+ .mdl-cell--2-col,
+ .mdl-cell--2-col-tablet.mdl-cell--2-col-tablet {
+ width: calc(25% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--2-col,
+ .mdl-grid--no-spacing>.mdl-cell--2-col-tablet.mdl-cell--2-col-tablet {
+ width: 25%
+ }
+ .mdl-cell--3-col,
+ .mdl-cell--3-col-tablet.mdl-cell--3-col-tablet {
+ width: calc(37.5% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--3-col,
+ .mdl-grid--no-spacing>.mdl-cell--3-col-tablet.mdl-cell--3-col-tablet {
+ width: 37.5%
+ }
+ .mdl-cell--4-col,
+ .mdl-cell--4-col-tablet.mdl-cell--4-col-tablet {
+ width: calc(50% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--4-col,
+ .mdl-grid--no-spacing>.mdl-cell--4-col-tablet.mdl-cell--4-col-tablet {
+ width: 50%
+ }
+ .mdl-cell--5-col,
+ .mdl-cell--5-col-tablet.mdl-cell--5-col-tablet {
+ width: calc(62.5% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--5-col,
+ .mdl-grid--no-spacing>.mdl-cell--5-col-tablet.mdl-cell--5-col-tablet {
+ width: 62.5%
+ }
+ .mdl-cell--6-col,
+ .mdl-cell--6-col-tablet.mdl-cell--6-col-tablet {
+ width: calc(75% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--6-col,
+ .mdl-grid--no-spacing>.mdl-cell--6-col-tablet.mdl-cell--6-col-tablet {
+ width: 75%
+ }
+ .mdl-cell--7-col,
+ .mdl-cell--7-col-tablet.mdl-cell--7-col-tablet {
+ width: calc(87.5% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--7-col,
+ .mdl-grid--no-spacing>.mdl-cell--7-col-tablet.mdl-cell--7-col-tablet {
+ width: 87.5%
+ }
+ .mdl-cell--8-col,
+ .mdl-cell--8-col-tablet.mdl-cell--8-col-tablet {
+ width: calc(100% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--8-col,
+ .mdl-grid--no-spacing>.mdl-cell--8-col-tablet.mdl-cell--8-col-tablet {
+ width: 100%
+ }
+ .mdl-cell--9-col,
+ .mdl-cell--9-col-tablet.mdl-cell--9-col-tablet {
+ width: calc(100% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--9-col,
+ .mdl-grid--no-spacing>.mdl-cell--9-col-tablet.mdl-cell--9-col-tablet {
+ width: 100%
+ }
+ .mdl-cell--10-col,
+ .mdl-cell--10-col-tablet.mdl-cell--10-col-tablet {
+ width: calc(100% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--10-col,
+ .mdl-grid--no-spacing>.mdl-cell--10-col-tablet.mdl-cell--10-col-tablet {
+ width: 100%
+ }
+ .mdl-cell--11-col,
+ .mdl-cell--11-col-tablet.mdl-cell--11-col-tablet {
+ width: calc(100% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--11-col,
+ .mdl-grid--no-spacing>.mdl-cell--11-col-tablet.mdl-cell--11-col-tablet {
+ width: 100%
+ }
+ .mdl-cell--12-col,
+ .mdl-cell--12-col-tablet.mdl-cell--12-col-tablet {
+ width: calc(100% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--12-col,
+ .mdl-grid--no-spacing>.mdl-cell--12-col-tablet.mdl-cell--12-col-tablet {
+ width: 100%
+ }
+ .mdl-cell--1-offset,
+ .mdl-cell--1-offset-tablet.mdl-cell--1-offset-tablet {
+ margin-left: calc(12.5% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset-tablet.mdl-cell--1-offset-tablet {
+ margin-left: 12.5%
+ }
+ .mdl-cell--2-offset,
+ .mdl-cell--2-offset-tablet.mdl-cell--2-offset-tablet {
+ margin-left: calc(25% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset-tablet.mdl-cell--2-offset-tablet {
+ margin-left: 25%
+ }
+ .mdl-cell--3-offset,
+ .mdl-cell--3-offset-tablet.mdl-cell--3-offset-tablet {
+ margin-left: calc(37.5% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset-tablet.mdl-cell--3-offset-tablet {
+ margin-left: 37.5%
+ }
+ .mdl-cell--4-offset,
+ .mdl-cell--4-offset-tablet.mdl-cell--4-offset-tablet {
+ margin-left: calc(50% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset-tablet.mdl-cell--4-offset-tablet {
+ margin-left: 50%
+ }
+ .mdl-cell--5-offset,
+ .mdl-cell--5-offset-tablet.mdl-cell--5-offset-tablet {
+ margin-left: calc(62.5% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset-tablet.mdl-cell--5-offset-tablet {
+ margin-left: 62.5%
+ }
+ .mdl-cell--6-offset,
+ .mdl-cell--6-offset-tablet.mdl-cell--6-offset-tablet {
+ margin-left: calc(75% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset-tablet.mdl-cell--6-offset-tablet {
+ margin-left: 75%
+ }
+ .mdl-cell--7-offset,
+ .mdl-cell--7-offset-tablet.mdl-cell--7-offset-tablet {
+ margin-left: calc(87.5% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset-tablet.mdl-cell--7-offset-tablet {
+ margin-left: 87.5%
+ }
+}
+
+@media (min-width:840px) {
+ .mdl-grid {
+ padding: 8px
+ }
+ .mdl-cell {
+ margin: 8px;
+ width: calc(33.3333333333% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell {
+ width: 33.3333333333%
+ }
+ .mdl-cell--hide-desktop {
+ display: none !important
+ }
+ .mdl-cell--order-1-desktop.mdl-cell--order-1-desktop {
+ -webkit-order: 1;
+ -ms-flex-order: 1;
+ order: 1
+ }
+ .mdl-cell--order-2-desktop.mdl-cell--order-2-desktop {
+ -webkit-order: 2;
+ -ms-flex-order: 2;
+ order: 2
+ }
+ .mdl-cell--order-3-desktop.mdl-cell--order-3-desktop {
+ -webkit-order: 3;
+ -ms-flex-order: 3;
+ order: 3
+ }
+ .mdl-cell--order-4-desktop.mdl-cell--order-4-desktop {
+ -webkit-order: 4;
+ -ms-flex-order: 4;
+ order: 4
+ }
+ .mdl-cell--order-5-desktop.mdl-cell--order-5-desktop {
+ -webkit-order: 5;
+ -ms-flex-order: 5;
+ order: 5
+ }
+ .mdl-cell--order-6-desktop.mdl-cell--order-6-desktop {
+ -webkit-order: 6;
+ -ms-flex-order: 6;
+ order: 6
+ }
+ .mdl-cell--order-7-desktop.mdl-cell--order-7-desktop {
+ -webkit-order: 7;
+ -ms-flex-order: 7;
+ order: 7
+ }
+ .mdl-cell--order-8-desktop.mdl-cell--order-8-desktop {
+ -webkit-order: 8;
+ -ms-flex-order: 8;
+ order: 8
+ }
+ .mdl-cell--order-9-desktop.mdl-cell--order-9-desktop {
+ -webkit-order: 9;
+ -ms-flex-order: 9;
+ order: 9
+ }
+ .mdl-cell--order-10-desktop.mdl-cell--order-10-desktop {
+ -webkit-order: 10;
+ -ms-flex-order: 10;
+ order: 10
+ }
+ .mdl-cell--order-11-desktop.mdl-cell--order-11-desktop {
+ -webkit-order: 11;
+ -ms-flex-order: 11;
+ order: 11
+ }
+ .mdl-cell--order-12-desktop.mdl-cell--order-12-desktop {
+ -webkit-order: 12;
+ -ms-flex-order: 12;
+ order: 12
+ }
+ .mdl-cell--1-col,
+ .mdl-cell--1-col-desktop.mdl-cell--1-col-desktop {
+ width: calc(8.3333333333% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--1-col,
+ .mdl-grid--no-spacing>.mdl-cell--1-col-desktop.mdl-cell--1-col-desktop {
+ width: 8.3333333333%
+ }
+ .mdl-cell--2-col,
+ .mdl-cell--2-col-desktop.mdl-cell--2-col-desktop {
+ width: calc(16.6666666667% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--2-col,
+ .mdl-grid--no-spacing>.mdl-cell--2-col-desktop.mdl-cell--2-col-desktop {
+ width: 16.6666666667%
+ }
+ .mdl-cell--3-col,
+ .mdl-cell--3-col-desktop.mdl-cell--3-col-desktop {
+ width: calc(25% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--3-col,
+ .mdl-grid--no-spacing>.mdl-cell--3-col-desktop.mdl-cell--3-col-desktop {
+ width: 25%
+ }
+ .mdl-cell--4-col,
+ .mdl-cell--4-col-desktop.mdl-cell--4-col-desktop {
+ width: calc(33.3333333333% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--4-col,
+ .mdl-grid--no-spacing>.mdl-cell--4-col-desktop.mdl-cell--4-col-desktop {
+ width: 33.3333333333%
+ }
+ .mdl-cell--5-col,
+ .mdl-cell--5-col-desktop.mdl-cell--5-col-desktop {
+ width: calc(41.6666666667% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--5-col,
+ .mdl-grid--no-spacing>.mdl-cell--5-col-desktop.mdl-cell--5-col-desktop {
+ width: 41.6666666667%
+ }
+ .mdl-cell--6-col,
+ .mdl-cell--6-col-desktop.mdl-cell--6-col-desktop {
+ width: calc(50% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--6-col,
+ .mdl-grid--no-spacing>.mdl-cell--6-col-desktop.mdl-cell--6-col-desktop {
+ width: 50%
+ }
+ .mdl-cell--7-col,
+ .mdl-cell--7-col-desktop.mdl-cell--7-col-desktop {
+ width: calc(58.3333333333% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--7-col,
+ .mdl-grid--no-spacing>.mdl-cell--7-col-desktop.mdl-cell--7-col-desktop {
+ width: 58.3333333333%
+ }
+ .mdl-cell--8-col,
+ .mdl-cell--8-col-desktop.mdl-cell--8-col-desktop {
+ width: calc(66.6666666667% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--8-col,
+ .mdl-grid--no-spacing>.mdl-cell--8-col-desktop.mdl-cell--8-col-desktop {
+ width: 66.6666666667%
+ }
+ .mdl-cell--9-col,
+ .mdl-cell--9-col-desktop.mdl-cell--9-col-desktop {
+ width: calc(75% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--9-col,
+ .mdl-grid--no-spacing>.mdl-cell--9-col-desktop.mdl-cell--9-col-desktop {
+ width: 75%
+ }
+ .mdl-cell--10-col,
+ .mdl-cell--10-col-desktop.mdl-cell--10-col-desktop {
+ width: calc(83.3333333333% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--10-col,
+ .mdl-grid--no-spacing>.mdl-cell--10-col-desktop.mdl-cell--10-col-desktop {
+ width: 83.3333333333%
+ }
+ .mdl-cell--11-col,
+ .mdl-cell--11-col-desktop.mdl-cell--11-col-desktop {
+ width: calc(91.6666666667% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--11-col,
+ .mdl-grid--no-spacing>.mdl-cell--11-col-desktop.mdl-cell--11-col-desktop {
+ width: 91.6666666667%
+ }
+ .mdl-cell--12-col,
+ .mdl-cell--12-col-desktop.mdl-cell--12-col-desktop {
+ width: calc(100% - 16px)
+ }
+ .mdl-grid--no-spacing>.mdl-cell--12-col,
+ .mdl-grid--no-spacing>.mdl-cell--12-col-desktop.mdl-cell--12-col-desktop {
+ width: 100%
+ }
+ .mdl-cell--1-offset,
+ .mdl-cell--1-offset-desktop.mdl-cell--1-offset-desktop {
+ margin-left: calc(8.3333333333% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--1-offset-desktop.mdl-cell--1-offset-desktop {
+ margin-left: 8.3333333333%
+ }
+ .mdl-cell--2-offset,
+ .mdl-cell--2-offset-desktop.mdl-cell--2-offset-desktop {
+ margin-left: calc(16.6666666667% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--2-offset-desktop.mdl-cell--2-offset-desktop {
+ margin-left: 16.6666666667%
+ }
+ .mdl-cell--3-offset,
+ .mdl-cell--3-offset-desktop.mdl-cell--3-offset-desktop {
+ margin-left: calc(25% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--3-offset-desktop.mdl-cell--3-offset-desktop {
+ margin-left: 25%
+ }
+ .mdl-cell--4-offset,
+ .mdl-cell--4-offset-desktop.mdl-cell--4-offset-desktop {
+ margin-left: calc(33.3333333333% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--4-offset-desktop.mdl-cell--4-offset-desktop {
+ margin-left: 33.3333333333%
+ }
+ .mdl-cell--5-offset,
+ .mdl-cell--5-offset-desktop.mdl-cell--5-offset-desktop {
+ margin-left: calc(41.6666666667% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--5-offset-desktop.mdl-cell--5-offset-desktop {
+ margin-left: 41.6666666667%
+ }
+ .mdl-cell--6-offset,
+ .mdl-cell--6-offset-desktop.mdl-cell--6-offset-desktop {
+ margin-left: calc(50% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--6-offset-desktop.mdl-cell--6-offset-desktop {
+ margin-left: 50%
+ }
+ .mdl-cell--7-offset,
+ .mdl-cell--7-offset-desktop.mdl-cell--7-offset-desktop {
+ margin-left: calc(58.3333333333% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--7-offset-desktop.mdl-cell--7-offset-desktop {
+ margin-left: 58.3333333333%
+ }
+ .mdl-cell--8-offset,
+ .mdl-cell--8-offset-desktop.mdl-cell--8-offset-desktop {
+ margin-left: calc(66.6666666667% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--8-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--8-offset-desktop.mdl-cell--8-offset-desktop {
+ margin-left: 66.6666666667%
+ }
+ .mdl-cell--9-offset,
+ .mdl-cell--9-offset-desktop.mdl-cell--9-offset-desktop {
+ margin-left: calc(75% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--9-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--9-offset-desktop.mdl-cell--9-offset-desktop {
+ margin-left: 75%
+ }
+ .mdl-cell--10-offset,
+ .mdl-cell--10-offset-desktop.mdl-cell--10-offset-desktop {
+ margin-left: calc(83.3333333333% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--10-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--10-offset-desktop.mdl-cell--10-offset-desktop {
+ margin-left: 83.3333333333%
+ }
+ .mdl-cell--11-offset,
+ .mdl-cell--11-offset-desktop.mdl-cell--11-offset-desktop {
+ margin-left: calc(91.6666666667% + 8px)
+ }
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--11-offset,
+ .mdl-grid.mdl-grid--no-spacing>.mdl-cell--11-offset-desktop.mdl-cell--11-offset-desktop {
+ margin-left: 91.6666666667%
+ }
+}
+
+body {
+ margin: 0
+}
+
+.styleguide-demo h1 {
+ margin: 48px 24px 0
+}
+
+.styleguide-demo h1:after {
+ content: '';
+ display: block;
+ width: 100%;
+ border-bottom: 1px solid rgba(0, 0, 0, .5);
+ margin-top: 24px
+}
+
+.styleguide-demo {
+ opacity: 0;
+ transition: opacity .6s ease
+}
+
+.styleguide-masthead {
+ height: 256px;
+ background: #212121;
+ padding: 115px 16px 0
+}
+
+.styleguide-container {
+ position: relative;
+ max-width: 960px;
+ width: 100%
+}
+
+.styleguide-title {
+ color: #fff;
+ bottom: auto;
+ position: relative;
+ font-size: 56px;
+ font-weight: 300;
+ line-height: 1;
+ letter-spacing: -.02em
+}
+
+.styleguide-title:after {
+ border-bottom: 0
+}
+
+.styleguide-title span {
+ font-weight: 300
+}
+
+.mdl-styleguide .mdl-layout__drawer .mdl-navigation__link {
+ padding: 10px 24px
+}
+
+.demosLoaded .styleguide-demo {
+ opacity: 1
+}
+
+iframe {
+ display: block;
+ width: 100%;
+ border: none
+}
+
+iframe.heightSet {
+ overflow: hidden
+}
+
+.demo-wrapper {
+ margin: 24px
+}
+
+.demo-wrapper iframe {
+ border: 1px solid rgba(0, 0, 0, .5)
+} \ No newline at end of file
diff --git a/css/style.css b/css/style.css
new file mode 100755
index 0000000..ce350c6
--- /dev/null
+++ b/css/style.css
@@ -0,0 +1,3 @@
+#hello {
+ color: red;
+}
diff --git a/img/app.svg b/img/app.svg
new file mode 100755
index 0000000..fe370f8
--- /dev/null
+++ b/img/app.svg
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ height="32"
+ width="32"
+ version="1"
+ viewBox="0 0 32 32"
+ id="svg4"
+ sodipodi:docname="app.svg"
+ inkscape:version="0.92.1 r">
+ <metadata
+ id="metadata10">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs8" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="789"
+ inkscape:window-height="480"
+ id="namedview6"
+ showgrid="false"
+ inkscape:zoom="7.375"
+ inkscape:cx="-8.3389831"
+ inkscape:cy="16"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="svg4" />
+ <path
+ d="M13.733 0a.915.915 0 0 0-.933.934V3.6c-1.182.304-2.243.794-3.267 1.4L7.6 3.068a.93.93 0 0 0-1.334 0l-3.2 3.2a.93.93 0 0 0 0 1.334L5 9.535c-.607 1.024-1.097 2.085-1.4 3.267H.933a.915.915 0 0 0-.933.934v4.533c0 .53.403.934.933.934H3.6c.303 1.182.793 2.243 1.4 3.267l-1.934 1.935a.93.93 0 0 0 0 1.333l3.2 3.2a.93.93 0 0 0 1.333 0L9.532 27c1.024.61 2.085 1.097 3.266 1.4v2.667c0 .53.402.933.932.933h4.534c.53 0 .933-.403.933-.935V28.4c1.18-.305 2.24-.795 3.265-1.4L24.4 28.93a.93.93 0 0 0 1.332 0l3.2-3.2a.93.93 0 0 0 0-1.333L27 22.465c.607-1.024 1.096-2.085 1.4-3.266h2.665a.915.915 0 0 0 .935-.933v-4.534a.915.915 0 0 0-.934-.933H28.4c-.304-1.182-.792-2.243-1.4-3.267L28.932 7.6a.93.93 0 0 0 0-1.334l-3.2-3.2a.93.93 0 0 0-1.333 0L22.465 5c-1.024-.607-2.084-1.097-3.266-1.4V.933A.915.915 0 0 0 18.267 0zM16 8.87A7.134 7.134 0 0 1 23.13 16 7.134 7.134 0 0 1 16 23.133c-3.936 0-7.13-3.196-7.13-7.132S12.063 8.87 16 8.87z"
+ display="block"
+ fill="#fff"
+ id="path2"
+ style="fill:#ffffff" />
+</svg>
diff --git a/js/browsers/browser.js b/js/browsers/browser.js
new file mode 100755
index 0000000..9d10e5c
--- /dev/null
+++ b/js/browsers/browser.js
@@ -0,0 +1,539 @@
+var initPath = "recentdb://"
+var currentPath;
+var currentTask = undefined;
+var noteCardViewGrid = undefined;
+var notePath = []
+var wasNewNote = false
+var dontOpen = false;
+var currentNotePath = undefined
+const {
+ ipcRenderer,
+ remote,
+ app
+} = require('electron');
+const Store = require('electron-store');
+const store = new Store();
+var noteCacheStr = String(store.get("note_cache"))
+if (noteCacheStr == "undefined")
+ noteCacheStr = "{}"
+console.log("cache loaded " + noteCacheStr)
+
+var oldNotes = JSON.parse(noteCacheStr);
+var main = remote.require("./main.js");
+var SettingsHelper = require("./settings/settings_helper").SettingsHelper
+var settingsHelper = new SettingsHelper()
+var TextGetterTask = function (list) {
+ this.list = list;
+ this.current = 0;
+ this.continue = true;
+ this.stopAt = 50;
+}
+
+TextGetterTask.prototype.startList = function () {
+ this.getNext();
+}
+
+TextGetterTask.prototype.getNext = function () {
+ if (this.current >= this.stopAt) {
+ console.log("save cache ")
+ store.set("note_cache", JSON.stringify(oldNotes))
+ return;
+ }
+ if (this.list[this.current] instanceof Note) {
+ var opener = new NoteOpener(this.list[this.current])
+ var myTask = this;
+ var note = this.list[this.current]
+ var fast = false;
+ //should we go fast or slow refresh ?
+ for (var i = this.current; i < this.stopAt && i < this.list.length && i < oldNotes.length; i++) {
+ if (oldNotes[this.list[i].path] == undefined) {
+ fast = true;
+ break;
+ }
+ }
+ setTimeout(function () {
+ try {
+ opener.getMainTextMetadataAndPreviews(function (txt, metadata, previews) {
+ if (myTask.continue) {
+ if (txt != undefined)
+ note.text = txt.substring(0, 200);
+ if (metadata != undefined)
+ note.metadata = metadata;
+ note.previews = previews;
+ oldNotes[note.path] = note;
+ noteCardViewGrid.updateNote(note)
+ noteCardViewGrid.msnry.layout();
+
+ myTask.getNext();
+ }
+ });
+ } catch (error) {
+ console.log(error);
+ }
+ myTask.current++;
+ }, !fast ? 1000 : 100)
+
+ } else {
+ this.current++;
+ this.getNext();
+ }
+
+}
+
+var NewNoteCreationTask = function (callback) {
+ var path = currentPath;
+ if (path == initPath || path.startsWith("keyword://"))
+ path = main.getNotePath();
+ var fs = require('fs');
+ if (!fs.exists(path)) {
+ var mkdirp = require('mkdirp');
+ mkdirp.sync(path);
+ }
+
+ var fb = new FileBrowser(path);
+ console.log(path + " fefef")
+ var task = this;
+ fb.list(function (files) {
+ task.files = files;
+ var name = "untitled.sqd";
+ var sContinue = true;
+ var i = 1;
+ while (sContinue) {
+ sContinue = false
+ for (let file of files) {
+ if (file.name == name) {
+ sContinue = true;
+ i++;
+ name = "untitled " + i + ".sqd";
+ }
+ }
+ }
+ callback(path + "/" + name)
+
+ });
+}
+
+String.prototype.replaceAll = function (search, replacement) {
+ var target = this;
+ return target.replace(new RegExp(search, 'g'), replacement);
+};
+
+function openNote(notePath) {
+ currentNotePath = notePath
+ const electron = require('electron')
+ const remote = electron.remote;
+ const BrowserWindow = remote.BrowserWindow;
+ const path = require('path')
+ //var win = new BrowserWindow({ width: 800, height: 600 });
+ if (!hasLoadedOnce)
+ $(loadingView).fadeIn();
+ //$(browserElem).faceOut();
+ var rimraf = require('rimraf');
+ const tmp = path.join(main.getPath("temp"), "tmpquicknote");
+ rimraf(tmp, function () {
+ var fs = require('fs');
+
+ fs.mkdir(tmp, function (e) {
+ fs.readFile(__dirname + '/reader/reader.html', 'utf8', function (err, data) {
+ if (err) {
+ fs.rea
+ console.log("error ")
+ return console.log(err);
+ }
+ const index = path.join(tmp, 'reader.html');
+ fs.writeFileSync(index, data.replace(new RegExp('<!ROOTPATH>', 'g'), __dirname + '/'));
+ /* var size = remote.getCurrentWindow().getSize();
+ var pos = remote.getCurrentWindow().getPosition();
+ var win = new BrowserWindow({
+ width: size[0],
+ height: size[1],
+ x: pos[0],
+ y: pos[1],
+ frame: false
+ });
+ console.log("w " + remote.getCurrentWindow().getPosition()[0])
+ const url = require('url')
+ win.loadURL(url.format({
+ pathname: path.join(__dirname, 'tmp/reader.html'),
+ protocol: 'file:',
+ query: {
+ 'path': notePath
+ },
+ slashes: true
+ }))*/
+ const url = require('url')
+
+ if (!hasLoadedOnce) {
+ webview.setAttribute("src", url.format({
+ pathname: index,
+ protocol: 'file:',
+ query: {
+ 'path': notePath,
+ 'tmppath': tmp + "/"
+ },
+ slashes: true
+ }));
+ } else
+ webview.send('loadnote', notePath);
+ webview.style = "position:fixed; top:0px; left:0px; height:100%; width:100%; z-index:100; right:0; bottom:0;"
+ //to resize properly
+ hasLoadedOnce = true;
+ });
+
+
+ });
+
+ })
+}
+
+function onDragEnd(gg) {
+ console.log("ondragend")
+ dontOpen = true;
+}
+
+function refreshKeywords() {
+ var KeywordsDBManager = require("./keywords/keywords_db_manager").KeywordsDBManager;
+ var keywordsDBManager = new KeywordsDBManager(main.getNotePath() + "/quickdoc/keywords/" + main.getAppUid())
+ keywordsDBManager.getFlatenDB(function (error, data) {
+ var keywordsContainer = document.getElementById("keywords");
+ keywordsContainer.innerHTML = "";
+ var dataArray = []
+ for (let key in data) {
+ if (data[key].length == 0)
+ continue;
+ dataArray.push(key)
+ }
+ dataArray.sort(Utils.caseInsensitiveSrt)
+ for (let key of dataArray) {
+
+ var keywordElem = document.createElement("a");
+ keywordElem.classList.add("mdl-navigation__link")
+ keywordElem.innerHTML = key;
+ keywordElem.setAttribute("href", "");
+ keywordElem.onclick = function () {
+ list("keyword://" + key, false);
+ return false;
+ }
+ keywordsContainer.appendChild(keywordElem)
+ }
+ })
+}
+
+function searchInNotes(searching) {
+ resetGrid(false)
+ var settingsHelper = require("./settings/settings_helper").SettingsHelper
+ var SettingsHelper = new settingsHelper();
+ var Search = require("./browsers/search").Search
+ var browser = this;
+ notes = []
+ var callback = function () {
+
+ }
+ callback.update = function (note) {
+ console.log("found " + note.path)
+ note = new Note(note.title, note.text.substring(0, 200), note.path, note.metadata)
+ browser.noteCardViewGrid.addNote(note)
+ notes.push(note)
+
+ }
+ callback.onEnd = function (list) {
+ console.log("onEnd " + list.length)
+
+
+ }
+ search = new Search(searching, SettingsHelper.getNotePath(), callback)
+ search.start()
+
+}
+
+function resetGrid(discret) {
+ var grid = document.getElementById("page-content");
+ var scroll = 0;
+ if (discret)
+ scroll = document.getElementById("grid-container").scrollTop;
+ grid.innerHTML = "";
+ noteCardViewGrid = new NoteCardViewGrid(grid, discret, onDragEnd);
+ this.noteCardViewGrid = noteCardViewGrid;
+ noteCardViewGrid.onFolderClick(function (folder) {
+ list(folder.path)
+ })
+ noteCardViewGrid.onNoteClick(function (note) {
+ if (!dontOpen)
+ openNote(note.path)
+ dontOpen = false;
+ // var reader = new Writer(note,"");
+ // reader.extractNote()
+ })
+
+
+ noteCardViewGrid.onMenuClick(function (note) {
+ mNoteContextualDialog.show(note)
+ })
+}
+
+class ContextualDialog {
+ constructor() {
+ this.showDelete = true;
+ this.showArchive = true;
+ this.showPin = true;
+ this.dialog = document.querySelector('#contextual-dialog');
+ this.nameInput = this.dialog.querySelector('#name-input');
+ this.deleteButton = this.dialog.querySelector('.delete-button');
+ this.archiveButton = this.dialog.querySelector('#archive-button');
+ this.pinButton = this.dialog.querySelector('#pin-button');
+ this.cancel = this.dialog.querySelector('.cancel');
+ this.ok = this.dialog.querySelector('.ok');
+ var context = this;
+ this.cancel.onclick = function () {
+ context.dialog.close();
+ }
+ }
+
+ show() {
+ this.showDelete ? $(this.deleteButton).show() : $(this.deleteButton).hide();
+ this.showArchive ? $(this.archiveButton).show() : $(this.archiveButton).hide();
+ this.showPin ? $(this.pinButton).show() : $(this.pinButton).hide();
+ this.dialog.showModal();
+ this.nameInput.focus()
+ }
+}
+
+class NewFolderDialog extends ContextualDialog {
+ constructor() {
+ super();
+ this.showDelete = false;
+ this.showArchive = false;
+ this.showPin = false;
+ }
+
+ show() {
+ var context = this;
+
+ this.ok.onclick = function () {
+ var fb = new FileBrowser(currentPath);
+ fb.createFolder(context.nameInput.value, function () {
+ list(currentPath, true)
+ context.dialog.close();
+ })
+ }
+ super.show()
+
+ }
+}
+
+class NoteContextualDialog extends ContextualDialog {
+ constructor() {
+ super();
+ }
+
+ show(note) {
+ var context = this;
+ this.nameInput.value = note.title;
+ this.deleteButton.onclick = function () {
+ NoteUtils.deleteNote(note.path, function () {
+ context.dialog.close();
+ list(currentPath, true)
+ })
+ }
+ this.archiveButton.onclick = function () {
+ var db = new RecentDBManager(main.getNotePath() + "/quickdoc/recentdb/" + main.getAppUid())
+ db.removeFromDB(NoteUtils.getNoteRelativePath(main.getNotePath(), note.path), function () {
+ context.dialog.close();
+ list(currentPath, true)
+ });
+
+ }
+ if (note.isPinned == true) {
+ this.pinButton.innerHTML = "Unpin"
+ } else this.pinButton.innerHTML = "Pin"
+
+ this.pinButton.onclick = function () {
+ var db = new RecentDBManager(main.getNotePath() + "/quickdoc/recentdb/" + main.getAppUid())
+ if (note.isPinned == true)
+ db.unpin(NoteUtils.getNoteRelativePath(main.getNotePath(), note.path), function () {
+ context.dialog.close();
+ list(currentPath, true)
+ });
+
+ else
+ db.pin(NoteUtils.getNoteRelativePath(main.getNotePath(), note.path), function () {
+ context.dialog.close();
+ list(currentPath, true)
+ });
+ }
+ this.ok.onclick = function () {
+ NoteUtils.renameNote(note.path, context.nameInput.value + ".sqd", function () {
+ list(currentPath, true)
+ })
+
+ context.dialog.close();
+ }
+ super.show()
+
+ }
+}
+
+var mNoteContextualDialog = new NoteContextualDialog()
+var mNewFolderDialog = new NewFolderDialog()
+
+
+function list(pathToList, discret) {
+ if (pathToList == undefined)
+ pathToList = currentPath;
+ console.log("listing path " + pathToList);
+ currentPath = pathToList;
+ if (pathToList == settingsHelper.getNotePath() || pathToList == initPath || pathToList.startsWith("keyword://")) {
+ if (pathToList != settingsHelper.getNotePath()) {
+ $("#add-directory-button").hide()
+ } else
+ $("#add-directory-button").show()
+
+ $("#back_arrow").hide()
+ } else {
+ $("#back_arrow").show()
+ $("#add-directory-button").show()
+ }
+
+ resetGrid(discret);
+ var noteCardViewGrid = this.noteCardViewGrid
+ var notes = [];
+ notePath = [];
+
+ var fb = new FileBrowser(pathToList);
+ fb.list(function (files) {
+ if (currentTask != undefined)
+ currentTask.continue = false
+ if (files.length > 0) {
+ $("#emty-view").fadeOut("fast");
+ } else
+ $("#emty-view").fadeIn("fast");
+ for (let file of files) {
+ var filename = getFilenameFromPath(file.path);
+ if (file.isFile && filename.endsWith(".sqd")) {
+ var oldNote = oldNotes[file.path];
+
+ var noteTestTxt = new Note(stripExtensionFromName(filename), oldNote != undefined ? oldNote.text : "", file.path, oldNote != undefined ? oldNote.metadata : undefined, oldNote != undefined ? oldNote.previews : undefined);
+ noteTestTxt.isPinned = file.isPinned
+ notes.push(noteTestTxt)
+ } else if (!file.isFile) {
+
+ notes.push(file)
+ }
+ notePath.push(file.path)
+ }
+ noteCardViewGrid.setNotesAndFolders(notes)
+ if (discret) {
+ document.getElementById("grid-container").scrollTop = scroll;
+ console.log("scroll : " + scroll)
+
+ }
+ currentTask = new TextGetterTask(notes);
+ console.log("stopping and starting task")
+ currentTask.startList();
+
+ });
+
+}
+list(initPath)
+refreshKeywords();
+
+function minimize() {
+ remote.BrowserWindow.getFocusedWindow().minimize();
+}
+
+function maximize() {
+ if (remote.BrowserWindow.getFocusedWindow().isMaximized())
+ remote.BrowserWindow.getFocusedWindow().unmaximize();
+ else
+ remote.BrowserWindow.getFocusedWindow().maximize();
+}
+
+function closeW() {
+ remote.app.exit(0);
+ console.log("cloose")
+}
+
+function toggleSearch() {
+ $("#search-container").slideToggle();
+}
+
+
+main.setMergeListener(function () {
+ list(initPath, true)
+})
+
+document.getElementById("add-note-button").onclick = function () {
+ new NewNoteCreationTask(function (path) {
+ console.log("found " + path)
+ wasNewNote = true;
+ var db = new RecentDBManager(main.getNotePath() + "/quickdoc/recentdb/" + main.getAppUid())
+ db.addToDB(NoteUtils.getNoteRelativePath(main.getNotePath(), path));
+ openNote(path)
+ })
+}
+
+document.getElementById("add-directory-button").onclick = function () {
+ mNewFolderDialog.show();
+}
+
+
+document.getElementById("search-input").onkeydown = function (event) {
+ if (event.key === 'Enter') {
+ searchInNotes(this.value)
+ }
+}
+
+document.getElementById("back_arrow").addEventListener("click", function () {
+ list(getParentFolderFromPath(currentPath))
+});
+
+function getNotePath() {
+
+ return main.getNotePath()
+}
+
+function loadNextNotes() {
+ browser.noteCardViewGrid.addNext(15);
+ currentTask.stopAt += 15;
+ currentTask.getNext()
+}
+
+var browser = this
+document.getElementById("grid-container").onscroll = function () {
+ if (this.offsetHeight + this.scrollTop >= this.scrollHeight - 80) {
+ loadNextNotes();
+
+ }
+}
+var webview = document.getElementById("writer-webview")
+
+webview.addEventListener('ipc-message', event => {
+ if (event.channel == "exit") {
+ webview.style = "position:fixed; top:0px; left:0px; height:0px; width:0px; z-index:100; right:0; bottom:0;"
+ //$(browserElem).faceIn();
+ $("#no-drag-bar").hide()
+ if (wasNewNote)
+ list(currentPath, true)
+ else if (currentTask != undefined) {
+ var noteIndex
+ if ((noteIndex = notePath.indexOf(currentNotePath)) == -1) {
+ noteIndex = 0;
+ }
+ currentTask.current = noteIndex;
+ currentTask.getNext()
+ }
+ wasNewNote = false;
+ refreshKeywords()
+
+ } else if (event.channel == "loaded") {
+ $(loadingView).fadeOut();
+ $("#no-drag-bar").show()
+
+ }
+});
+var hasLoadedOnce = false
+webview.addEventListener('dom-ready', () => {
+ webview.openDevTools()
+})
+var loadingView = document.getElementById("loading-view")
+//var browserElem = document.getElementById("browser") \ No newline at end of file
diff --git a/js/browsers/design.css b/js/browsers/design.css
new file mode 100755
index 0000000..7a1285a
--- /dev/null
+++ b/js/browsers/design.css
@@ -0,0 +1,152 @@
+.demo-card-wide.mdl-card {
+ width: 202px;
+ min-height: 0px;
+ margin: 5px;
+ cursor: pointer;
+}
+
+.mdl-card__supporting-text{
+ padding-bottom: 0px !important;
+}
+
+.note-card-view :hover,
+.folder-card-view :hover {
+ background-color: rgb(230, 230, 230);
+ -webkit-transition: background-color 250ms linear;
+ -ms-transition: background-color 250ms linear;
+ transition: background-color 250ms linear;
+}
+
+.demo-card-wide>.mdl-card__title {
+ color: black;
+}
+
+.packery-drop-placeholder {
+ outline: 3px dashed #444;
+ outline-offset: -6px;
+ /* transition position changing */
+ -webkit-transition: -webkit-transform 0.2s;
+ transition: transform 0.2s;
+}
+
+
+/* highlight drag & drop */
+
+
+/* jQuery UI Draggable adds ui-draggable-dragging */
+
+.ui-draggable-dragging,
+.is-positioning-post-drag {
+ background: #C90;
+ z-index: 20000 !important;
+ /* keep dragged item on top */
+}
+
+.demo-card-wide>.mdl-card__menu {
+ color: #fff;
+}
+
+body {
+ background: #fafafa;
+ position: relative;
+}
+
+#page-content {
+ position: relative;
+ margin: 0 auto;
+}
+
+#grid-container {
+ margin: 0 auto;
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ overflow-y: auto;
+}
+
+.big-text {
+ font-size: 40px;
+}
+
+.medium-text {
+ font-size: 30px;
+}
+
+@media (min-width: 1314px) {
+ #grid-container {
+ max-width: 1074px;
+ left: calc(50% - 537px);
+ }
+}
+
+.card-title {
+ font-size: 24px;
+ font-weight: 300;
+ line-height: normal;
+ color: black;
+ margin: 0px;
+}
+
+.card-text {
+ line-height: initial;
+ margin-bottom: 10px;
+ margin-right: 20px;
+ word-wrap: break-word;
+ color: rgba(0,0,0,.87);
+
+}
+
+.card-title:hover {
+ background: none;
+}
+
+.card-text:hover {
+ background: none;
+}
+
+.mdl-layout__header {
+ -webkit-app-region: drag;
+}
+
+.mdl-layout__header .mdl-layout__drawer-button,
+.mdl-layout__header button,
+.mdl-layout__header .mdl-textfield {
+ -webkit-app-region: no-drag;
+}
+
+.folder-icon {
+ width: 50px;
+}
+
+.card-more-button {
+ right: 0px;
+ background: inherit !important;
+ position: absolute !important;
+}
+
+.keywords{
+ margin-bottom:16px;
+}
+
+.keyword {
+ margin-right: 3px;
+ margin-top: 3px;
+ padding: 3px;
+ background: #D2D2D2;
+ display: inline-block;
+}
+
+.card-rating{
+ margin-right:10px;
+ float:right;
+}
+
+.card-medias{
+ margin-left:-20px;
+ margin-right:-5px;
+ background: black;
+ border-radius: 2px;
+}
+.card-medias img{
+ width:100%;
+}
diff --git a/js/browsers/file-browser.js b/js/browsers/file-browser.js
new file mode 100755
index 0000000..3777106
--- /dev/null
+++ b/js/browsers/file-browser.js
@@ -0,0 +1,109 @@
+var fs = require("fs");
+const pathTool = require('path')
+var getParentFolderFromPath = require('path').dirname;
+var FileBrowser = function (path) {
+ this.path = path;
+}
+
+FileBrowser.prototype.createFolder = function (name, callback) {
+ fs.mkdir(pathTool.join(this.path, name), function (e) {
+ callback();
+ });
+
+}
+
+FileBrowser.prototype.list = function (callback) {
+ var {
+ ipcRenderer,
+ remote
+ } = require('electron');
+ var main = remote.require("./main.js");
+ var mainPath = main.getNotePath();
+
+ if (this.path == "recentdb://") {
+ console.log("getting recent")
+ var db = new RecentDBManager(mainPath + "/quickdoc/recentdb/" + main.getAppUid())
+ db.getFlatenDB(function (err, flaten, pin) {
+ console.log(JSON.stringify(flaten))
+ var files = [];
+ for (let filePath of pin) {
+ var filename = filePath;
+ filePath = mainPath + "/" + filePath
+ file = new File(filePath, true, filename);
+ file.isPinned = true;
+ files.push(file)
+ }
+ for (let filePath of flaten) {
+ if (pin.indexOf(filePath) != -1)
+ continue;
+ var filename = filePath;
+ filePath = mainPath + "/" + filePath
+ file = new File(filePath, true, filename);
+ files.push(file)
+ }
+ callback(files)
+ })
+ } else if (this.path.startsWith("keyword://")) {
+ console.log("getting keyword")
+ var KeywordsDBManager = require("./keywords/keywords_db_manager").KeywordsDBManager;
+ var keywordsDBManager = new KeywordsDBManager(main.getNotePath() + "/quickdoc/keywords/" + main.getAppUid())
+ var filebrowser = this;
+ keywordsDBManager.getFlatenDB(function (error, data) {
+ var files = [];
+ console.log("keyword " + filebrowser.path.substring("keyword://".length))
+ for (let filePath of data[filebrowser.path.substring("keyword://".length)]) {
+ var filename = filePath;
+ console.log("file " + filePath)
+
+ filePath = mainPath + "/" + filePath
+ file = new File(filePath, true, filename);
+ files.push(file)
+ }
+ callback(files)
+ })
+ } else {
+ fs.readdir(this.path, (err, dir) => {
+ //console.log(dir);
+ var files = [];
+ var dirs_in = [];
+ var files_in = [];
+ for (let filePath of dir) {
+ var filename = filePath;
+ if (filename == "quickdoc" || filename.startsWith("."))
+ continue;
+ filePath = this.path + "/" + filePath
+ var stat = fs.statSync(filePath);
+ file = new File(filePath, stat.isFile(), filename);
+ console.log(filePath)
+ if (stat.isFile())
+ files_in.push(file)
+ else
+ dirs_in.push(file)
+
+ }
+ files = files.concat(dirs_in)
+ files = files.concat(files_in)
+
+ callback(files)
+ });
+ }
+}
+
+var File = function (path, isFile, name, extension) {
+ this.path = path;
+ this.isFile = isFile;
+ this.name = name;
+ this.extension = extension;
+
+}
+File.prototype.getName = function () {
+ return getFilenameFromPath(this.path);
+}
+
+function getFilenameFromPath(path) {
+ return path.replace(/^.*[\\\/]/, '');
+}
+
+function stripExtensionFromName(name) {
+ return name.replace(/\.[^/.]+$/, "")
+} \ No newline at end of file
diff --git a/js/browsers/note.js b/js/browsers/note.js
new file mode 100755
index 0000000..a227c83
--- /dev/null
+++ b/js/browsers/note.js
@@ -0,0 +1,24 @@
+
+
+var Note = function(title, text, path, metadata, previews){
+ this.title = title;
+ this.text = text;
+ this.path = path;
+ this.previews = previews;
+ if(metadata == undefined){
+ this.metadata = new NoteMetadata();
+ this.metadata.creation_date = Date.now();
+ this.metadata.last_modification_date = this.metadata.creation_date;
+ }
+ else
+ this.metadata = metadata;
+
+}
+
+var NoteMetadata = function(){
+ this.creation_date = ""
+ this.last_modification_date = ""
+ this.keywords = []
+ this.rating = -1;
+}
+exports.Note = Note \ No newline at end of file
diff --git a/js/browsers/note_card_view.js b/js/browsers/note_card_view.js
new file mode 100755
index 0000000..9471a91
--- /dev/null
+++ b/js/browsers/note_card_view.js
@@ -0,0 +1,250 @@
+var NoteCardView = function (elem) {
+ this.elem = elem;
+ this.init();
+}
+NoteCardView.prototype.setNote = function (note) {
+ this.note = note;
+ if (note.title.indexOf("untitled") == 0)
+ this.cardTitleText.innerHTML = ""
+ else
+ this.cardTitleText.innerHTML = note.title;
+ var date = new Date(note.metadata.last_modification_date).toLocaleDateString();
+ this.cardText.innerHTML = note.text;
+ this.cardDate.innerHTML = date;
+ if(note.metadata.rating>0)
+ this.cardRating.innerHTML = note.metadata.rating+"★"
+ this.cardKeywords.innerHTML = "";
+ this.cardText.classList.remove("big-text")
+ this.cardText.classList.remove("medium-text")
+
+ if (note.text.length < 40 && this.cardTitleText.innerHTML == "")
+ this.cardText.classList.add("big-text")
+ else if (note.text.length < 100 && this.cardTitleText.innerHTML == "") {
+ this.cardText.classList.add("medium-text")
+
+ }
+ if (typeof note.metadata.keywords[Symbol.iterator] === 'function')
+ for (let keyword of note.metadata.keywords) {
+ console.log("keyword " + keyword)
+ keywordSpan = document.createElement('span');
+ keywordSpan.innerHTML = keyword;
+ keywordSpan.classList.add("keyword");
+ this.cardKeywords.appendChild(keywordSpan)
+ }
+ this.cardMedias.innerHTML = "";
+ if(note.previews != undefined)
+ for (let preview of note.previews) {
+ var img = document.createElement('img');
+ img.src = preview;
+ this.cardMedias.appendChild(img);
+ }
+
+}
+
+NoteCardView.prototype.init = function () {
+ this.elem.classList.add("mdl-card");
+ this.elem.classList.add("note-card-view");
+
+ this.menuButton = document.createElement('button');
+
+ this.menuButton.classList.add("mdl-button");
+
+ this.menuButton.classList.add("mdl-js-button");
+ this.menuButton.classList.add("mdl-button--icon");
+ this.menuButton.classList.add("card-more-button");
+
+ var menuButtonIcon = document.createElement('li');
+ menuButtonIcon.classList.add("material-icons");
+ menuButtonIcon.innerHTML = "more_vert";
+ this.menuButton.appendChild(menuButtonIcon);
+ this.elem.classList.add("mdl-shadow--2dp");
+ this.cardContent = document.createElement('div');
+ this.cardContent.classList.add("mdl-card__supporting-text");
+ this.cardContent.appendChild(this.menuButton)
+ this.cardText = document.createElement('div');
+ this.cardText.classList.add("card-text");
+
+ this.cardTitleText = document.createElement('h2');
+ this.cardTitleText.classList.add("card-title");
+ this.cardContent.appendChild(this.cardTitleText)
+ this.cardContent.appendChild(this.cardText)
+ this.cardRating = document.createElement('div');
+ this.cardRating.classList.add("card-rating");
+ this.cardContent.appendChild(this.cardRating)
+ this.cardDate = document.createElement('div');
+ this.cardDate.classList.add("card-date");
+ this.cardContent.appendChild(this.cardDate)
+
+ this.cardKeywords = document.createElement('div');
+ this.cardKeywords.classList.add("keywords");
+ this.cardContent.appendChild(this.cardKeywords)
+
+ this.cardMedias = document.createElement('div');
+ this.cardMedias.classList.add("card-medias");
+ this.cardContent.appendChild(this.cardMedias)
+
+ this.elem.appendChild(this.cardContent);
+
+}
+
+var Masonry = require('masonry-layout');
+var NoteCardViewGrid = function (elem, discret, dragCallback) {
+
+ this.elem = elem;
+ this.discret = discret;
+ this.init();
+ this.dragCallback = dragCallback;
+}
+
+
+
+
+NoteCardViewGrid.prototype.init = function () {
+ this.noteCards = [];
+ this.lastAdded = 0;
+ this.notes = []
+ this.msnry = new Masonry(this.elem, {
+ // options
+ itemSelector: '.demo-card-wide.mdl-card',
+ fitWidth: true,
+ columnWidth: 212,
+ transitionDuration: this.discret ? 0 : "0.6s",
+ animationOptions: {
+
+ queue: false,
+ isAnimated: false
+ },
+ });
+
+
+}
+
+NoteCardViewGrid.prototype.onFolderClick = function (callback) {
+ this.onFolderClick = callback;
+}
+
+NoteCardViewGrid.prototype.onNoteClick = function (callback) {
+ this.onNoteClick = callback;
+}
+
+NoteCardViewGrid.prototype.onMenuClick = function (callback) {
+ this.onMenuClick = callback;
+}
+
+
+NoteCardViewGrid.prototype.updateNote = function (note) {
+ for (var i = 0; i < this.noteCards.length; i++) {
+ var noteCard = this.noteCards[i];
+ if (noteCard.note.path == note.path) {
+ noteCard.setNote(note);
+ }
+ }
+}
+
+NoteCardViewGrid.prototype.setNotesAndFolders = function (notes) {
+ this.notes = notes;
+ this.noteCards = [];
+ this.lastAdded = 0;
+ this.addNext(45);
+}
+NoteCardViewGrid.prototype.addNote = function(note){
+ this.notes.push(note)
+ this.addNext(1);
+
+}
+NoteCardViewGrid.prototype.addNext = function (num) {
+ var lastAdded = this.lastAdded
+ for (i = this.lastAdded; i < this.notes.length && i < num + lastAdded; i++) {
+ var note = this.notes[i]
+ if (note instanceof Note) {
+ var noteElem = document.createElement("div");
+ noteElem.classList.add("demo-card-wide")
+ noteElem.classList.add("isotope-item")
+ var noteCard = new NoteCardView(noteElem);
+ noteCard.setNote(note);
+ noteElem.note = note;
+ this.noteCards.push(noteCard);
+ this.elem.appendChild(noteElem)
+ this.msnry.appended(noteElem)
+
+ $(noteElem).bind('click', {
+ note: note,
+ callback: this.onNoteClick
+ }, function (event) {
+ if (!$(this).hasClass('noclick')) {
+ var data = event.data;
+ data.callback(data.note)
+ }
+ });
+
+ $(noteCard.menuButton).bind('click', {
+ note: note,
+ callback: this.onMenuClick
+ }, function (event) {
+ if (!$(this).hasClass('noclick')) {
+ var data = event.data;
+ data.callback(data.note)
+ return false;
+ }
+ });
+ } else {
+ var folderElem = document.createElement("div");
+ folderElem.classList.add("demo-card-wide")
+ folderElem.classList.add("isotope-item")
+
+ $(folderElem).bind('click', {
+ folder: note,
+ callback: this.onFolderClick
+ }, function (event) {
+ if (!$(this).hasClass('noclick')) {
+ var data = event.data;
+ data.callback(data.folder)
+ }
+ });
+
+
+ var folderCard = new FolderView(folderElem);
+ folderCard.setFolder(note);
+ this.elem.appendChild(folderElem)
+ this.msnry.appended(folderElem)
+ }
+ this.lastAdded = i + 1;
+ }
+
+ // make all grid-items draggable
+ var grid = this;
+
+ this.msnry.layout();
+ this.msnry.options.transitionDuration = "0.6s" //restore even when discret
+
+}
+
+
+
+var FolderView = function (elem) {
+ this.elem = elem;
+ this.init();
+}
+FolderView.prototype.setFolder = function (folder) {
+ this.folder = folder;
+ this.cardTitle.innerHTML = folder.getName();
+}
+
+FolderView.prototype.init = function () {
+ this.elem.classList.add("mdl-card");
+ this.elem.classList.add("folder-card-view");
+ this.elem.classList.add("mdl-shadow--2dp");
+ this.cardContent = document.createElement('div');
+ this.cardContent.classList.add("mdl-card__supporting-text");
+ this.img = document.createElement('img');
+ this.img.classList.add("folder-icon")
+ this.img.src = "img/directory.png";
+ this.cardContent.appendChild(this.img);
+
+ this.cardTitle = document.createElement('h2');
+ this.cardTitle.classList.add("card-title");
+ this.cardTitle.style = "display:inline;margin-left:5px;"
+ this.cardContent.appendChild(this.cardTitle);
+ this.elem.appendChild(this.cardContent);
+
+} \ No newline at end of file
diff --git a/js/browsers/search.js b/js/browsers/search.js
new file mode 100755
index 0000000..cfefd26
--- /dev/null
+++ b/js/browsers/search.js
@@ -0,0 +1,86 @@
+var fs = require("fs");
+var Search = function (keyword, path, callback) {
+ this.keyword = keyword.toLowerCase();
+ this.callback = callback;
+ this.path = path
+}
+
+Search.prototype.start = function () {
+ this.fileList = [];
+ this.toVisit = [];
+ this.result = [];
+ var search = this;
+
+ this.recursiveVisit(this.path, function () {
+ if (search.fileList.length > 0) {
+ search.searchInFiles(search.callback);
+ }
+ })
+}
+Search.prototype.searchInFiles = function (callback) {
+ var search = this;
+ if (search.fileList.length > 0) {
+ this.searchInFile(search.fileList.pop(), function () {
+ search.searchInFiles(callback)
+ })
+ } else
+ callback.onEnd(this.result)
+
+}
+
+function getFilenameFromPath(path) {
+ return path.replace(/^.*[\\\/]/, '');
+}
+
+function stripExtensionFromName(name) {
+ return name.replace(/\.[^/.]+$/, "")
+}
+Search.prototype.searchInFile = function (filePath, callback) {
+ console.log("searchInFile " + filePath)
+ var NoteOpener = require("../note/note-opener").NoteOpener
+ var Note = require("./note").Note
+
+ var opener = new NoteOpener(new Note(filePath, "", filePath, undefined))
+ var search = this;
+ try {
+ console.log("opening")
+
+ opener.getMainTextAndMetadata(function (txt, metadata) {
+ var fileName = stripExtensionFromName(getFilenameFromPath(filePath));
+ console.log("opened")
+ if (fileName.toLowerCase().indexOf(search.keyword) >= 0 || txt !== undefined && txt.toLowerCase().indexOf(search.keyword) >= 0 || metadata !== undefined && metadata.keywords.indexOf(search.keyword) >= 0) {
+ search.result.push(new Note(fileName, txt, filePath, metadata))
+ search.callback.update(new Note(stripExtensionFromName(getFilenameFromPath(filePath)), txt, filePath, metadata))
+ console.log("found in " + filePath)
+
+ }
+ callback()
+ });
+ } catch (error) {
+ console.log(error);
+ callback()
+ }
+}
+Search.prototype.recursiveVisit = function (path, callback) {
+ var search = this;
+ console.log("visiting " + path)
+ fs.readdir(path, (err, dir) => {
+
+ if (!err)
+ for (var filePath of dir) {
+ filePath = path + "/" + filePath;
+ var stat = fs.statSync(filePath);
+
+ if (!stat.isFile()) {
+ search.toVisit.push(filePath)
+ } else if (filePath.endsWith(".sqd")) {
+ search.fileList.push(filePath)
+ }
+ }
+ if (search.toVisit.length > 0) {
+ search.recursiveVisit(search.toVisit.pop(), callback)
+ } else
+ callback()
+ });
+}
+exports.Search = Search \ No newline at end of file
diff --git a/js/libs/material.js b/js/libs/material.js
new file mode 100755
index 0000000..7892213
--- /dev/null
+++ b/js/libs/material.js
@@ -0,0 +1,4010 @@
+;
+(function () {
+ "use strict";
+
+ /**
+ * @license
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /**
+ * A component handler interface using the revealing module design pattern.
+ * More details on this design pattern here:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @author Jason Mayes.
+ */
+ /* exported componentHandler */
+
+ // Pre-defining the componentHandler interface, for closure documentation and
+ // static verification.
+ var componentHandler = {
+ /**
+ * Searches existing DOM for elements of our component type and upgrades them
+ * if they have not already been upgraded.
+ *
+ * @param {string=} optJsClass the programatic name of the element class we
+ * need to create a new instance of.
+ * @param {string=} optCssClass the name of the CSS class elements of this
+ * type will have.
+ */
+ upgradeDom: function (optJsClass, optCssClass) {},
+ /**
+ * Upgrades a specific element rather than all in the DOM.
+ *
+ * @param {!Element} element The element we wish to upgrade.
+ * @param {string=} optJsClass Optional name of the class we want to upgrade
+ * the element to.
+ */
+ upgradeElement: function (element, optJsClass) {},
+ /**
+ * Upgrades a specific list of elements rather than all in the DOM.
+ *
+ * @param {!Element|!Array<!Element>|!NodeList|!HTMLCollection} elements
+ * The elements we wish to upgrade.
+ */
+ upgradeElements: function (elements) {},
+ /**
+ * Upgrades all registered components found in the current DOM. This is
+ * automatically called on window load.
+ */
+ upgradeAllRegistered: function () {},
+ /**
+ * Allows user to be alerted to any upgrades that are performed for a given
+ * component type
+ *
+ * @param {string} jsClass The class name of the MDL component we wish
+ * to hook into for any upgrades performed.
+ * @param {function(!HTMLElement)} callback The function to call upon an
+ * upgrade. This function should expect 1 parameter - the HTMLElement which
+ * got upgraded.
+ */
+ registerUpgradedCallback: function (jsClass, callback) {},
+ /**
+ * Registers a class for future use and attempts to upgrade existing DOM.
+ *
+ * @param {componentHandler.ComponentConfigPublic} config the registration configuration
+ */
+ register: function (config) {},
+ /**
+ * Downgrade either a given node, an array of nodes, or a NodeList.
+ *
+ * @param {!Node|!Array<!Node>|!NodeList} nodes
+ */
+ downgradeElements: function (nodes) {}
+ };
+
+ componentHandler = (function () {
+ 'use strict';
+
+ /** @type {!Array<componentHandler.ComponentConfig>} */
+ var registeredComponents_ = [];
+
+ /** @type {!Array<componentHandler.Component>} */
+ var createdComponents_ = [];
+
+ var componentConfigProperty_ = 'mdlComponentConfigInternal_';
+
+ /**
+ * Searches registered components for a class we are interested in using.
+ * Optionally replaces a match with passed object if specified.
+ *
+ * @param {string} name The name of a class we want to use.
+ * @param {componentHandler.ComponentConfig=} optReplace Optional object to replace match with.
+ * @return {!Object|boolean}
+ * @private
+ */
+ function findRegisteredClass_(name, optReplace) {
+ for (var i = 0; i < registeredComponents_.length; i++) {
+ if (registeredComponents_[i].className === name) {
+ if (typeof optReplace !== 'undefined') {
+ registeredComponents_[i] = optReplace;
+ }
+ return registeredComponents_[i];
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns an array of the classNames of the upgraded classes on the element.
+ *
+ * @param {!Element} element The element to fetch data from.
+ * @return {!Array<string>}
+ * @private
+ */
+ function getUpgradedListOfElement_(element) {
+ var dataUpgraded = element.getAttribute('data-upgraded');
+ // Use `['']` as default value to conform the `,name,name...` style.
+ return dataUpgraded === null ? [''] : dataUpgraded.split(',');
+ }
+
+ /**
+ * Returns true if the given element has already been upgraded for the given
+ * class.
+ *
+ * @param {!Element} element The element we want to check.
+ * @param {string} jsClass The class to check for.
+ * @returns {boolean}
+ * @private
+ */
+ function isElementUpgraded_(element, jsClass) {
+ var upgradedList = getUpgradedListOfElement_(element);
+ return upgradedList.indexOf(jsClass) !== -1;
+ }
+
+ /**
+ * Create an event object.
+ *
+ * @param {string} eventType The type name of the event.
+ * @param {boolean} bubbles Whether the event should bubble up the DOM.
+ * @param {boolean} cancelable Whether the event can be canceled.
+ * @returns {!Event}
+ */
+ function createEvent_(eventType, bubbles, cancelable) {
+ if ('CustomEvent' in window && typeof window.CustomEvent === 'function') {
+ return new CustomEvent(eventType, {
+ bubbles: bubbles,
+ cancelable: cancelable
+ });
+ } else {
+ var ev = document.createEvent('Events');
+ ev.initEvent(eventType, bubbles, cancelable);
+ return ev;
+ }
+ }
+
+ /**
+ * Searches existing DOM for elements of our component type and upgrades them
+ * if they have not already been upgraded.
+ *
+ * @param {string=} optJsClass the programatic name of the element class we
+ * need to create a new instance of.
+ * @param {string=} optCssClass the name of the CSS class elements of this
+ * type will have.
+ */
+ function upgradeDomInternal(optJsClass, optCssClass) {
+ if (typeof optJsClass === 'undefined' &&
+ typeof optCssClass === 'undefined') {
+ for (var i = 0; i < registeredComponents_.length; i++) {
+ upgradeDomInternal(registeredComponents_[i].className,
+ registeredComponents_[i].cssClass);
+ }
+ } else {
+ var jsClass = /** @type {string} */ (optJsClass);
+ if (typeof optCssClass === 'undefined') {
+ var registeredClass = findRegisteredClass_(jsClass);
+ if (registeredClass) {
+ optCssClass = registeredClass.cssClass;
+ }
+ }
+
+ var elements = document.querySelectorAll('.' + optCssClass);
+ for (var n = 0; n < elements.length; n++) {
+ upgradeElementInternal(elements[n], jsClass);
+ }
+ }
+ }
+
+ /**
+ * Upgrades a specific element rather than all in the DOM.
+ *
+ * @param {!Element} element The element we wish to upgrade.
+ * @param {string=} optJsClass Optional name of the class we want to upgrade
+ * the element to.
+ */
+ function upgradeElementInternal(element, optJsClass) {
+ // Verify argument type.
+ if (!(typeof element === 'object' && element instanceof Element)) {
+ throw new Error('Invalid argument provided to upgrade MDL element.');
+ }
+ // Allow upgrade to be canceled by canceling emitted event.
+ var upgradingEv = createEvent_('mdl-componentupgrading', true, true);
+ element.dispatchEvent(upgradingEv);
+ if (upgradingEv.defaultPrevented) {
+ return;
+ }
+
+ var upgradedList = getUpgradedListOfElement_(element);
+ var classesToUpgrade = [];
+ // If jsClass is not provided scan the registered components to find the
+ // ones matching the element's CSS classList.
+ if (!optJsClass) {
+ var classList = element.classList;
+ registeredComponents_.forEach(function (component) {
+ // Match CSS & Not to be upgraded & Not upgraded.
+ if (classList.contains(component.cssClass) &&
+ classesToUpgrade.indexOf(component) === -1 &&
+ !isElementUpgraded_(element, component.className)) {
+ classesToUpgrade.push(component);
+ }
+ });
+ } else if (!isElementUpgraded_(element, optJsClass)) {
+ classesToUpgrade.push(findRegisteredClass_(optJsClass));
+ }
+
+ // Upgrade the element for each classes.
+ for (var i = 0, n = classesToUpgrade.length, registeredClass; i < n; i++) {
+ registeredClass = classesToUpgrade[i];
+ if (registeredClass) {
+ // Mark element as upgraded.
+ upgradedList.push(registeredClass.className);
+ element.setAttribute('data-upgraded', upgradedList.join(','));
+ var instance = new registeredClass.classConstructor(element);
+ instance[componentConfigProperty_] = registeredClass;
+ createdComponents_.push(instance);
+ // Call any callbacks the user has registered with this component type.
+ for (var j = 0, m = registeredClass.callbacks.length; j < m; j++) {
+ registeredClass.callbacks[j](element);
+ }
+
+ if (registeredClass.widget) {
+ // Assign per element instance for control over API
+ element[registeredClass.className] = instance;
+ }
+ } else {
+ throw new Error(
+ 'Unable to find a registered component for the given class.');
+ }
+
+ var upgradedEv = createEvent_('mdl-componentupgraded', true, false);
+ element.dispatchEvent(upgradedEv);
+ }
+ }
+
+ /**
+ * Upgrades a specific list of elements rather than all in the DOM.
+ *
+ * @param {!Element|!Array<!Element>|!NodeList|!HTMLCollection} elements
+ * The elements we wish to upgrade.
+ */
+ function upgradeElementsInternal(elements) {
+ if (!Array.isArray(elements)) {
+ if (elements instanceof Element) {
+ elements = [elements];
+ } else {
+ elements = Array.prototype.slice.call(elements);
+ }
+ }
+ for (var i = 0, n = elements.length, element; i < n; i++) {
+ element = elements[i];
+ if (element instanceof HTMLElement) {
+ upgradeElementInternal(element);
+ if (element.children.length > 0) {
+ upgradeElementsInternal(element.children);
+ }
+ }
+ }
+ }
+
+ /**
+ * Registers a class for future use and attempts to upgrade existing DOM.
+ *
+ * @param {componentHandler.ComponentConfigPublic} config
+ */
+ function registerInternal(config) {
+ // In order to support both Closure-compiled and uncompiled code accessing
+ // this method, we need to allow for both the dot and array syntax for
+ // property access. You'll therefore see the `foo.bar || foo['bar']`
+ // pattern repeated across this method.
+ var widgetMissing = (typeof config.widget === 'undefined' &&
+ typeof config['widget'] === 'undefined');
+ var widget = true;
+
+ if (!widgetMissing) {
+ widget = config.widget || config['widget'];
+ }
+
+ var newConfig = /** @type {componentHandler.ComponentConfig} */ ({
+ classConstructor: config.constructor || config['constructor'],
+ className: config.classAsString || config['classAsString'],
+ cssClass: config.cssClass || config['cssClass'],
+ widget: widget,
+ callbacks: []
+ });
+
+ registeredComponents_.forEach(function (item) {
+ if (item.cssClass === newConfig.cssClass) {
+ throw new Error('The provided cssClass has already been registered: ' + item.cssClass);
+ }
+ if (item.className === newConfig.className) {
+ throw new Error('The provided className has already been registered');
+ }
+ });
+
+ if (config.constructor.prototype
+ .hasOwnProperty(componentConfigProperty_)) {
+ throw new Error(
+ 'MDL component classes must not have ' + componentConfigProperty_ +
+ ' defined as a property.');
+ }
+
+ var found = findRegisteredClass_(config.classAsString, newConfig);
+
+ if (!found) {
+ registeredComponents_.push(newConfig);
+ }
+ }
+
+ /**
+ * Allows user to be alerted to any upgrades that are performed for a given
+ * component type
+ *
+ * @param {string} jsClass The class name of the MDL component we wish
+ * to hook into for any upgrades performed.
+ * @param {function(!HTMLElement)} callback The function to call upon an
+ * upgrade. This function should expect 1 parameter - the HTMLElement which
+ * got upgraded.
+ */
+ function registerUpgradedCallbackInternal(jsClass, callback) {
+ var regClass = findRegisteredClass_(jsClass);
+ if (regClass) {
+ regClass.callbacks.push(callback);
+ }
+ }
+
+ /**
+ * Upgrades all registered components found in the current DOM. This is
+ * automatically called on window load.
+ */
+ function upgradeAllRegisteredInternal() {
+ for (var n = 0; n < registeredComponents_.length; n++) {
+ upgradeDomInternal(registeredComponents_[n].className);
+ }
+ }
+
+ /**
+ * Check the component for the downgrade method.
+ * Execute if found.
+ * Remove component from createdComponents list.
+ *
+ * @param {?componentHandler.Component} component
+ */
+ function deconstructComponentInternal(component) {
+ if (component) {
+ var componentIndex = createdComponents_.indexOf(component);
+ createdComponents_.splice(componentIndex, 1);
+
+ var upgrades = component.element_.getAttribute('data-upgraded').split(',');
+ var componentPlace = upgrades.indexOf(component[componentConfigProperty_].classAsString);
+ upgrades.splice(componentPlace, 1);
+ component.element_.setAttribute('data-upgraded', upgrades.join(','));
+
+ var ev = createEvent_('mdl-componentdowngraded', true, false);
+ component.element_.dispatchEvent(ev);
+ }
+ }
+
+ /**
+ * Downgrade either a given node, an array of nodes, or a NodeList.
+ *
+ * @param {!Node|!Array<!Node>|!NodeList} nodes
+ */
+ function downgradeNodesInternal(nodes) {
+ /**
+ * Auxiliary function to downgrade a single node.
+ * @param {!Node} node the node to be downgraded
+ */
+ var downgradeNode = function (node) {
+ createdComponents_.filter(function (item) {
+ return item.element_ === node;
+ }).forEach(deconstructComponentInternal);
+ };
+ if (nodes instanceof Array || nodes instanceof NodeList) {
+ for (var n = 0; n < nodes.length; n++) {
+ downgradeNode(nodes[n]);
+ }
+ } else if (nodes instanceof Node) {
+ downgradeNode(nodes);
+ } else {
+ throw new Error('Invalid argument provided to downgrade MDL nodes.');
+ }
+ }
+
+ // Now return the functions that should be made public with their publicly
+ // facing names...
+ return {
+ upgradeDom: upgradeDomInternal,
+ upgradeElement: upgradeElementInternal,
+ upgradeElements: upgradeElementsInternal,
+ upgradeAllRegistered: upgradeAllRegisteredInternal,
+ registerUpgradedCallback: registerUpgradedCallbackInternal,
+ register: registerInternal,
+ downgradeElements: downgradeNodesInternal
+ };
+ })();
+
+ /**
+ * Describes the type of a registered component type managed by
+ * componentHandler. Provided for benefit of the Closure compiler.
+ *
+ * @typedef {{
+ * constructor: Function,
+ * classAsString: string,
+ * cssClass: string,
+ * widget: (string|boolean|undefined)
+ * }}
+ */
+ componentHandler.ComponentConfigPublic; // jshint ignore:line
+
+ /**
+ * Describes the type of a registered component type managed by
+ * componentHandler. Provided for benefit of the Closure compiler.
+ *
+ * @typedef {{
+ * constructor: !Function,
+ * className: string,
+ * cssClass: string,
+ * widget: (string|boolean),
+ * callbacks: !Array<function(!HTMLElement)>
+ * }}
+ */
+ componentHandler.ComponentConfig; // jshint ignore:line
+
+ /**
+ * Created component (i.e., upgraded element) type as managed by
+ * componentHandler. Provided for benefit of the Closure compiler.
+ *
+ * @typedef {{
+ * element_: !HTMLElement,
+ * className: string,
+ * classAsString: string,
+ * cssClass: string,
+ * widget: string
+ * }}
+ */
+ componentHandler.Component; // jshint ignore:line
+
+ // Export all symbols, for the benefit of Closure compiler.
+ // No effect on uncompiled code.
+ componentHandler['upgradeDom'] = componentHandler.upgradeDom;
+ componentHandler['upgradeElement'] = componentHandler.upgradeElement;
+ componentHandler['upgradeElements'] = componentHandler.upgradeElements;
+ componentHandler['upgradeAllRegistered'] =
+ componentHandler.upgradeAllRegistered;
+ componentHandler['registerUpgradedCallback'] =
+ componentHandler.registerUpgradedCallback;
+ componentHandler['register'] = componentHandler.register;
+ componentHandler['downgradeElements'] = componentHandler.downgradeElements;
+ window.componentHandler = componentHandler;
+ window['componentHandler'] = componentHandler;
+
+ window.addEventListener('load', function () {
+ 'use strict';
+
+ /**
+ * Performs a "Cutting the mustard" test. If the browser supports the features
+ * tested, adds a mdl-js class to the <html> element. It then upgrades all MDL
+ * components requiring JavaScript.
+ */
+ if ('classList' in document.createElement('div') &&
+ 'querySelector' in document &&
+ 'addEventListener' in window && Array.prototype.forEach) {
+ document.documentElement.classList.add('mdl-js');
+ componentHandler.upgradeAllRegistered();
+ } else {
+ /**
+ * Dummy function to avoid JS errors.
+ */
+ componentHandler.upgradeElement = function () {};
+ /**
+ * Dummy function to avoid JS errors.
+ */
+ componentHandler.register = function () {};
+ }
+ });
+
+ // Source: https://github.com/darius/requestAnimationFrame/blob/master/requestAnimationFrame.js
+ // Adapted from https://gist.github.com/paulirish/1579671 which derived from
+ // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
+ // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
+ // requestAnimationFrame polyfill by Erik Möller.
+ // Fixes from Paul Irish, Tino Zijdel, Andrew Mao, Klemen Slavič, Darius Bacon
+ // MIT license
+ if (!Date.now) {
+ /**
+ * Date.now polyfill.
+ * @return {number} the current Date
+ */
+ Date.now = function () {
+ return new Date().getTime();
+ };
+ Date['now'] = Date.now;
+ }
+ var vendors = [
+ 'webkit',
+ 'moz'
+ ];
+ for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) {
+ var vp = vendors[i];
+ window.requestAnimationFrame = window[vp + 'RequestAnimationFrame'];
+ window.cancelAnimationFrame = window[vp + 'CancelAnimationFrame'] || window[vp + 'CancelRequestAnimationFrame'];
+ window['requestAnimationFrame'] = window.requestAnimationFrame;
+ window['cancelAnimationFrame'] = window.cancelAnimationFrame;
+ }
+ if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) || !window.requestAnimationFrame || !window.cancelAnimationFrame) {
+ var lastTime = 0;
+ /**
+ * requestAnimationFrame polyfill.
+ * @param {!Function} callback the callback function.
+ */
+ window.requestAnimationFrame = function (callback) {
+ var now = Date.now();
+ var nextTime = Math.max(lastTime + 16, now);
+ return setTimeout(function () {
+ callback(lastTime = nextTime);
+ }, nextTime - now);
+ };
+ window.cancelAnimationFrame = clearTimeout;
+ window['requestAnimationFrame'] = window.requestAnimationFrame;
+ window['cancelAnimationFrame'] = window.cancelAnimationFrame;
+ }
+ /**
+ * @license
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /**
+ * Class constructor for Button MDL component.
+ * Implements MDL component design pattern defined at:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @param {HTMLElement} element The element that will be upgraded.
+ */
+ var MaterialButton = function MaterialButton(element) {
+ this.element_ = element;
+ // Initialize instance.
+ this.init();
+ };
+ window['MaterialButton'] = MaterialButton;
+ /**
+ * Store constants in one place so they can be updated easily.
+ *
+ * @enum {string | number}
+ * @private
+ */
+ MaterialButton.prototype.Constant_ = {};
+ /**
+ * Store strings for class names defined by this component that are used in
+ * JavaScript. This allows us to simply change it in one place should we
+ * decide to modify at a later date.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialButton.prototype.CssClasses_ = {
+ RIPPLE_EFFECT: 'mdl-js-ripple-effect',
+ RIPPLE_CONTAINER: 'mdl-button__ripple-container',
+ RIPPLE: 'mdl-ripple'
+ };
+ /**
+ * Handle blur of element.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialButton.prototype.blurHandler_ = function (event) {
+ if (event) {
+ this.element_.blur();
+ }
+ };
+ // Public methods.
+ /**
+ * Disable button.
+ *
+ * @public
+ */
+ MaterialButton.prototype.disable = function () {
+ this.element_.disabled = true;
+ };
+ MaterialButton.prototype['disable'] = MaterialButton.prototype.disable;
+ /**
+ * Enable button.
+ *
+ * @public
+ */
+ MaterialButton.prototype.enable = function () {
+ this.element_.disabled = false;
+ };
+ MaterialButton.prototype['enable'] = MaterialButton.prototype.enable;
+ /**
+ * Initialize element.
+ */
+ MaterialButton.prototype.init = function () {
+ if (this.element_) {
+ if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {
+ var rippleContainer = document.createElement('span');
+ rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER);
+ this.rippleElement_ = document.createElement('span');
+ this.rippleElement_.classList.add(this.CssClasses_.RIPPLE);
+ rippleContainer.appendChild(this.rippleElement_);
+ this.boundRippleBlurHandler = this.blurHandler_.bind(this);
+ this.rippleElement_.addEventListener('mouseup', this.boundRippleBlurHandler);
+ this.element_.appendChild(rippleContainer);
+ }
+ this.boundButtonBlurHandler = this.blurHandler_.bind(this);
+ this.element_.addEventListener('mouseup', this.boundButtonBlurHandler);
+ this.element_.addEventListener('mouseleave', this.boundButtonBlurHandler);
+ }
+ };
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ componentHandler.register({
+ constructor: MaterialButton,
+ classAsString: 'MaterialButton',
+ cssClass: 'mdl-js-button',
+ widget: true
+ });
+ /**
+ * @license
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /**
+ * Class constructor for Checkbox MDL component.
+ * Implements MDL component design pattern defined at:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @constructor
+ * @param {HTMLElement} element The element that will be upgraded.
+ */
+ var MaterialCheckbox = function MaterialCheckbox(element) {
+ this.element_ = element;
+ // Initialize instance.
+ this.init();
+ };
+ window['MaterialCheckbox'] = MaterialCheckbox;
+ /**
+ * Store constants in one place so they can be updated easily.
+ *
+ * @enum {string | number}
+ * @private
+ */
+ MaterialCheckbox.prototype.Constant_ = {
+ TINY_TIMEOUT: 0.001
+ };
+ /**
+ * Store strings for class names defined by this component that are used in
+ * JavaScript. This allows us to simply change it in one place should we
+ * decide to modify at a later date.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialCheckbox.prototype.CssClasses_ = {
+ INPUT: 'mdl-checkbox__input',
+ BOX_OUTLINE: 'mdl-checkbox__box-outline',
+ FOCUS_HELPER: 'mdl-checkbox__focus-helper',
+ TICK_OUTLINE: 'mdl-checkbox__tick-outline',
+ RIPPLE_EFFECT: 'mdl-js-ripple-effect',
+ RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
+ RIPPLE_CONTAINER: 'mdl-checkbox__ripple-container',
+ RIPPLE_CENTER: 'mdl-ripple--center',
+ RIPPLE: 'mdl-ripple',
+ IS_FOCUSED: 'is-focused',
+ IS_DISABLED: 'is-disabled',
+ IS_CHECKED: 'is-checked',
+ IS_UPGRADED: 'is-upgraded'
+ };
+ /**
+ * Handle change of state.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialCheckbox.prototype.onChange_ = function (event) {
+ this.updateClasses_();
+ };
+ /**
+ * Handle focus of element.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialCheckbox.prototype.onFocus_ = function (event) {
+ this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
+ };
+ /**
+ * Handle lost focus of element.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialCheckbox.prototype.onBlur_ = function (event) {
+ this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
+ };
+ /**
+ * Handle mouseup.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialCheckbox.prototype.onMouseUp_ = function (event) {
+ this.blur_();
+ };
+ /**
+ * Handle class updates.
+ *
+ * @private
+ */
+ MaterialCheckbox.prototype.updateClasses_ = function () {
+ this.checkDisabled();
+ this.checkToggleState();
+ };
+ /**
+ * Add blur.
+ *
+ * @private
+ */
+ MaterialCheckbox.prototype.blur_ = function () {
+ // TODO: figure out why there's a focus event being fired after our blur,
+ // so that we can avoid this hack.
+ window.setTimeout(function () {
+ this.inputElement_.blur();
+ }.bind(this), this.Constant_.TINY_TIMEOUT);
+ };
+ // Public methods.
+ /**
+ * Check the inputs toggle state and update display.
+ *
+ * @public
+ */
+ MaterialCheckbox.prototype.checkToggleState = function () {
+ if (this.inputElement_.checked) {
+ this.element_.classList.add(this.CssClasses_.IS_CHECKED);
+ } else {
+ this.element_.classList.remove(this.CssClasses_.IS_CHECKED);
+ }
+ };
+ MaterialCheckbox.prototype['checkToggleState'] = MaterialCheckbox.prototype.checkToggleState;
+ /**
+ * Check the inputs disabled state and update display.
+ *
+ * @public
+ */
+ MaterialCheckbox.prototype.checkDisabled = function () {
+ if (this.inputElement_.disabled) {
+ this.element_.classList.add(this.CssClasses_.IS_DISABLED);
+ } else {
+ this.element_.classList.remove(this.CssClasses_.IS_DISABLED);
+ }
+ };
+ MaterialCheckbox.prototype['checkDisabled'] = MaterialCheckbox.prototype.checkDisabled;
+ /**
+ * Disable checkbox.
+ *
+ * @public
+ */
+ MaterialCheckbox.prototype.disable = function () {
+ this.inputElement_.disabled = true;
+ this.updateClasses_();
+ };
+ MaterialCheckbox.prototype['disable'] = MaterialCheckbox.prototype.disable;
+ /**
+ * Enable checkbox.
+ *
+ * @public
+ */
+ MaterialCheckbox.prototype.enable = function () {
+ this.inputElement_.disabled = false;
+ this.updateClasses_();
+ };
+ MaterialCheckbox.prototype['enable'] = MaterialCheckbox.prototype.enable;
+ /**
+ * Check checkbox.
+ *
+ * @public
+ */
+ MaterialCheckbox.prototype.check = function () {
+ this.inputElement_.checked = true;
+ this.updateClasses_();
+ };
+ MaterialCheckbox.prototype['check'] = MaterialCheckbox.prototype.check;
+ /**
+ * Uncheck checkbox.
+ *
+ * @public
+ */
+ MaterialCheckbox.prototype.uncheck = function () {
+ this.inputElement_.checked = false;
+ this.updateClasses_();
+ };
+ MaterialCheckbox.prototype['uncheck'] = MaterialCheckbox.prototype.uncheck;
+ /**
+ * Initialize element.
+ */
+ MaterialCheckbox.prototype.init = function () {
+ if (this.element_) {
+ this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT);
+ var boxOutline = document.createElement('span');
+ boxOutline.classList.add(this.CssClasses_.BOX_OUTLINE);
+ var tickContainer = document.createElement('span');
+ tickContainer.classList.add(this.CssClasses_.FOCUS_HELPER);
+ var tickOutline = document.createElement('span');
+ tickOutline.classList.add(this.CssClasses_.TICK_OUTLINE);
+ boxOutline.appendChild(tickOutline);
+ this.element_.appendChild(tickContainer);
+ this.element_.appendChild(boxOutline);
+ if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {
+ this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
+ this.rippleContainerElement_ = document.createElement('span');
+ this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER);
+ this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT);
+ this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);
+ this.boundRippleMouseUp = this.onMouseUp_.bind(this);
+ this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp);
+ var ripple = document.createElement('span');
+ ripple.classList.add(this.CssClasses_.RIPPLE);
+ this.rippleContainerElement_.appendChild(ripple);
+ this.element_.appendChild(this.rippleContainerElement_);
+ }
+ this.boundInputOnChange = this.onChange_.bind(this);
+ this.boundInputOnFocus = this.onFocus_.bind(this);
+ this.boundInputOnBlur = this.onBlur_.bind(this);
+ this.boundElementMouseUp = this.onMouseUp_.bind(this);
+ this.inputElement_.addEventListener('change', this.boundInputOnChange);
+ this.inputElement_.addEventListener('focus', this.boundInputOnFocus);
+ this.inputElement_.addEventListener('blur', this.boundInputOnBlur);
+ this.element_.addEventListener('mouseup', this.boundElementMouseUp);
+ this.updateClasses_();
+ this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
+ }
+ };
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ componentHandler.register({
+ constructor: MaterialCheckbox,
+ classAsString: 'MaterialCheckbox',
+ cssClass: 'mdl-js-checkbox',
+ widget: true
+ });
+ /**
+ * @license
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /**
+ * Class constructor for icon toggle MDL component.
+ * Implements MDL component design pattern defined at:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @constructor
+ * @param {HTMLElement} element The element that will be upgraded.
+ */
+ var MaterialIconToggle = function MaterialIconToggle(element) {
+ this.element_ = element;
+ // Initialize instance.
+ this.init();
+ };
+ window['MaterialIconToggle'] = MaterialIconToggle;
+ /**
+ * Store constants in one place so they can be updated easily.
+ *
+ * @enum {string | number}
+ * @private
+ */
+ MaterialIconToggle.prototype.Constant_ = {
+ TINY_TIMEOUT: 0.001
+ };
+ /**
+ * Store strings for class names defined by this component that are used in
+ * JavaScript. This allows us to simply change it in one place should we
+ * decide to modify at a later date.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialIconToggle.prototype.CssClasses_ = {
+ INPUT: 'mdl-icon-toggle__input',
+ JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect',
+ RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
+ RIPPLE_CONTAINER: 'mdl-icon-toggle__ripple-container',
+ RIPPLE_CENTER: 'mdl-ripple--center',
+ RIPPLE: 'mdl-ripple',
+ IS_FOCUSED: 'is-focused',
+ IS_DISABLED: 'is-disabled',
+ IS_CHECKED: 'is-checked'
+ };
+ /**
+ * Handle change of state.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialIconToggle.prototype.onChange_ = function (event) {
+ this.updateClasses_();
+ };
+ /**
+ * Handle focus of element.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialIconToggle.prototype.onFocus_ = function (event) {
+ this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
+ };
+ /**
+ * Handle lost focus of element.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialIconToggle.prototype.onBlur_ = function (event) {
+ this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
+ };
+ /**
+ * Handle mouseup.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialIconToggle.prototype.onMouseUp_ = function (event) {
+ this.blur_();
+ };
+ /**
+ * Handle class updates.
+ *
+ * @private
+ */
+ MaterialIconToggle.prototype.updateClasses_ = function () {
+ this.checkDisabled();
+ this.checkToggleState();
+ };
+ /**
+ * Add blur.
+ *
+ * @private
+ */
+ MaterialIconToggle.prototype.blur_ = function () {
+ // TODO: figure out why there's a focus event being fired after our blur,
+ // so that we can avoid this hack.
+ window.setTimeout(function () {
+ this.inputElement_.blur();
+ }.bind(this), this.Constant_.TINY_TIMEOUT);
+ };
+ // Public methods.
+ /**
+ * Check the inputs toggle state and update display.
+ *
+ * @public
+ */
+ MaterialIconToggle.prototype.checkToggleState = function () {
+ if (this.inputElement_.checked) {
+ this.element_.classList.add(this.CssClasses_.IS_CHECKED);
+ } else {
+ this.element_.classList.remove(this.CssClasses_.IS_CHECKED);
+ }
+ };
+ MaterialIconToggle.prototype['checkToggleState'] = MaterialIconToggle.prototype.checkToggleState;
+ /**
+ * Check the inputs disabled state and update display.
+ *
+ * @public
+ */
+ MaterialIconToggle.prototype.checkDisabled = function () {
+ if (this.inputElement_.disabled) {
+ this.element_.classList.add(this.CssClasses_.IS_DISABLED);
+ } else {
+ this.element_.classList.remove(this.CssClasses_.IS_DISABLED);
+ }
+ };
+ MaterialIconToggle.prototype['checkDisabled'] = MaterialIconToggle.prototype.checkDisabled;
+ /**
+ * Disable icon toggle.
+ *
+ * @public
+ */
+ MaterialIconToggle.prototype.disable = function () {
+ this.inputElement_.disabled = true;
+ this.updateClasses_();
+ };
+ MaterialIconToggle.prototype['disable'] = MaterialIconToggle.prototype.disable;
+ /**
+ * Enable icon toggle.
+ *
+ * @public
+ */
+ MaterialIconToggle.prototype.enable = function () {
+ this.inputElement_.disabled = false;
+ this.updateClasses_();
+ };
+ MaterialIconToggle.prototype['enable'] = MaterialIconToggle.prototype.enable;
+ /**
+ * Check icon toggle.
+ *
+ * @public
+ */
+ MaterialIconToggle.prototype.check = function () {
+ this.inputElement_.checked = true;
+ this.updateClasses_();
+ };
+ MaterialIconToggle.prototype['check'] = MaterialIconToggle.prototype.check;
+ /**
+ * Uncheck icon toggle.
+ *
+ * @public
+ */
+ MaterialIconToggle.prototype.uncheck = function () {
+ this.inputElement_.checked = false;
+ this.updateClasses_();
+ };
+ MaterialIconToggle.prototype['uncheck'] = MaterialIconToggle.prototype.uncheck;
+ /**
+ * Initialize element.
+ */
+ MaterialIconToggle.prototype.init = function () {
+ if (this.element_) {
+ this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT);
+ if (this.element_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) {
+ this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
+ this.rippleContainerElement_ = document.createElement('span');
+ this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER);
+ this.rippleContainerElement_.classList.add(this.CssClasses_.JS_RIPPLE_EFFECT);
+ this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);
+ this.boundRippleMouseUp = this.onMouseUp_.bind(this);
+ this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp);
+ var ripple = document.createElement('span');
+ ripple.classList.add(this.CssClasses_.RIPPLE);
+ this.rippleContainerElement_.appendChild(ripple);
+ this.element_.appendChild(this.rippleContainerElement_);
+ }
+ this.boundInputOnChange = this.onChange_.bind(this);
+ this.boundInputOnFocus = this.onFocus_.bind(this);
+ this.boundInputOnBlur = this.onBlur_.bind(this);
+ this.boundElementOnMouseUp = this.onMouseUp_.bind(this);
+ this.inputElement_.addEventListener('change', this.boundInputOnChange);
+ this.inputElement_.addEventListener('focus', this.boundInputOnFocus);
+ this.inputElement_.addEventListener('blur', this.boundInputOnBlur);
+ this.element_.addEventListener('mouseup', this.boundElementOnMouseUp);
+ this.updateClasses_();
+ this.element_.classList.add('is-upgraded');
+ }
+ };
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ componentHandler.register({
+ constructor: MaterialIconToggle,
+ classAsString: 'MaterialIconToggle',
+ cssClass: 'mdl-js-icon-toggle',
+ widget: true
+ });
+ /**
+ * @license
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /**
+ * Class constructor for dropdown MDL component.
+ * Implements MDL component design pattern defined at:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @constructor
+ * @param {HTMLElement} element The element that will be upgraded.
+ */
+ var MaterialMenu = function MaterialMenu(element) {
+ this.element_ = element;
+ // Initialize instance.
+ this.init();
+ };
+ window['MaterialMenu'] = MaterialMenu;
+ /**
+ * Store constants in one place so they can be updated easily.
+ *
+ * @enum {string | number}
+ * @private
+ */
+ MaterialMenu.prototype.Constant_ = {
+ // Total duration of the menu animation.
+ TRANSITION_DURATION_SECONDS: 0.3,
+ // The fraction of the total duration we want to use for menu item animations.
+ TRANSITION_DURATION_FRACTION: 0.8,
+ // How long the menu stays open after choosing an option (so the user can see
+ // the ripple).
+ CLOSE_TIMEOUT: 150
+ };
+ /**
+ * Keycodes, for code readability.
+ *
+ * @enum {number}
+ * @private
+ */
+ MaterialMenu.prototype.Keycodes_ = {
+ ENTER: 13,
+ ESCAPE: 27,
+ SPACE: 32,
+ UP_ARROW: 38,
+ DOWN_ARROW: 40
+ };
+ /**
+ * Store strings for class names defined by this component that are used in
+ * JavaScript. This allows us to simply change it in one place should we
+ * decide to modify at a later date.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialMenu.prototype.CssClasses_ = {
+ CONTAINER: 'mdl-menu__container',
+ OUTLINE: 'mdl-menu__outline',
+ ITEM: 'mdl-menu__item',
+ ITEM_RIPPLE_CONTAINER: 'mdl-menu__item-ripple-container',
+ RIPPLE_EFFECT: 'mdl-js-ripple-effect',
+ RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
+ RIPPLE: 'mdl-ripple',
+ // Statuses
+ IS_UPGRADED: 'is-upgraded',
+ IS_VISIBLE: 'is-visible',
+ IS_ANIMATING: 'is-animating',
+ // Alignment options
+ BOTTOM_LEFT: 'mdl-menu--bottom-left',
+ // This is the default.
+ BOTTOM_RIGHT: 'mdl-menu--bottom-right',
+ TOP_LEFT: 'mdl-menu--top-left',
+ TOP_RIGHT: 'mdl-menu--top-right',
+ UNALIGNED: 'mdl-menu--unaligned'
+ };
+ /**
+ * Initialize element.
+ */
+ MaterialMenu.prototype.init = function () {
+ if (this.element_) {
+ // Create container for the menu.
+ var container = document.createElement('div');
+ container.classList.add(this.CssClasses_.CONTAINER);
+ this.element_.parentElement.insertBefore(container, this.element_);
+ this.element_.parentElement.removeChild(this.element_);
+ container.appendChild(this.element_);
+ this.container_ = container;
+ // Create outline for the menu (shadow and background).
+ var outline = document.createElement('div');
+ outline.classList.add(this.CssClasses_.OUTLINE);
+ this.outline_ = outline;
+ container.insertBefore(outline, this.element_);
+ // Find the "for" element and bind events to it.
+ var forElId = this.element_.getAttribute('for') || this.element_.getAttribute('data-mdl-for');
+ console.log("for id " + forElId)
+ var forEl = null;
+ if (forElId) {
+ forEl = document.getElementById(forElId);
+ if (forEl) {
+ this.forElement_ = forEl;
+ forEl.addEventListener('click', this.handleForClick_.bind(this));
+ forEl.addEventListener('keydown', this.handleForKeyboardEvent_.bind(this));
+ }
+ }
+ var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM);
+ this.boundItemKeydown_ = this.handleItemKeyboardEvent_.bind(this);
+ this.boundItemClick_ = this.handleItemClick_.bind(this);
+ for (var i = 0; i < items.length; i++) {
+ // Add a listener to each menu item.
+ items[i].addEventListener('click', this.boundItemClick_);
+ // Add a tab index to each menu item.
+ items[i].tabIndex = '-1';
+ // Add a keyboard listener to each menu item.
+ items[i].addEventListener('keydown', this.boundItemKeydown_);
+ }
+ // Add ripple classes to each item, if the user has enabled ripples.
+ if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {
+ this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
+ for (i = 0; i < items.length; i++) {
+ var item = items[i];
+ var rippleContainer = document.createElement('span');
+ rippleContainer.classList.add(this.CssClasses_.ITEM_RIPPLE_CONTAINER);
+ var ripple = document.createElement('span');
+ ripple.classList.add(this.CssClasses_.RIPPLE);
+ rippleContainer.appendChild(ripple);
+ item.appendChild(rippleContainer);
+ item.classList.add(this.CssClasses_.RIPPLE_EFFECT);
+ }
+ }
+ // Copy alignment classes to the container, so the outline can use them.
+ if (this.element_.classList.contains(this.CssClasses_.BOTTOM_LEFT)) {
+ this.outline_.classList.add(this.CssClasses_.BOTTOM_LEFT);
+ }
+ if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) {
+ this.outline_.classList.add(this.CssClasses_.BOTTOM_RIGHT);
+ }
+ if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) {
+ this.outline_.classList.add(this.CssClasses_.TOP_LEFT);
+ }
+ if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {
+ this.outline_.classList.add(this.CssClasses_.TOP_RIGHT);
+ }
+ if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) {
+ this.outline_.classList.add(this.CssClasses_.UNALIGNED);
+ }
+ container.classList.add(this.CssClasses_.IS_UPGRADED);
+ }
+ };
+ /**
+ * Handles a click on the "for" element, by positioning the menu and then
+ * toggling it.
+ *
+ * @param {Event} evt The event that fired.
+ * @private
+ */
+ MaterialMenu.prototype.handleForClick_ = function (evt) {
+ if (this.element_ && this.forElement_) {
+ var rect = this.forElement_.getBoundingClientRect();
+ var forRect = this.forElement_.parentElement.getBoundingClientRect();
+ if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) {} else if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) {
+ // Position below the "for" element, aligned to its right.
+ this.container_.style.right = forRect.right - rect.right + 'px';
+ this.container_.style.top = this.forElement_.offsetTop + this.forElement_.offsetHeight + 'px';
+ } else if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) {
+ // Position above the "for" element, aligned to its left.
+ this.container_.style.left = this.forElement_.offsetLeft + 'px';
+ this.container_.style.bottom = forRect.bottom - rect.top + 'px';
+ } else if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {
+ // Position above the "for" element, aligned to its right.
+ this.container_.style.right = forRect.right - rect.right + 'px';
+ this.container_.style.bottom = forRect.bottom - rect.top + 'px';
+ } else {
+ // Default: position below the "for" element, aligned to its left.
+ this.container_.style.left = this.forElement_.offsetLeft + 'px';
+ this.container_.style.top = this.forElement_.offsetTop + this.forElement_.offsetHeight + 'px';
+ }
+ }
+ this.toggle(evt);
+ };
+ /**
+ * Handles a keyboard event on the "for" element.
+ *
+ * @param {Event} evt The event that fired.
+ * @private
+ */
+ MaterialMenu.prototype.handleForKeyboardEvent_ = function (evt) {
+ if (this.element_ && this.container_ && this.forElement_) {
+ var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM + ':not([disabled])');
+ if (items && items.length > 0 && this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) {
+ if (evt.keyCode === this.Keycodes_.UP_ARROW) {
+ evt.preventDefault();
+ items[items.length - 1].focus();
+ } else if (evt.keyCode === this.Keycodes_.DOWN_ARROW) {
+ evt.preventDefault();
+ items[0].focus();
+ }
+ }
+ }
+ };
+ /**
+ * Handles a keyboard event on an item.
+ *
+ * @param {Event} evt The event that fired.
+ * @private
+ */
+ MaterialMenu.prototype.handleItemKeyboardEvent_ = function (evt) {
+ if (this.element_ && this.container_) {
+ var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM + ':not([disabled])');
+ if (items && items.length > 0 && this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) {
+ var currentIndex = Array.prototype.slice.call(items).indexOf(evt.target);
+ if (evt.keyCode === this.Keycodes_.UP_ARROW) {
+ evt.preventDefault();
+ if (currentIndex > 0) {
+ items[currentIndex - 1].focus();
+ } else {
+ items[items.length - 1].focus();
+ }
+ } else if (evt.keyCode === this.Keycodes_.DOWN_ARROW) {
+ evt.preventDefault();
+ if (items.length > currentIndex + 1) {
+ items[currentIndex + 1].focus();
+ } else {
+ items[0].focus();
+ }
+ } else if (evt.keyCode === this.Keycodes_.SPACE || evt.keyCode === this.Keycodes_.ENTER) {
+ evt.preventDefault();
+ // Send mousedown and mouseup to trigger ripple.
+ var e = new MouseEvent('mousedown');
+ evt.target.dispatchEvent(e);
+ e = new MouseEvent('mouseup');
+ evt.target.dispatchEvent(e);
+ // Send click.
+ evt.target.click();
+ } else if (evt.keyCode === this.Keycodes_.ESCAPE) {
+ evt.preventDefault();
+ this.hide();
+ }
+ }
+ }
+ };
+ /**
+ * Handles a click event on an item.
+ *
+ * @param {Event} evt The event that fired.
+ * @private
+ */
+ MaterialMenu.prototype.handleItemClick_ = function (evt) {
+ if (evt.target.hasAttribute('disabled')) {
+ evt.stopPropagation();
+ } else {
+ // Wait some time before closing menu, so the user can see the ripple.
+ this.closing_ = true;
+ window.setTimeout(function (evt) {
+ this.hide();
+ this.closing_ = false;
+ }.bind(this), this.Constant_.CLOSE_TIMEOUT);
+ }
+ };
+ /**
+ * Calculates the initial clip (for opening the menu) or final clip (for closing
+ * it), and applies it. This allows us to animate from or to the correct point,
+ * that is, the point it's aligned to in the "for" element.
+ *
+ * @param {number} height Height of the clip rectangle
+ * @param {number} width Width of the clip rectangle
+ * @private
+ */
+ MaterialMenu.prototype.applyClip_ = function (height, width) {
+ if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) {
+ // Do not clip.
+ this.element_.style.clip = '';
+ } else if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) {
+ // Clip to the top right corner of the menu.
+ this.element_.style.clip = 'rect(0 ' + width + 'px ' + '0 ' + width + 'px)';
+ } else if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) {
+ // Clip to the bottom left corner of the menu.
+ this.element_.style.clip = 'rect(' + height + 'px 0 ' + height + 'px 0)';
+ } else if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {
+ // Clip to the bottom right corner of the menu.
+ this.element_.style.clip = 'rect(' + height + 'px ' + width + 'px ' + height + 'px ' + width + 'px)';
+ } else {
+ // Default: do not clip (same as clipping to the top left corner).
+ this.element_.style.clip = '';
+ }
+ };
+ /**
+ * Cleanup function to remove animation listeners.
+ *
+ * @param {Event} evt
+ * @private
+ */
+ MaterialMenu.prototype.removeAnimationEndListener_ = function (evt) {
+ evt.target.classList.remove(MaterialMenu.prototype.CssClasses_.IS_ANIMATING);
+ };
+ /**
+ * Adds an event listener to clean up after the animation ends.
+ *
+ * @private
+ */
+ MaterialMenu.prototype.addAnimationEndListener_ = function () {
+ this.element_.addEventListener('transitionend', this.removeAnimationEndListener_);
+ this.element_.addEventListener('webkitTransitionEnd', this.removeAnimationEndListener_);
+ };
+ /**
+ * Displays the menu.
+ *
+ * @public
+ */
+ MaterialMenu.prototype.show = function (evt) {
+ console.log("show")
+ if (this.element_ && this.container_ && this.outline_) {
+ // Measure the inner element.
+ var height = this.element_.getBoundingClientRect().height;
+ var width = this.element_.getBoundingClientRect().width;
+ // Apply the inner element's size to the container and outline.
+ this.container_.style.width = width + 'px';
+ this.container_.style.height = height + 'px';
+ this.outline_.style.width = width + 'px';
+ this.outline_.style.height = height + 'px';
+ var transitionDuration = this.Constant_.TRANSITION_DURATION_SECONDS * this.Constant_.TRANSITION_DURATION_FRACTION;
+ // Calculate transition delays for individual menu items, so that they fade
+ // in one at a time.
+ var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM);
+ for (var i = 0; i < items.length; i++) {
+ var itemDelay = null;
+ if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT) || this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {
+ itemDelay = (height - items[i].offsetTop - items[i].offsetHeight) / height * transitionDuration + 's';
+ } else {
+ itemDelay = items[i].offsetTop / height * transitionDuration + 's';
+ }
+ items[i].style.transitionDelay = itemDelay;
+ }
+ // Apply the initial clip to the text before we start animating.
+ this.applyClip_(height, width);
+ // Wait for the next frame, turn on animation, and apply the final clip.
+ // Also make it visible. This triggers the transitions.
+ window.requestAnimationFrame(function () {
+ this.element_.classList.add(this.CssClasses_.IS_ANIMATING);
+ this.element_.style.clip = 'rect(0 ' + width + 'px ' + height + 'px 0)';
+ this.container_.classList.add(this.CssClasses_.IS_VISIBLE);
+ }.bind(this));
+ // Clean up after the animation is complete.
+ this.addAnimationEndListener_();
+ // Add a click listener to the document, to close the menu.
+ var callback = function (e) {
+ // Check to see if the document is processing the same event that
+ // displayed the menu in the first place. If so, do nothing.
+ // Also check to see if the menu is in the process of closing itself, and
+ // do nothing in that case.
+ // Also check if the clicked element is a menu item
+ // if so, do nothing.
+ if (e !== evt && !this.closing_ && e.target.parentNode !== this.element_) {
+ document.removeEventListener('click', callback);
+ this.hide();
+ }
+ }.bind(this);
+ document.addEventListener('click', callback);
+ }
+ };
+ MaterialMenu.prototype['show'] = MaterialMenu.prototype.show;
+ /**
+ * Hides the menu.
+ *
+ * @public
+ */
+ MaterialMenu.prototype.hide = function () {
+ if (this.element_ && this.container_ && this.outline_) {
+ var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM);
+ // Remove all transition delays; menu items fade out concurrently.
+ for (var i = 0; i < items.length; i++) {
+ items[i].style.removeProperty('transition-delay');
+ }
+ // Measure the inner element.
+ var rect = this.element_.getBoundingClientRect();
+ var height = rect.height;
+ var width = rect.width;
+ // Turn on animation, and apply the final clip. Also make invisible.
+ // This triggers the transitions.
+ this.element_.classList.add(this.CssClasses_.IS_ANIMATING);
+ this.applyClip_(height, width);
+ this.container_.classList.remove(this.CssClasses_.IS_VISIBLE);
+ // Clean up after the animation is complete.
+ this.addAnimationEndListener_();
+ }
+ };
+ MaterialMenu.prototype['hide'] = MaterialMenu.prototype.hide;
+ /**
+ * Displays or hides the menu, depending on current state.
+ *
+ * @public
+ */
+ MaterialMenu.prototype.toggle = function (evt) {
+ if (this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) {
+ this.hide();
+ } else {
+ this.show(evt);
+ }
+ };
+ MaterialMenu.prototype['toggle'] = MaterialMenu.prototype.toggle;
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ componentHandler.register({
+ constructor: MaterialMenu,
+ classAsString: 'MaterialMenu',
+ cssClass: 'mdl-js-menu',
+ widget: true
+ });
+ /**
+ * @license
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /**
+ * Class constructor for Progress MDL component.
+ * Implements MDL component design pattern defined at:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @constructor
+ * @param {HTMLElement} element The element that will be upgraded.
+ */
+ var MaterialProgress = function MaterialProgress(element) {
+ this.element_ = element;
+ // Initialize instance.
+ this.init();
+ };
+ window['MaterialProgress'] = MaterialProgress;
+ /**
+ * Store constants in one place so they can be updated easily.
+ *
+ * @enum {string | number}
+ * @private
+ */
+ MaterialProgress.prototype.Constant_ = {};
+ /**
+ * Store strings for class names defined by this component that are used in
+ * JavaScript. This allows us to simply change it in one place should we
+ * decide to modify at a later date.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialProgress.prototype.CssClasses_ = {
+ INDETERMINATE_CLASS: 'mdl-progress__indeterminate'
+ };
+ /**
+ * Set the current progress of the progressbar.
+ *
+ * @param {number} p Percentage of the progress (0-100)
+ * @public
+ */
+ MaterialProgress.prototype.setProgress = function (p) {
+ if (this.element_.classList.contains(this.CssClasses_.INDETERMINATE_CLASS)) {
+ return;
+ }
+ this.progressbar_.style.width = p + '%';
+ };
+ MaterialProgress.prototype['setProgress'] = MaterialProgress.prototype.setProgress;
+ /**
+ * Set the current progress of the buffer.
+ *
+ * @param {number} p Percentage of the buffer (0-100)
+ * @public
+ */
+ MaterialProgress.prototype.setBuffer = function (p) {
+ this.bufferbar_.style.width = p + '%';
+ this.auxbar_.style.width = 100 - p + '%';
+ };
+ MaterialProgress.prototype['setBuffer'] = MaterialProgress.prototype.setBuffer;
+ /**
+ * Initialize element.
+ */
+ MaterialProgress.prototype.init = function () {
+ if (this.element_) {
+ var el = document.createElement('div');
+ el.className = 'progressbar bar bar1';
+ this.element_.appendChild(el);
+ this.progressbar_ = el;
+ el = document.createElement('div');
+ el.className = 'bufferbar bar bar2';
+ this.element_.appendChild(el);
+ this.bufferbar_ = el;
+ el = document.createElement('div');
+ el.className = 'auxbar bar bar3';
+ this.element_.appendChild(el);
+ this.auxbar_ = el;
+ this.progressbar_.style.width = '0%';
+ this.bufferbar_.style.width = '100%';
+ this.auxbar_.style.width = '0%';
+ this.element_.classList.add('is-upgraded');
+ }
+ };
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ componentHandler.register({
+ constructor: MaterialProgress,
+ classAsString: 'MaterialProgress',
+ cssClass: 'mdl-js-progress',
+ widget: true
+ });
+ /**
+ * @license
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /**
+ * Class constructor for Radio MDL component.
+ * Implements MDL component design pattern defined at:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @constructor
+ * @param {HTMLElement} element The element that will be upgraded.
+ */
+ var MaterialRadio = function MaterialRadio(element) {
+ this.element_ = element;
+ // Initialize instance.
+ this.init();
+ };
+ window['MaterialRadio'] = MaterialRadio;
+ /**
+ * Store constants in one place so they can be updated easily.
+ *
+ * @enum {string | number}
+ * @private
+ */
+ MaterialRadio.prototype.Constant_ = {
+ TINY_TIMEOUT: 0.001
+ };
+ /**
+ * Store strings for class names defined by this component that are used in
+ * JavaScript. This allows us to simply change it in one place should we
+ * decide to modify at a later date.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialRadio.prototype.CssClasses_ = {
+ IS_FOCUSED: 'is-focused',
+ IS_DISABLED: 'is-disabled',
+ IS_CHECKED: 'is-checked',
+ IS_UPGRADED: 'is-upgraded',
+ JS_RADIO: 'mdl-js-radio',
+ RADIO_BTN: 'mdl-radio__button',
+ RADIO_OUTER_CIRCLE: 'mdl-radio__outer-circle',
+ RADIO_INNER_CIRCLE: 'mdl-radio__inner-circle',
+ RIPPLE_EFFECT: 'mdl-js-ripple-effect',
+ RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
+ RIPPLE_CONTAINER: 'mdl-radio__ripple-container',
+ RIPPLE_CENTER: 'mdl-ripple--center',
+ RIPPLE: 'mdl-ripple'
+ };
+ /**
+ * Handle change of state.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialRadio.prototype.onChange_ = function (event) {
+ // Since other radio buttons don't get change events, we need to look for
+ // them to update their classes.
+ var radios = document.getElementsByClassName(this.CssClasses_.JS_RADIO);
+ for (var i = 0; i < radios.length; i++) {
+ var button = radios[i].querySelector('.' + this.CssClasses_.RADIO_BTN);
+ // Different name == different group, so no point updating those.
+ if (button.getAttribute('name') === this.btnElement_.getAttribute('name')) {
+ if (typeof radios[i]['MaterialRadio'] !== 'undefined') {
+ radios[i]['MaterialRadio'].updateClasses_();
+ }
+ }
+ }
+ };
+ /**
+ * Handle focus.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialRadio.prototype.onFocus_ = function (event) {
+ this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
+ };
+ /**
+ * Handle lost focus.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialRadio.prototype.onBlur_ = function (event) {
+ this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
+ };
+ /**
+ * Handle mouseup.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialRadio.prototype.onMouseup_ = function (event) {
+ this.blur_();
+ };
+ /**
+ * Update classes.
+ *
+ * @private
+ */
+ MaterialRadio.prototype.updateClasses_ = function () {
+ this.checkDisabled();
+ this.checkToggleState();
+ };
+ /**
+ * Add blur.
+ *
+ * @private
+ */
+ MaterialRadio.prototype.blur_ = function () {
+ // TODO: figure out why there's a focus event being fired after our blur,
+ // so that we can avoid this hack.
+ window.setTimeout(function () {
+ this.btnElement_.blur();
+ }.bind(this), this.Constant_.TINY_TIMEOUT);
+ };
+ // Public methods.
+ /**
+ * Check the components disabled state.
+ *
+ * @public
+ */
+ MaterialRadio.prototype.checkDisabled = function () {
+ if (this.btnElement_.disabled) {
+ this.element_.classList.add(this.CssClasses_.IS_DISABLED);
+ } else {
+ this.element_.classList.remove(this.CssClasses_.IS_DISABLED);
+ }
+ };
+ MaterialRadio.prototype['checkDisabled'] = MaterialRadio.prototype.checkDisabled;
+ /**
+ * Check the components toggled state.
+ *
+ * @public
+ */
+ MaterialRadio.prototype.checkToggleState = function () {
+ if (this.btnElement_.checked) {
+ this.element_.classList.add(this.CssClasses_.IS_CHECKED);
+ } else {
+ this.element_.classList.remove(this.CssClasses_.IS_CHECKED);
+ }
+ };
+ MaterialRadio.prototype['checkToggleState'] = MaterialRadio.prototype.checkToggleState;
+ /**
+ * Disable radio.
+ *
+ * @public
+ */
+ MaterialRadio.prototype.disable = function () {
+ this.btnElement_.disabled = true;
+ this.updateClasses_();
+ };
+ MaterialRadio.prototype['disable'] = MaterialRadio.prototype.disable;
+ /**
+ * Enable radio.
+ *
+ * @public
+ */
+ MaterialRadio.prototype.enable = function () {
+ this.btnElement_.disabled = false;
+ this.updateClasses_();
+ };
+ MaterialRadio.prototype['enable'] = MaterialRadio.prototype.enable;
+ /**
+ * Check radio.
+ *
+ * @public
+ */
+ MaterialRadio.prototype.check = function () {
+ this.btnElement_.checked = true;
+ this.onChange_(null);
+ };
+ MaterialRadio.prototype['check'] = MaterialRadio.prototype.check;
+ /**
+ * Uncheck radio.
+ *
+ * @public
+ */
+ MaterialRadio.prototype.uncheck = function () {
+ this.btnElement_.checked = false;
+ this.onChange_(null);
+ };
+ MaterialRadio.prototype['uncheck'] = MaterialRadio.prototype.uncheck;
+ /**
+ * Initialize element.
+ */
+ MaterialRadio.prototype.init = function () {
+ if (this.element_) {
+ this.btnElement_ = this.element_.querySelector('.' + this.CssClasses_.RADIO_BTN);
+ this.boundChangeHandler_ = this.onChange_.bind(this);
+ this.boundFocusHandler_ = this.onChange_.bind(this);
+ this.boundBlurHandler_ = this.onBlur_.bind(this);
+ this.boundMouseUpHandler_ = this.onMouseup_.bind(this);
+ var outerCircle = document.createElement('span');
+ outerCircle.classList.add(this.CssClasses_.RADIO_OUTER_CIRCLE);
+ var innerCircle = document.createElement('span');
+ innerCircle.classList.add(this.CssClasses_.RADIO_INNER_CIRCLE);
+ this.element_.appendChild(outerCircle);
+ this.element_.appendChild(innerCircle);
+ var rippleContainer;
+ if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {
+ this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
+ rippleContainer = document.createElement('span');
+ rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER);
+ rippleContainer.classList.add(this.CssClasses_.RIPPLE_EFFECT);
+ rippleContainer.classList.add(this.CssClasses_.RIPPLE_CENTER);
+ rippleContainer.addEventListener('mouseup', this.boundMouseUpHandler_);
+ var ripple = document.createElement('span');
+ ripple.classList.add(this.CssClasses_.RIPPLE);
+ rippleContainer.appendChild(ripple);
+ this.element_.appendChild(rippleContainer);
+ }
+ this.btnElement_.addEventListener('change', this.boundChangeHandler_);
+ this.btnElement_.addEventListener('focus', this.boundFocusHandler_);
+ this.btnElement_.addEventListener('blur', this.boundBlurHandler_);
+ this.element_.addEventListener('mouseup', this.boundMouseUpHandler_);
+ this.updateClasses_();
+ this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
+ }
+ };
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ componentHandler.register({
+ constructor: MaterialRadio,
+ classAsString: 'MaterialRadio',
+ cssClass: 'mdl-js-radio',
+ widget: true
+ });
+ /**
+ * @license
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /**
+ * Class constructor for Slider MDL component.
+ * Implements MDL component design pattern defined at:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @constructor
+ * @param {HTMLElement} element The element that will be upgraded.
+ */
+ var MaterialSlider = function MaterialSlider(element) {
+ this.element_ = element;
+ // Browser feature detection.
+ this.isIE_ = window.navigator.msPointerEnabled;
+ // Initialize instance.
+ this.init();
+ };
+ window['MaterialSlider'] = MaterialSlider;
+ /**
+ * Store constants in one place so they can be updated easily.
+ *
+ * @enum {string | number}
+ * @private
+ */
+ MaterialSlider.prototype.Constant_ = {};
+ /**
+ * Store strings for class names defined by this component that are used in
+ * JavaScript. This allows us to simply change it in one place should we
+ * decide to modify at a later date.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialSlider.prototype.CssClasses_ = {
+ IE_CONTAINER: 'mdl-slider__ie-container',
+ SLIDER_CONTAINER: 'mdl-slider__container',
+ BACKGROUND_FLEX: 'mdl-slider__background-flex',
+ BACKGROUND_LOWER: 'mdl-slider__background-lower',
+ BACKGROUND_UPPER: 'mdl-slider__background-upper',
+ IS_LOWEST_VALUE: 'is-lowest-value',
+ IS_UPGRADED: 'is-upgraded'
+ };
+ /**
+ * Handle input on element.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialSlider.prototype.onInput_ = function (event) {
+ this.updateValueStyles_();
+ };
+ /**
+ * Handle change on element.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialSlider.prototype.onChange_ = function (event) {
+ this.updateValueStyles_();
+ };
+ /**
+ * Handle mouseup on element.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialSlider.prototype.onMouseUp_ = function (event) {
+ event.target.blur();
+ };
+ /**
+ * Handle mousedown on container element.
+ * This handler is purpose is to not require the use to click
+ * exactly on the 2px slider element, as FireFox seems to be very
+ * strict about this.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ * @suppress {missingProperties}
+ */
+ MaterialSlider.prototype.onContainerMouseDown_ = function (event) {
+ // If this click is not on the parent element (but rather some child)
+ // ignore. It may still bubble up.
+ if (event.target !== this.element_.parentElement) {
+ return;
+ }
+ // Discard the original event and create a new event that
+ // is on the slider element.
+ event.preventDefault();
+ var newEvent = new MouseEvent('mousedown', {
+ target: event.target,
+ buttons: event.buttons,
+ clientX: event.clientX,
+ clientY: this.element_.getBoundingClientRect().y
+ });
+ this.element_.dispatchEvent(newEvent);
+ };
+ /**
+ * Handle updating of values.
+ *
+ * @private
+ */
+ MaterialSlider.prototype.updateValueStyles_ = function () {
+ // Calculate and apply percentages to div structure behind slider.
+ var fraction = (this.element_.value - this.element_.min) / (this.element_.max - this.element_.min);
+ if (fraction === 0) {
+ this.element_.classList.add(this.CssClasses_.IS_LOWEST_VALUE);
+ } else {
+ this.element_.classList.remove(this.CssClasses_.IS_LOWEST_VALUE);
+ }
+ if (!this.isIE_) {
+ this.backgroundLower_.style.flex = fraction;
+ this.backgroundLower_.style.webkitFlex = fraction;
+ this.backgroundUpper_.style.flex = 1 - fraction;
+ this.backgroundUpper_.style.webkitFlex = 1 - fraction;
+ }
+ };
+ // Public methods.
+ /**
+ * Disable slider.
+ *
+ * @public
+ */
+ MaterialSlider.prototype.disable = function () {
+ this.element_.disabled = true;
+ };
+ MaterialSlider.prototype['disable'] = MaterialSlider.prototype.disable;
+ /**
+ * Enable slider.
+ *
+ * @public
+ */
+ MaterialSlider.prototype.enable = function () {
+ this.element_.disabled = false;
+ };
+ MaterialSlider.prototype['enable'] = MaterialSlider.prototype.enable;
+ /**
+ * Update slider value.
+ *
+ * @param {number} value The value to which to set the control (optional).
+ * @public
+ */
+ MaterialSlider.prototype.change = function (value) {
+ if (typeof value !== 'undefined') {
+ this.element_.value = value;
+ }
+ this.updateValueStyles_();
+ };
+ MaterialSlider.prototype['change'] = MaterialSlider.prototype.change;
+ /**
+ * Initialize element.
+ */
+ MaterialSlider.prototype.init = function () {
+ if (this.element_) {
+ if (this.isIE_) {
+ // Since we need to specify a very large height in IE due to
+ // implementation limitations, we add a parent here that trims it down to
+ // a reasonable size.
+ var containerIE = document.createElement('div');
+ containerIE.classList.add(this.CssClasses_.IE_CONTAINER);
+ this.element_.parentElement.insertBefore(containerIE, this.element_);
+ this.element_.parentElement.removeChild(this.element_);
+ containerIE.appendChild(this.element_);
+ } else {
+ // For non-IE browsers, we need a div structure that sits behind the
+ // slider and allows us to style the left and right sides of it with
+ // different colors.
+ var container = document.createElement('div');
+ container.classList.add(this.CssClasses_.SLIDER_CONTAINER);
+ this.element_.parentElement.insertBefore(container, this.element_);
+ this.element_.parentElement.removeChild(this.element_);
+ container.appendChild(this.element_);
+ var backgroundFlex = document.createElement('div');
+ backgroundFlex.classList.add(this.CssClasses_.BACKGROUND_FLEX);
+ container.appendChild(backgroundFlex);
+ this.backgroundLower_ = document.createElement('div');
+ this.backgroundLower_.classList.add(this.CssClasses_.BACKGROUND_LOWER);
+ backgroundFlex.appendChild(this.backgroundLower_);
+ this.backgroundUpper_ = document.createElement('div');
+ this.backgroundUpper_.classList.add(this.CssClasses_.BACKGROUND_UPPER);
+ backgroundFlex.appendChild(this.backgroundUpper_);
+ }
+ this.boundInputHandler = this.onInput_.bind(this);
+ this.boundChangeHandler = this.onChange_.bind(this);
+ this.boundMouseUpHandler = this.onMouseUp_.bind(this);
+ this.boundContainerMouseDownHandler = this.onContainerMouseDown_.bind(this);
+ this.element_.addEventListener('input', this.boundInputHandler);
+ this.element_.addEventListener('change', this.boundChangeHandler);
+ this.element_.addEventListener('mouseup', this.boundMouseUpHandler);
+ this.element_.parentElement.addEventListener('mousedown', this.boundContainerMouseDownHandler);
+ this.updateValueStyles_();
+ this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
+ }
+ };
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ componentHandler.register({
+ constructor: MaterialSlider,
+ classAsString: 'MaterialSlider',
+ cssClass: 'mdl-js-slider',
+ widget: true
+ });
+ /**
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /**
+ * Class constructor for Snackbar MDL component.
+ * Implements MDL component design pattern defined at:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @constructor
+ * @param {HTMLElement} element The element that will be upgraded.
+ */
+ var MaterialSnackbar = function MaterialSnackbar(element) {
+ this.element_ = element;
+ this.textElement_ = this.element_.querySelector('.' + this.cssClasses_.MESSAGE);
+ this.actionElement_ = this.element_.querySelector('.' + this.cssClasses_.ACTION);
+ if (!this.textElement_) {
+ throw new Error('There must be a message element for a snackbar.');
+ }
+ if (!this.actionElement_) {
+ throw new Error('There must be an action element for a snackbar.');
+ }
+ this.active = false;
+ this.actionHandler_ = undefined;
+ this.message_ = undefined;
+ this.actionText_ = undefined;
+ this.queuedNotifications_ = [];
+ this.setActionHidden_(true);
+ };
+ window['MaterialSnackbar'] = MaterialSnackbar;
+ /**
+ * Store constants in one place so they can be updated easily.
+ *
+ * @enum {string | number}
+ * @private
+ */
+ MaterialSnackbar.prototype.Constant_ = {
+ // The duration of the snackbar show/hide animation, in ms.
+ ANIMATION_LENGTH: 250
+ };
+ /**
+ * Store strings for class names defined by this component that are used in
+ * JavaScript. This allows us to simply change it in one place should we
+ * decide to modify at a later date.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialSnackbar.prototype.cssClasses_ = {
+ SNACKBAR: 'mdl-snackbar',
+ MESSAGE: 'mdl-snackbar__text',
+ ACTION: 'mdl-snackbar__action',
+ ACTIVE: 'mdl-snackbar--active'
+ };
+ /**
+ * Display the snackbar.
+ *
+ * @private
+ */
+ MaterialSnackbar.prototype.displaySnackbar_ = function () {
+ this.element_.setAttribute('aria-hidden', 'true');
+ if (this.actionHandler_) {
+ this.actionElement_.textContent = this.actionText_;
+ this.actionElement_.addEventListener('click', this.actionHandler_);
+ this.setActionHidden_(false);
+ }
+ this.textElement_.textContent = this.message_;
+ this.element_.classList.add(this.cssClasses_.ACTIVE);
+ this.element_.setAttribute('aria-hidden', 'false');
+ setTimeout(this.cleanup_.bind(this), this.timeout_);
+ };
+ /**
+ * Show the snackbar.
+ *
+ * @param {Object} data The data for the notification.
+ * @public
+ */
+ MaterialSnackbar.prototype.showSnackbar = function (data) {
+ if (data === undefined) {
+ throw new Error('Please provide a data object with at least a message to display.');
+ }
+ if (data['message'] === undefined) {
+ throw new Error('Please provide a message to be displayed.');
+ }
+ if (data['actionHandler'] && !data['actionText']) {
+ throw new Error('Please provide action text with the handler.');
+ }
+ if (this.active) {
+ this.queuedNotifications_.push(data);
+ } else {
+ this.active = true;
+ this.message_ = data['message'];
+ if (data['timeout']) {
+ this.timeout_ = data['timeout'];
+ } else {
+ this.timeout_ = 2750;
+ }
+ if (data['actionHandler']) {
+ this.actionHandler_ = data['actionHandler'];
+ }
+ if (data['actionText']) {
+ this.actionText_ = data['actionText'];
+ }
+ this.displaySnackbar_();
+ }
+ };
+ MaterialSnackbar.prototype['showSnackbar'] = MaterialSnackbar.prototype.showSnackbar;
+ /**
+ * Check if the queue has items within it.
+ * If it does, display the next entry.
+ *
+ * @private
+ */
+ MaterialSnackbar.prototype.checkQueue_ = function () {
+ if (this.queuedNotifications_.length > 0) {
+ this.showSnackbar(this.queuedNotifications_.shift());
+ }
+ };
+ /**
+ * Cleanup the snackbar event listeners and accessiblity attributes.
+ *
+ * @private
+ */
+ MaterialSnackbar.prototype.cleanup_ = function () {
+ this.element_.classList.remove(this.cssClasses_.ACTIVE);
+ setTimeout(function () {
+ this.element_.setAttribute('aria-hidden', 'true');
+ this.textElement_.textContent = '';
+ if (!Boolean(this.actionElement_.getAttribute('aria-hidden'))) {
+ this.setActionHidden_(true);
+ this.actionElement_.textContent = '';
+ this.actionElement_.removeEventListener('click', this.actionHandler_);
+ }
+ this.actionHandler_ = undefined;
+ this.message_ = undefined;
+ this.actionText_ = undefined;
+ this.active = false;
+ this.checkQueue_();
+ }.bind(this), this.Constant_.ANIMATION_LENGTH);
+ };
+ /**
+ * Set the action handler hidden state.
+ *
+ * @param {boolean} value
+ * @private
+ */
+ MaterialSnackbar.prototype.setActionHidden_ = function (value) {
+ if (value) {
+ this.actionElement_.setAttribute('aria-hidden', 'true');
+ } else {
+ this.actionElement_.removeAttribute('aria-hidden');
+ }
+ };
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ componentHandler.register({
+ constructor: MaterialSnackbar,
+ classAsString: 'MaterialSnackbar',
+ cssClass: 'mdl-js-snackbar',
+ widget: true
+ });
+ /**
+ * @license
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /**
+ * Class constructor for Spinner MDL component.
+ * Implements MDL component design pattern defined at:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @param {HTMLElement} element The element that will be upgraded.
+ * @constructor
+ */
+ var MaterialSpinner = function MaterialSpinner(element) {
+ this.element_ = element;
+ // Initialize instance.
+ this.init();
+ };
+ window['MaterialSpinner'] = MaterialSpinner;
+ /**
+ * Store constants in one place so they can be updated easily.
+ *
+ * @enum {string | number}
+ * @private
+ */
+ MaterialSpinner.prototype.Constant_ = {
+ MDL_SPINNER_LAYER_COUNT: 4
+ };
+ /**
+ * Store strings for class names defined by this component that are used in
+ * JavaScript. This allows us to simply change it in one place should we
+ * decide to modify at a later date.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialSpinner.prototype.CssClasses_ = {
+ MDL_SPINNER_LAYER: 'mdl-spinner__layer',
+ MDL_SPINNER_CIRCLE_CLIPPER: 'mdl-spinner__circle-clipper',
+ MDL_SPINNER_CIRCLE: 'mdl-spinner__circle',
+ MDL_SPINNER_GAP_PATCH: 'mdl-spinner__gap-patch',
+ MDL_SPINNER_LEFT: 'mdl-spinner__left',
+ MDL_SPINNER_RIGHT: 'mdl-spinner__right'
+ };
+ /**
+ * Auxiliary method to create a spinner layer.
+ *
+ * @param {number} index Index of the layer to be created.
+ * @public
+ */
+ MaterialSpinner.prototype.createLayer = function (index) {
+ var layer = document.createElement('div');
+ layer.classList.add(this.CssClasses_.MDL_SPINNER_LAYER);
+ layer.classList.add(this.CssClasses_.MDL_SPINNER_LAYER + '-' + index);
+ var leftClipper = document.createElement('div');
+ leftClipper.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER);
+ leftClipper.classList.add(this.CssClasses_.MDL_SPINNER_LEFT);
+ var gapPatch = document.createElement('div');
+ gapPatch.classList.add(this.CssClasses_.MDL_SPINNER_GAP_PATCH);
+ var rightClipper = document.createElement('div');
+ rightClipper.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER);
+ rightClipper.classList.add(this.CssClasses_.MDL_SPINNER_RIGHT);
+ var circleOwners = [
+ leftClipper,
+ gapPatch,
+ rightClipper
+ ];
+ for (var i = 0; i < circleOwners.length; i++) {
+ var circle = document.createElement('div');
+ circle.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE);
+ circleOwners[i].appendChild(circle);
+ }
+ layer.appendChild(leftClipper);
+ layer.appendChild(gapPatch);
+ layer.appendChild(rightClipper);
+ this.element_.appendChild(layer);
+ };
+ MaterialSpinner.prototype['createLayer'] = MaterialSpinner.prototype.createLayer;
+ /**
+ * Stops the spinner animation.
+ * Public method for users who need to stop the spinner for any reason.
+ *
+ * @public
+ */
+ MaterialSpinner.prototype.stop = function () {
+ this.element_.classList.remove('is-active');
+ };
+ MaterialSpinner.prototype['stop'] = MaterialSpinner.prototype.stop;
+ /**
+ * Starts the spinner animation.
+ * Public method for users who need to manually start the spinner for any reason
+ * (instead of just adding the 'is-active' class to their markup).
+ *
+ * @public
+ */
+ MaterialSpinner.prototype.start = function () {
+ this.element_.classList.add('is-active');
+ };
+ MaterialSpinner.prototype['start'] = MaterialSpinner.prototype.start;
+ /**
+ * Initialize element.
+ */
+ MaterialSpinner.prototype.init = function () {
+ if (this.element_) {
+ for (var i = 1; i <= this.Constant_.MDL_SPINNER_LAYER_COUNT; i++) {
+ this.createLayer(i);
+ }
+ this.element_.classList.add('is-upgraded');
+ }
+ };
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ componentHandler.register({
+ constructor: MaterialSpinner,
+ classAsString: 'MaterialSpinner',
+ cssClass: 'mdl-js-spinner',
+ widget: true
+ });
+ /**
+ * @license
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /**
+ * Class constructor for Checkbox MDL component.
+ * Implements MDL component design pattern defined at:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @constructor
+ * @param {HTMLElement} element The element that will be upgraded.
+ */
+ var MaterialSwitch = function MaterialSwitch(element) {
+ this.element_ = element;
+ // Initialize instance.
+ this.init();
+ };
+ window['MaterialSwitch'] = MaterialSwitch;
+ /**
+ * Store constants in one place so they can be updated easily.
+ *
+ * @enum {string | number}
+ * @private
+ */
+ MaterialSwitch.prototype.Constant_ = {
+ TINY_TIMEOUT: 0.001
+ };
+ /**
+ * Store strings for class names defined by this component that are used in
+ * JavaScript. This allows us to simply change it in one place should we
+ * decide to modify at a later date.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialSwitch.prototype.CssClasses_ = {
+ INPUT: 'mdl-switch__input',
+ TRACK: 'mdl-switch__track',
+ THUMB: 'mdl-switch__thumb',
+ FOCUS_HELPER: 'mdl-switch__focus-helper',
+ RIPPLE_EFFECT: 'mdl-js-ripple-effect',
+ RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
+ RIPPLE_CONTAINER: 'mdl-switch__ripple-container',
+ RIPPLE_CENTER: 'mdl-ripple--center',
+ RIPPLE: 'mdl-ripple',
+ IS_FOCUSED: 'is-focused',
+ IS_DISABLED: 'is-disabled',
+ IS_CHECKED: 'is-checked'
+ };
+ /**
+ * Handle change of state.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialSwitch.prototype.onChange_ = function (event) {
+ this.updateClasses_();
+ };
+ /**
+ * Handle focus of element.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialSwitch.prototype.onFocus_ = function (event) {
+ this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
+ };
+ /**
+ * Handle lost focus of element.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialSwitch.prototype.onBlur_ = function (event) {
+ this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
+ };
+ /**
+ * Handle mouseup.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialSwitch.prototype.onMouseUp_ = function (event) {
+ this.blur_();
+ };
+ /**
+ * Handle class updates.
+ *
+ * @private
+ */
+ MaterialSwitch.prototype.updateClasses_ = function () {
+ this.checkDisabled();
+ this.checkToggleState();
+ };
+ /**
+ * Add blur.
+ *
+ * @private
+ */
+ MaterialSwitch.prototype.blur_ = function () {
+ // TODO: figure out why there's a focus event being fired after our blur,
+ // so that we can avoid this hack.
+ window.setTimeout(function () {
+ this.inputElement_.blur();
+ }.bind(this), this.Constant_.TINY_TIMEOUT);
+ };
+ // Public methods.
+ /**
+ * Check the components disabled state.
+ *
+ * @public
+ */
+ MaterialSwitch.prototype.checkDisabled = function () {
+ if (this.inputElement_.disabled) {
+ this.element_.classList.add(this.CssClasses_.IS_DISABLED);
+ } else {
+ this.element_.classList.remove(this.CssClasses_.IS_DISABLED);
+ }
+ };
+ MaterialSwitch.prototype['checkDisabled'] = MaterialSwitch.prototype.checkDisabled;
+ /**
+ * Check the components toggled state.
+ *
+ * @public
+ */
+ MaterialSwitch.prototype.checkToggleState = function () {
+ if (this.inputElement_.checked) {
+ this.element_.classList.add(this.CssClasses_.IS_CHECKED);
+ } else {
+ this.element_.classList.remove(this.CssClasses_.IS_CHECKED);
+ }
+ };
+ MaterialSwitch.prototype['checkToggleState'] = MaterialSwitch.prototype.checkToggleState;
+ /**
+ * Disable switch.
+ *
+ * @public
+ */
+ MaterialSwitch.prototype.disable = function () {
+ this.inputElement_.disabled = true;
+ this.updateClasses_();
+ };
+ MaterialSwitch.prototype['disable'] = MaterialSwitch.prototype.disable;
+ /**
+ * Enable switch.
+ *
+ * @public
+ */
+ MaterialSwitch.prototype.enable = function () {
+ this.inputElement_.disabled = false;
+ this.updateClasses_();
+ };
+ MaterialSwitch.prototype['enable'] = MaterialSwitch.prototype.enable;
+ /**
+ * Activate switch.
+ *
+ * @public
+ */
+ MaterialSwitch.prototype.on = function () {
+ this.inputElement_.checked = true;
+ this.updateClasses_();
+ };
+ MaterialSwitch.prototype['on'] = MaterialSwitch.prototype.on;
+ /**
+ * Deactivate switch.
+ *
+ * @public
+ */
+ MaterialSwitch.prototype.off = function () {
+ this.inputElement_.checked = false;
+ this.updateClasses_();
+ };
+ MaterialSwitch.prototype['off'] = MaterialSwitch.prototype.off;
+ /**
+ * Initialize element.
+ */
+ MaterialSwitch.prototype.init = function () {
+ if (this.element_) {
+ this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT);
+ var track = document.createElement('div');
+ track.classList.add(this.CssClasses_.TRACK);
+ var thumb = document.createElement('div');
+ thumb.classList.add(this.CssClasses_.THUMB);
+ var focusHelper = document.createElement('span');
+ focusHelper.classList.add(this.CssClasses_.FOCUS_HELPER);
+ thumb.appendChild(focusHelper);
+ this.element_.appendChild(track);
+ this.element_.appendChild(thumb);
+ this.boundMouseUpHandler = this.onMouseUp_.bind(this);
+ if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {
+ this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
+ this.rippleContainerElement_ = document.createElement('span');
+ this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER);
+ this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT);
+ this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);
+ this.rippleContainerElement_.addEventListener('mouseup', this.boundMouseUpHandler);
+ var ripple = document.createElement('span');
+ ripple.classList.add(this.CssClasses_.RIPPLE);
+ this.rippleContainerElement_.appendChild(ripple);
+ this.element_.appendChild(this.rippleContainerElement_);
+ }
+ this.boundChangeHandler = this.onChange_.bind(this);
+ this.boundFocusHandler = this.onFocus_.bind(this);
+ this.boundBlurHandler = this.onBlur_.bind(this);
+ this.inputElement_.addEventListener('change', this.boundChangeHandler);
+ this.inputElement_.addEventListener('focus', this.boundFocusHandler);
+ this.inputElement_.addEventListener('blur', this.boundBlurHandler);
+ this.element_.addEventListener('mouseup', this.boundMouseUpHandler);
+ this.updateClasses_();
+ this.element_.classList.add('is-upgraded');
+ }
+ };
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ componentHandler.register({
+ constructor: MaterialSwitch,
+ classAsString: 'MaterialSwitch',
+ cssClass: 'mdl-js-switch',
+ widget: true
+ });
+ /**
+ * @license
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /**
+ * Class constructor for Tabs MDL component.
+ * Implements MDL component design pattern defined at:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @constructor
+ * @param {Element} element The element that will be upgraded.
+ */
+ var MaterialTabs = function MaterialTabs(element) {
+ // Stores the HTML element.
+ this.element_ = element;
+ // Initialize instance.
+ this.init();
+ };
+ window['MaterialTabs'] = MaterialTabs;
+ /**
+ * Store constants in one place so they can be updated easily.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialTabs.prototype.Constant_ = {};
+ /**
+ * Store strings for class names defined by this component that are used in
+ * JavaScript. This allows us to simply change it in one place should we
+ * decide to modify at a later date.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialTabs.prototype.CssClasses_ = {
+ TAB_CLASS: 'mdl-tabs__tab',
+ PANEL_CLASS: 'mdl-tabs__panel',
+ ACTIVE_CLASS: 'is-active',
+ UPGRADED_CLASS: 'is-upgraded',
+ MDL_JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect',
+ MDL_RIPPLE_CONTAINER: 'mdl-tabs__ripple-container',
+ MDL_RIPPLE: 'mdl-ripple',
+ MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events'
+ };
+ /**
+ * Handle clicks to a tabs component
+ *
+ * @private
+ */
+ MaterialTabs.prototype.initTabs_ = function () {
+ if (this.element_.classList.contains(this.CssClasses_.MDL_JS_RIPPLE_EFFECT)) {
+ this.element_.classList.add(this.CssClasses_.MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS);
+ }
+ // Select element tabs, document panels
+ this.tabs_ = this.element_.querySelectorAll('.' + this.CssClasses_.TAB_CLASS);
+ this.panels_ = this.element_.querySelectorAll('.' + this.CssClasses_.PANEL_CLASS);
+ // Create new tabs for each tab element
+ for (var i = 0; i < this.tabs_.length; i++) {
+ new MaterialTab(this.tabs_[i], this);
+ }
+ this.element_.classList.add(this.CssClasses_.UPGRADED_CLASS);
+ };
+ /**
+ * Reset tab state, dropping active classes
+ *
+ * @private
+ */
+ MaterialTabs.prototype.resetTabState_ = function () {
+ for (var k = 0; k < this.tabs_.length; k++) {
+ this.tabs_[k].classList.remove(this.CssClasses_.ACTIVE_CLASS);
+ }
+ };
+ /**
+ * Reset panel state, droping active classes
+ *
+ * @private
+ */
+ MaterialTabs.prototype.resetPanelState_ = function () {
+ for (var j = 0; j < this.panels_.length; j++) {
+ this.panels_[j].classList.remove(this.CssClasses_.ACTIVE_CLASS);
+ }
+ };
+ /**
+ * Initialize element.
+ */
+ MaterialTabs.prototype.init = function () {
+ if (this.element_) {
+ this.initTabs_();
+ }
+ };
+ /**
+ * Constructor for an individual tab.
+ *
+ * @constructor
+ * @param {Element} tab The HTML element for the tab.
+ * @param {MaterialTabs} ctx The MaterialTabs object that owns the tab.
+ */
+ function MaterialTab(tab, ctx) {
+ if (tab) {
+ if (ctx.element_.classList.contains(ctx.CssClasses_.MDL_JS_RIPPLE_EFFECT)) {
+ var rippleContainer = document.createElement('span');
+ rippleContainer.classList.add(ctx.CssClasses_.MDL_RIPPLE_CONTAINER);
+ rippleContainer.classList.add(ctx.CssClasses_.MDL_JS_RIPPLE_EFFECT);
+ var ripple = document.createElement('span');
+ ripple.classList.add(ctx.CssClasses_.MDL_RIPPLE);
+ rippleContainer.appendChild(ripple);
+ tab.appendChild(rippleContainer);
+ }
+ tab.addEventListener('click', function (e) {
+ if (tab.getAttribute('href').charAt(0) === '#') {
+ e.preventDefault();
+ var href = tab.href.split('#')[1];
+ var panel = ctx.element_.querySelector('#' + href);
+ ctx.resetTabState_();
+ ctx.resetPanelState_();
+ tab.classList.add(ctx.CssClasses_.ACTIVE_CLASS);
+ panel.classList.add(ctx.CssClasses_.ACTIVE_CLASS);
+ }
+ });
+ }
+ }
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ componentHandler.register({
+ constructor: MaterialTabs,
+ classAsString: 'MaterialTabs',
+ cssClass: 'mdl-js-tabs'
+ });
+ /**
+ * @license
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /**
+ * Class constructor for Textfield MDL component.
+ * Implements MDL component design pattern defined at:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @constructor
+ * @param {HTMLElement} element The element that will be upgraded.
+ */
+ var MaterialTextfield = function MaterialTextfield(element) {
+ this.element_ = element;
+ this.maxRows = this.Constant_.NO_MAX_ROWS;
+ // Initialize instance.
+ this.init();
+ };
+ window['MaterialTextfield'] = MaterialTextfield;
+ /**
+ * Store constants in one place so they can be updated easily.
+ *
+ * @enum {string | number}
+ * @private
+ */
+ MaterialTextfield.prototype.Constant_ = {
+ NO_MAX_ROWS: -1,
+ MAX_ROWS_ATTRIBUTE: 'maxrows'
+ };
+ /**
+ * Store strings for class names defined by this component that are used in
+ * JavaScript. This allows us to simply change it in one place should we
+ * decide to modify at a later date.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialTextfield.prototype.CssClasses_ = {
+ LABEL: 'mdl-textfield__label',
+ INPUT: 'mdl-textfield__input',
+ IS_DIRTY: 'is-dirty',
+ IS_FOCUSED: 'is-focused',
+ IS_DISABLED: 'is-disabled',
+ IS_INVALID: 'is-invalid',
+ IS_UPGRADED: 'is-upgraded',
+ HAS_PLACEHOLDER: 'has-placeholder'
+ };
+ /**
+ * Handle input being entered.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialTextfield.prototype.onKeyDown_ = function (event) {
+ var currentRowCount = event.target.value.split('\n').length;
+ if (event.keyCode === 13) {
+ if (currentRowCount >= this.maxRows) {
+ event.preventDefault();
+ }
+ }
+ };
+ /**
+ * Handle focus.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialTextfield.prototype.onFocus_ = function (event) {
+ this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
+ };
+ /**
+ * Handle lost focus.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialTextfield.prototype.onBlur_ = function (event) {
+ this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
+ };
+ /**
+ * Handle reset event from out side.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialTextfield.prototype.onReset_ = function (event) {
+ this.updateClasses_();
+ };
+ /**
+ * Handle class updates.
+ *
+ * @private
+ */
+ MaterialTextfield.prototype.updateClasses_ = function () {
+ this.checkDisabled();
+ this.checkValidity();
+ this.checkDirty();
+ this.checkFocus();
+ };
+ // Public methods.
+ /**
+ * Check the disabled state and update field accordingly.
+ *
+ * @public
+ */
+ MaterialTextfield.prototype.checkDisabled = function () {
+ if (this.input_.disabled) {
+ this.element_.classList.add(this.CssClasses_.IS_DISABLED);
+ } else {
+ this.element_.classList.remove(this.CssClasses_.IS_DISABLED);
+ }
+ };
+ MaterialTextfield.prototype['checkDisabled'] = MaterialTextfield.prototype.checkDisabled;
+ /**
+ * Check the focus state and update field accordingly.
+ *
+ * @public
+ */
+ MaterialTextfield.prototype.checkFocus = function () {
+ if (Boolean(this.element_.querySelector(':focus'))) {
+ this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
+ } else {
+ this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
+ }
+ };
+ MaterialTextfield.prototype['checkFocus'] = MaterialTextfield.prototype.checkFocus;
+ /**
+ * Check the validity state and update field accordingly.
+ *
+ * @public
+ */
+ MaterialTextfield.prototype.checkValidity = function () {
+ if (this.input_.validity) {
+ if (this.input_.validity.valid) {
+ this.element_.classList.remove(this.CssClasses_.IS_INVALID);
+ } else {
+ this.element_.classList.add(this.CssClasses_.IS_INVALID);
+ }
+ }
+ };
+ MaterialTextfield.prototype['checkValidity'] = MaterialTextfield.prototype.checkValidity;
+ /**
+ * Check the dirty state and update field accordingly.
+ *
+ * @public
+ */
+ MaterialTextfield.prototype.checkDirty = function () {
+ if (this.input_.value && this.input_.value.length > 0) {
+ this.element_.classList.add(this.CssClasses_.IS_DIRTY);
+ } else {
+ this.element_.classList.remove(this.CssClasses_.IS_DIRTY);
+ }
+ };
+ MaterialTextfield.prototype['checkDirty'] = MaterialTextfield.prototype.checkDirty;
+ /**
+ * Disable text field.
+ *
+ * @public
+ */
+ MaterialTextfield.prototype.disable = function () {
+ this.input_.disabled = true;
+ this.updateClasses_();
+ };
+ MaterialTextfield.prototype['disable'] = MaterialTextfield.prototype.disable;
+ /**
+ * Enable text field.
+ *
+ * @public
+ */
+ MaterialTextfield.prototype.enable = function () {
+ this.input_.disabled = false;
+ this.updateClasses_();
+ };
+ MaterialTextfield.prototype['enable'] = MaterialTextfield.prototype.enable;
+ /**
+ * Update text field value.
+ *
+ * @param {string} value The value to which to set the control (optional).
+ * @public
+ */
+ MaterialTextfield.prototype.change = function (value) {
+ this.input_.value = value || '';
+ this.updateClasses_();
+ };
+ MaterialTextfield.prototype['change'] = MaterialTextfield.prototype.change;
+ /**
+ * Initialize element.
+ */
+ MaterialTextfield.prototype.init = function () {
+ if (this.element_) {
+ this.label_ = this.element_.querySelector('.' + this.CssClasses_.LABEL);
+ this.input_ = this.element_.querySelector('.' + this.CssClasses_.INPUT);
+ if (this.input_) {
+ if (this.input_.hasAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE)) {
+ this.maxRows = parseInt(this.input_.getAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE), 10);
+ if (isNaN(this.maxRows)) {
+ this.maxRows = this.Constant_.NO_MAX_ROWS;
+ }
+ }
+ if (this.input_.hasAttribute('placeholder')) {
+ this.element_.classList.add(this.CssClasses_.HAS_PLACEHOLDER);
+ }
+ this.boundUpdateClassesHandler = this.updateClasses_.bind(this);
+ this.boundFocusHandler = this.onFocus_.bind(this);
+ this.boundBlurHandler = this.onBlur_.bind(this);
+ this.boundResetHandler = this.onReset_.bind(this);
+ this.input_.addEventListener('input', this.boundUpdateClassesHandler);
+ this.input_.addEventListener('focus', this.boundFocusHandler);
+ this.input_.addEventListener('blur', this.boundBlurHandler);
+ this.input_.addEventListener('reset', this.boundResetHandler);
+ if (this.maxRows !== this.Constant_.NO_MAX_ROWS) {
+ // TODO: This should handle pasting multi line text.
+ // Currently doesn't.
+ this.boundKeyDownHandler = this.onKeyDown_.bind(this);
+ this.input_.addEventListener('keydown', this.boundKeyDownHandler);
+ }
+ var invalid = this.element_.classList.contains(this.CssClasses_.IS_INVALID);
+ this.updateClasses_();
+ this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
+ if (invalid) {
+ this.element_.classList.add(this.CssClasses_.IS_INVALID);
+ }
+ if (this.input_.hasAttribute('autofocus')) {
+ this.element_.focus();
+ this.checkFocus();
+ }
+ }
+ }
+ };
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ componentHandler.register({
+ constructor: MaterialTextfield,
+ classAsString: 'MaterialTextfield',
+ cssClass: 'mdl-js-textfield',
+ widget: true
+ });
+ /**
+ * @license
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /**
+ * Class constructor for Tooltip MDL component.
+ * Implements MDL component design pattern defined at:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @constructor
+ * @param {HTMLElement} element The element that will be upgraded.
+ */
+ var MaterialTooltip = function MaterialTooltip(element) {
+ this.element_ = element;
+ // Initialize instance.
+ this.init();
+ };
+ window['MaterialTooltip'] = MaterialTooltip;
+ /**
+ * Store constants in one place so they can be updated easily.
+ *
+ * @enum {string | number}
+ * @private
+ */
+ MaterialTooltip.prototype.Constant_ = {};
+ /**
+ * Store strings for class names defined by this component that are used in
+ * JavaScript. This allows us to simply change it in one place should we
+ * decide to modify at a later date.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialTooltip.prototype.CssClasses_ = {
+ IS_ACTIVE: 'is-active',
+ BOTTOM: 'mdl-tooltip--bottom',
+ LEFT: 'mdl-tooltip--left',
+ RIGHT: 'mdl-tooltip--right',
+ TOP: 'mdl-tooltip--top'
+ };
+ /**
+ * Handle mouseenter for tooltip.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialTooltip.prototype.handleMouseEnter_ = function (event) {
+ var props = event.target.getBoundingClientRect();
+ var left = props.left + props.width / 2;
+ var top = props.top + props.height / 2;
+ var marginLeft = -1 * (this.element_.offsetWidth / 2);
+ var marginTop = -1 * (this.element_.offsetHeight / 2);
+ if (this.element_.classList.contains(this.CssClasses_.LEFT) || this.element_.classList.contains(this.CssClasses_.RIGHT)) {
+ left = props.width / 2;
+ if (top + marginTop < 0) {
+ this.element_.style.top = '0';
+ this.element_.style.marginTop = '0';
+ } else {
+ this.element_.style.top = top + 'px';
+ this.element_.style.marginTop = marginTop + 'px';
+ }
+ } else {
+ if (left + marginLeft < 0) {
+ this.element_.style.left = '0';
+ this.element_.style.marginLeft = '0';
+ } else {
+ this.element_.style.left = left + 'px';
+ this.element_.style.marginLeft = marginLeft + 'px';
+ }
+ }
+ if (this.element_.classList.contains(this.CssClasses_.TOP)) {
+ this.element_.style.top = props.top - this.element_.offsetHeight - 10 + 'px';
+ } else if (this.element_.classList.contains(this.CssClasses_.RIGHT)) {
+ this.element_.style.left = props.left + props.width + 10 + 'px';
+ } else if (this.element_.classList.contains(this.CssClasses_.LEFT)) {
+ this.element_.style.left = props.left - this.element_.offsetWidth - 10 + 'px';
+ } else {
+ this.element_.style.top = props.top + props.height + 10 + 'px';
+ }
+ this.element_.classList.add(this.CssClasses_.IS_ACTIVE);
+ };
+ /**
+ * Hide tooltip on mouseleave or scroll
+ *
+ * @private
+ */
+ MaterialTooltip.prototype.hideTooltip_ = function () {
+ this.element_.classList.remove(this.CssClasses_.IS_ACTIVE);
+ };
+ /**
+ * Initialize element.
+ */
+ MaterialTooltip.prototype.init = function () {
+ if (this.element_) {
+ var forElId = this.element_.getAttribute('for') || this.element_.getAttribute('data-mdl-for');
+ if (forElId) {
+ this.forElement_ = document.getElementById(forElId);
+ }
+ if (this.forElement_) {
+ // It's left here because it prevents accidental text selection on Android
+ if (!this.forElement_.hasAttribute('tabindex')) {
+ this.forElement_.setAttribute('tabindex', '0');
+ }
+ this.boundMouseEnterHandler = this.handleMouseEnter_.bind(this);
+ this.boundMouseLeaveAndScrollHandler = this.hideTooltip_.bind(this);
+ this.forElement_.addEventListener('mouseenter', this.boundMouseEnterHandler, false);
+ this.forElement_.addEventListener('touchend', this.boundMouseEnterHandler, false);
+ this.forElement_.addEventListener('mouseleave', this.boundMouseLeaveAndScrollHandler, false);
+ window.addEventListener('scroll', this.boundMouseLeaveAndScrollHandler, true);
+ window.addEventListener('touchstart', this.boundMouseLeaveAndScrollHandler);
+ }
+ }
+ };
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ componentHandler.register({
+ constructor: MaterialTooltip,
+ classAsString: 'MaterialTooltip',
+ cssClass: 'mdl-tooltip'
+ });
+ /**
+ * @license
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /**
+ * Class constructor for Layout MDL component.
+ * Implements MDL component design pattern defined at:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @constructor
+ * @param {HTMLElement} element The element that will be upgraded.
+ */
+ var MaterialLayout = function MaterialLayout(element) {
+ this.element_ = element;
+ // Initialize instance.
+ this.init();
+ };
+ window['MaterialLayout'] = MaterialLayout;
+ /**
+ * Store constants in one place so they can be updated easily.
+ *
+ * @enum {string | number}
+ * @private
+ */
+ MaterialLayout.prototype.Constant_ = {
+ MAX_WIDTH: '(max-width: 900px)',
+ TAB_SCROLL_PIXELS: 100,
+ RESIZE_TIMEOUT: 100,
+ MENU_ICON: '&#xE5D2;',
+ CHEVRON_LEFT: 'chevron_left',
+ CHEVRON_RIGHT: 'chevron_right'
+ };
+ /**
+ * Keycodes, for code readability.
+ *
+ * @enum {number}
+ * @private
+ */
+ MaterialLayout.prototype.Keycodes_ = {
+ ENTER: 13,
+ ESCAPE: 27,
+ SPACE: 32
+ };
+ /**
+ * Modes.
+ *
+ * @enum {number}
+ * @private
+ */
+ MaterialLayout.prototype.Mode_ = {
+ STANDARD: 0,
+ SEAMED: 1,
+ WATERFALL: 2,
+ SCROLL: 3
+ };
+ /**
+ * Store strings for class names defined by this component that are used in
+ * JavaScript. This allows us to simply change it in one place should we
+ * decide to modify at a later date.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialLayout.prototype.CssClasses_ = {
+ CONTAINER: 'mdl-layout__container',
+ HEADER: 'mdl-layout__header',
+ DRAWER: 'mdl-layout__drawer',
+ CONTENT: 'mdl-layout__content',
+ DRAWER_BTN: 'mdl-layout__drawer-button',
+ ICON: 'material-icons',
+ JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect',
+ RIPPLE_CONTAINER: 'mdl-layout__tab-ripple-container',
+ RIPPLE: 'mdl-ripple',
+ RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
+ HEADER_SEAMED: 'mdl-layout__header--seamed',
+ HEADER_WATERFALL: 'mdl-layout__header--waterfall',
+ HEADER_SCROLL: 'mdl-layout__header--scroll',
+ FIXED_HEADER: 'mdl-layout--fixed-header',
+ OBFUSCATOR: 'mdl-layout__obfuscator',
+ TAB_BAR: 'mdl-layout__tab-bar',
+ TAB_CONTAINER: 'mdl-layout__tab-bar-container',
+ TAB: 'mdl-layout__tab',
+ TAB_BAR_BUTTON: 'mdl-layout__tab-bar-button',
+ TAB_BAR_LEFT_BUTTON: 'mdl-layout__tab-bar-left-button',
+ TAB_BAR_RIGHT_BUTTON: 'mdl-layout__tab-bar-right-button',
+ TAB_MANUAL_SWITCH: 'mdl-layout__tab-manual-switch',
+ PANEL: 'mdl-layout__tab-panel',
+ HAS_DRAWER: 'has-drawer',
+ HAS_TABS: 'has-tabs',
+ HAS_SCROLLING_HEADER: 'has-scrolling-header',
+ CASTING_SHADOW: 'is-casting-shadow',
+ IS_COMPACT: 'is-compact',
+ IS_SMALL_SCREEN: 'is-small-screen',
+ IS_DRAWER_OPEN: 'is-visible',
+ IS_ACTIVE: 'is-active',
+ IS_UPGRADED: 'is-upgraded',
+ IS_ANIMATING: 'is-animating',
+ ON_LARGE_SCREEN: 'mdl-layout--large-screen-only',
+ ON_SMALL_SCREEN: 'mdl-layout--small-screen-only'
+ };
+ /**
+ * Handles scrolling on the content.
+ *
+ * @private
+ */
+ MaterialLayout.prototype.contentScrollHandler_ = function () {
+ if (this.header_.classList.contains(this.CssClasses_.IS_ANIMATING)) {
+ return;
+ }
+ var headerVisible = !this.element_.classList.contains(this.CssClasses_.IS_SMALL_SCREEN) || this.element_.classList.contains(this.CssClasses_.FIXED_HEADER);
+ if (this.content_.scrollTop > 0 && !this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {
+ this.header_.classList.add(this.CssClasses_.CASTING_SHADOW);
+ this.header_.classList.add(this.CssClasses_.IS_COMPACT);
+ if (headerVisible) {
+ this.header_.classList.add(this.CssClasses_.IS_ANIMATING);
+ }
+ } else if (this.content_.scrollTop <= 0 && this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {
+ this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW);
+ this.header_.classList.remove(this.CssClasses_.IS_COMPACT);
+ if (headerVisible) {
+ this.header_.classList.add(this.CssClasses_.IS_ANIMATING);
+ }
+ }
+ };
+ /**
+ * Handles a keyboard event on the drawer.
+ *
+ * @param {Event} evt The event that fired.
+ * @private
+ */
+ MaterialLayout.prototype.keyboardEventHandler_ = function (evt) {
+ // Only react when the drawer is open.
+ if (evt.keyCode === this.Keycodes_.ESCAPE && this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)) {
+ this.toggleDrawer();
+ }
+ };
+ /**
+ * Handles changes in screen size.
+ *
+ * @private
+ */
+ MaterialLayout.prototype.screenSizeHandler_ = function () {
+ if (this.screenSizeMediaQuery_.matches) {
+ this.element_.classList.add(this.CssClasses_.IS_SMALL_SCREEN);
+ } else {
+ this.element_.classList.remove(this.CssClasses_.IS_SMALL_SCREEN);
+ // Collapse drawer (if any) when moving to a large screen size.
+ if (this.drawer_) {
+ this.drawer_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN);
+ this.obfuscator_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN);
+ }
+ }
+ };
+ /**
+ * Handles events of drawer button.
+ *
+ * @param {Event} evt The event that fired.
+ * @private
+ */
+ MaterialLayout.prototype.drawerToggleHandler_ = function (evt) {
+ if (evt && evt.type === 'keydown') {
+ if (evt.keyCode === this.Keycodes_.SPACE || evt.keyCode === this.Keycodes_.ENTER) {
+ // prevent scrolling in drawer nav
+ evt.preventDefault();
+ } else {
+ // prevent other keys
+ return;
+ }
+ }
+ this.toggleDrawer();
+ };
+ /**
+ * Handles (un)setting the `is-animating` class
+ *
+ * @private
+ */
+ MaterialLayout.prototype.headerTransitionEndHandler_ = function () {
+ this.header_.classList.remove(this.CssClasses_.IS_ANIMATING);
+ };
+ /**
+ * Handles expanding the header on click
+ *
+ * @private
+ */
+ MaterialLayout.prototype.headerClickHandler_ = function () {
+ if (this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {
+ this.header_.classList.remove(this.CssClasses_.IS_COMPACT);
+ this.header_.classList.add(this.CssClasses_.IS_ANIMATING);
+ }
+ };
+ /**
+ * Reset tab state, dropping active classes
+ *
+ * @private
+ */
+ MaterialLayout.prototype.resetTabState_ = function (tabBar) {
+ for (var k = 0; k < tabBar.length; k++) {
+ tabBar[k].classList.remove(this.CssClasses_.IS_ACTIVE);
+ }
+ };
+ /**
+ * Reset panel state, droping active classes
+ *
+ * @private
+ */
+ MaterialLayout.prototype.resetPanelState_ = function (panels) {
+ for (var j = 0; j < panels.length; j++) {
+ panels[j].classList.remove(this.CssClasses_.IS_ACTIVE);
+ }
+ };
+ /**
+ * Toggle drawer state
+ *
+ * @public
+ */
+ MaterialLayout.prototype.toggleDrawer = function () {
+ var drawerButton = this.element_.querySelector('.' + this.CssClasses_.DRAWER_BTN);
+ this.drawer_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN);
+ this.obfuscator_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN);
+ // Set accessibility properties.
+ if (this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)) {
+ this.drawer_.setAttribute('aria-hidden', 'false');
+ drawerButton.setAttribute('aria-expanded', 'true');
+ } else {
+ this.drawer_.setAttribute('aria-hidden', 'true');
+ drawerButton.setAttribute('aria-expanded', 'false');
+ }
+ };
+ MaterialLayout.prototype['toggleDrawer'] = MaterialLayout.prototype.toggleDrawer;
+ /**
+ * Initialize element.
+ */
+ MaterialLayout.prototype.init = function () {
+ if (this.element_) {
+ var container = document.createElement('div');
+ container.classList.add(this.CssClasses_.CONTAINER);
+ var focusedElement = this.element_.querySelector(':focus');
+ this.element_.parentElement.insertBefore(container, this.element_);
+ this.element_.parentElement.removeChild(this.element_);
+ container.appendChild(this.element_);
+ if (focusedElement) {
+ focusedElement.focus();
+ }
+ var directChildren = this.element_.childNodes;
+ var numChildren = directChildren.length;
+ for (var c = 0; c < numChildren; c++) {
+ var child = directChildren[c];
+ if (child.classList && child.classList.contains(this.CssClasses_.HEADER)) {
+ this.header_ = child;
+ }
+ if (child.classList && child.classList.contains(this.CssClasses_.DRAWER)) {
+ this.drawer_ = child;
+ }
+ if (child.classList && child.classList.contains(this.CssClasses_.CONTENT)) {
+ this.content_ = child;
+ }
+ }
+ window.addEventListener('pageshow', function (e) {
+ if (e.persisted) {
+ // when page is loaded from back/forward cache
+ // trigger repaint to let layout scroll in safari
+ this.element_.style.overflowY = 'hidden';
+ requestAnimationFrame(function () {
+ this.element_.style.overflowY = '';
+ }.bind(this));
+ }
+ }.bind(this), false);
+ if (this.header_) {
+ this.tabBar_ = this.header_.querySelector('.' + this.CssClasses_.TAB_BAR);
+ }
+ var mode = this.Mode_.STANDARD;
+ if (this.header_) {
+ if (this.header_.classList.contains(this.CssClasses_.HEADER_SEAMED)) {
+ mode = this.Mode_.SEAMED;
+ } else if (this.header_.classList.contains(this.CssClasses_.HEADER_WATERFALL)) {
+ mode = this.Mode_.WATERFALL;
+ this.header_.addEventListener('transitionend', this.headerTransitionEndHandler_.bind(this));
+ this.header_.addEventListener('click', this.headerClickHandler_.bind(this));
+ } else if (this.header_.classList.contains(this.CssClasses_.HEADER_SCROLL)) {
+ mode = this.Mode_.SCROLL;
+ container.classList.add(this.CssClasses_.HAS_SCROLLING_HEADER);
+ }
+ if (mode === this.Mode_.STANDARD) {
+ this.header_.classList.add(this.CssClasses_.CASTING_SHADOW);
+ if (this.tabBar_) {
+ this.tabBar_.classList.add(this.CssClasses_.CASTING_SHADOW);
+ }
+ } else if (mode === this.Mode_.SEAMED || mode === this.Mode_.SCROLL) {
+ this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW);
+ if (this.tabBar_) {
+ this.tabBar_.classList.remove(this.CssClasses_.CASTING_SHADOW);
+ }
+ } else if (mode === this.Mode_.WATERFALL) {
+ // Add and remove shadows depending on scroll position.
+ // Also add/remove auxiliary class for styling of the compact version of
+ // the header.
+ this.content_.addEventListener('scroll', this.contentScrollHandler_.bind(this));
+ this.contentScrollHandler_();
+ }
+ }
+ // Add drawer toggling button to our layout, if we have an openable drawer.
+ if (this.drawer_) {
+ var drawerButton = this.element_.querySelector('.' + this.CssClasses_.DRAWER_BTN);
+ if (!drawerButton) {
+ drawerButton = document.createElement('div');
+ drawerButton.setAttribute('aria-expanded', 'false');
+ drawerButton.setAttribute('role', 'button');
+ drawerButton.setAttribute('tabindex', '0');
+ drawerButton.classList.add(this.CssClasses_.DRAWER_BTN);
+ var drawerButtonIcon = document.createElement('i');
+ drawerButtonIcon.classList.add(this.CssClasses_.ICON);
+ drawerButtonIcon.innerHTML = this.Constant_.MENU_ICON;
+ drawerButton.appendChild(drawerButtonIcon);
+ }
+ if (this.drawer_.classList.contains(this.CssClasses_.ON_LARGE_SCREEN)) {
+ //If drawer has ON_LARGE_SCREEN class then add it to the drawer toggle button as well.
+ drawerButton.classList.add(this.CssClasses_.ON_LARGE_SCREEN);
+ } else if (this.drawer_.classList.contains(this.CssClasses_.ON_SMALL_SCREEN)) {
+ //If drawer has ON_SMALL_SCREEN class then add it to the drawer toggle button as well.
+ drawerButton.classList.add(this.CssClasses_.ON_SMALL_SCREEN);
+ }
+ drawerButton.addEventListener('click', this.drawerToggleHandler_.bind(this));
+ drawerButton.addEventListener('keydown', this.drawerToggleHandler_.bind(this));
+ // Add a class if the layout has a drawer, for altering the left padding.
+ // Adds the HAS_DRAWER to the elements since this.header_ may or may
+ // not be present.
+ this.element_.classList.add(this.CssClasses_.HAS_DRAWER);
+ // If we have a fixed header, add the button to the header rather than
+ // the layout.
+ if (this.element_.classList.contains(this.CssClasses_.FIXED_HEADER)) {
+ this.header_.insertBefore(drawerButton, this.header_.firstChild);
+ } else {
+ this.element_.insertBefore(drawerButton, this.content_);
+ }
+ var obfuscator = document.createElement('div');
+ obfuscator.classList.add(this.CssClasses_.OBFUSCATOR);
+ this.element_.appendChild(obfuscator);
+ obfuscator.addEventListener('click', this.drawerToggleHandler_.bind(this));
+ this.obfuscator_ = obfuscator;
+ this.drawer_.addEventListener('keydown', this.keyboardEventHandler_.bind(this));
+ this.drawer_.setAttribute('aria-hidden', 'true');
+ }
+ // Keep an eye on screen size, and add/remove auxiliary class for styling
+ // of small screens.
+ this.screenSizeMediaQuery_ = window.matchMedia(this.Constant_.MAX_WIDTH);
+ this.screenSizeMediaQuery_.addListener(this.screenSizeHandler_.bind(this));
+ this.screenSizeHandler_();
+ // Initialize tabs, if any.
+ if (this.header_ && this.tabBar_) {
+ this.element_.classList.add(this.CssClasses_.HAS_TABS);
+ var tabContainer = document.createElement('div');
+ tabContainer.classList.add(this.CssClasses_.TAB_CONTAINER);
+ this.header_.insertBefore(tabContainer, this.tabBar_);
+ this.header_.removeChild(this.tabBar_);
+ var leftButton = document.createElement('div');
+ leftButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON);
+ leftButton.classList.add(this.CssClasses_.TAB_BAR_LEFT_BUTTON);
+ var leftButtonIcon = document.createElement('i');
+ leftButtonIcon.classList.add(this.CssClasses_.ICON);
+ leftButtonIcon.textContent = this.Constant_.CHEVRON_LEFT;
+ leftButton.appendChild(leftButtonIcon);
+ leftButton.addEventListener('click', function () {
+ this.tabBar_.scrollLeft -= this.Constant_.TAB_SCROLL_PIXELS;
+ }.bind(this));
+ var rightButton = document.createElement('div');
+ rightButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON);
+ rightButton.classList.add(this.CssClasses_.TAB_BAR_RIGHT_BUTTON);
+ var rightButtonIcon = document.createElement('i');
+ rightButtonIcon.classList.add(this.CssClasses_.ICON);
+ rightButtonIcon.textContent = this.Constant_.CHEVRON_RIGHT;
+ rightButton.appendChild(rightButtonIcon);
+ rightButton.addEventListener('click', function () {
+ this.tabBar_.scrollLeft += this.Constant_.TAB_SCROLL_PIXELS;
+ }.bind(this));
+ tabContainer.appendChild(leftButton);
+ tabContainer.appendChild(this.tabBar_);
+ tabContainer.appendChild(rightButton);
+ // Add and remove tab buttons depending on scroll position and total
+ // window size.
+ var tabUpdateHandler = function () {
+ if (this.tabBar_.scrollLeft > 0) {
+ leftButton.classList.add(this.CssClasses_.IS_ACTIVE);
+ } else {
+ leftButton.classList.remove(this.CssClasses_.IS_ACTIVE);
+ }
+ if (this.tabBar_.scrollLeft < this.tabBar_.scrollWidth - this.tabBar_.offsetWidth) {
+ rightButton.classList.add(this.CssClasses_.IS_ACTIVE);
+ } else {
+ rightButton.classList.remove(this.CssClasses_.IS_ACTIVE);
+ }
+ }.bind(this);
+ this.tabBar_.addEventListener('scroll', tabUpdateHandler);
+ tabUpdateHandler();
+ // Update tabs when the window resizes.
+ var windowResizeHandler = function () {
+ // Use timeouts to make sure it doesn't happen too often.
+ if (this.resizeTimeoutId_) {
+ clearTimeout(this.resizeTimeoutId_);
+ }
+ this.resizeTimeoutId_ = setTimeout(function () {
+ tabUpdateHandler();
+ this.resizeTimeoutId_ = null;
+ }.bind(this), this.Constant_.RESIZE_TIMEOUT);
+ }.bind(this);
+ window.addEventListener('resize', windowResizeHandler);
+ if (this.tabBar_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) {
+ this.tabBar_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
+ }
+ // Select element tabs, document panels
+ var tabs = this.tabBar_.querySelectorAll('.' + this.CssClasses_.TAB);
+ var panels = this.content_.querySelectorAll('.' + this.CssClasses_.PANEL);
+ // Create new tabs for each tab element
+ for (var i = 0; i < tabs.length; i++) {
+ new MaterialLayoutTab(tabs[i], tabs, panels, this);
+ }
+ }
+ this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
+ }
+ };
+ /**
+ * Constructor for an individual tab.
+ *
+ * @constructor
+ * @param {HTMLElement} tab The HTML element for the tab.
+ * @param {!Array<HTMLElement>} tabs Array with HTML elements for all tabs.
+ * @param {!Array<HTMLElement>} panels Array with HTML elements for all panels.
+ * @param {MaterialLayout} layout The MaterialLayout object that owns the tab.
+ */
+ function MaterialLayoutTab(tab, tabs, panels, layout) {
+ /**
+ * Auxiliary method to programmatically select a tab in the UI.
+ */
+ function selectTab() {
+ var href = tab.href.split('#')[1];
+ var panel = layout.content_.querySelector('#' + href);
+ layout.resetTabState_(tabs);
+ layout.resetPanelState_(panels);
+ tab.classList.add(layout.CssClasses_.IS_ACTIVE);
+ panel.classList.add(layout.CssClasses_.IS_ACTIVE);
+ }
+ if (layout.tabBar_.classList.contains(layout.CssClasses_.JS_RIPPLE_EFFECT)) {
+ var rippleContainer = document.createElement('span');
+ rippleContainer.classList.add(layout.CssClasses_.RIPPLE_CONTAINER);
+ rippleContainer.classList.add(layout.CssClasses_.JS_RIPPLE_EFFECT);
+ var ripple = document.createElement('span');
+ ripple.classList.add(layout.CssClasses_.RIPPLE);
+ rippleContainer.appendChild(ripple);
+ tab.appendChild(rippleContainer);
+ }
+ if (!layout.tabBar_.classList.contains(layout.CssClasses_.TAB_MANUAL_SWITCH)) {
+ tab.addEventListener('click', function (e) {
+ if (tab.getAttribute('href').charAt(0) === '#') {
+ e.preventDefault();
+ selectTab();
+ }
+ });
+ }
+ tab.show = selectTab;
+ }
+ window['MaterialLayoutTab'] = MaterialLayoutTab;
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ componentHandler.register({
+ constructor: MaterialLayout,
+ classAsString: 'MaterialLayout',
+ cssClass: 'mdl-js-layout'
+ });
+ /**
+ * @license
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /**
+ * Class constructor for Data Table Card MDL component.
+ * Implements MDL component design pattern defined at:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @constructor
+ * @param {Element} element The element that will be upgraded.
+ */
+ var MaterialDataTable = function MaterialDataTable(element) {
+ this.element_ = element;
+ // Initialize instance.
+ this.init();
+ };
+ window['MaterialDataTable'] = MaterialDataTable;
+ /**
+ * Store constants in one place so they can be updated easily.
+ *
+ * @enum {string | number}
+ * @private
+ */
+ MaterialDataTable.prototype.Constant_ = {};
+ /**
+ * Store strings for class names defined by this component that are used in
+ * JavaScript. This allows us to simply change it in one place should we
+ * decide to modify at a later date.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialDataTable.prototype.CssClasses_ = {
+ DATA_TABLE: 'mdl-data-table',
+ SELECTABLE: 'mdl-data-table--selectable',
+ SELECT_ELEMENT: 'mdl-data-table__select',
+ IS_SELECTED: 'is-selected',
+ IS_UPGRADED: 'is-upgraded'
+ };
+ /**
+ * Generates and returns a function that toggles the selection state of a
+ * single row (or multiple rows).
+ *
+ * @param {Element} checkbox Checkbox that toggles the selection state.
+ * @param {Element} row Row to toggle when checkbox changes.
+ * @param {(Array<Object>|NodeList)=} opt_rows Rows to toggle when checkbox changes.
+ * @private
+ */
+ MaterialDataTable.prototype.selectRow_ = function (checkbox, row, opt_rows) {
+ if (row) {
+ return function () {
+ if (checkbox.checked) {
+ row.classList.add(this.CssClasses_.IS_SELECTED);
+ } else {
+ row.classList.remove(this.CssClasses_.IS_SELECTED);
+ }
+ }.bind(this);
+ }
+ if (opt_rows) {
+ return function () {
+ var i;
+ var el;
+ if (checkbox.checked) {
+ for (i = 0; i < opt_rows.length; i++) {
+ el = opt_rows[i].querySelector('td').querySelector('.mdl-checkbox');
+ el['MaterialCheckbox'].check();
+ opt_rows[i].classList.add(this.CssClasses_.IS_SELECTED);
+ }
+ } else {
+ for (i = 0; i < opt_rows.length; i++) {
+ el = opt_rows[i].querySelector('td').querySelector('.mdl-checkbox');
+ el['MaterialCheckbox'].uncheck();
+ opt_rows[i].classList.remove(this.CssClasses_.IS_SELECTED);
+ }
+ }
+ }.bind(this);
+ }
+ };
+ /**
+ * Creates a checkbox for a single or or multiple rows and hooks up the
+ * event handling.
+ *
+ * @param {Element} row Row to toggle when checkbox changes.
+ * @param {(Array<Object>|NodeList)=} opt_rows Rows to toggle when checkbox changes.
+ * @private
+ */
+ MaterialDataTable.prototype.createCheckbox_ = function (row, opt_rows) {
+ var label = document.createElement('label');
+ var labelClasses = [
+ 'mdl-checkbox',
+ 'mdl-js-checkbox',
+ 'mdl-js-ripple-effect',
+ this.CssClasses_.SELECT_ELEMENT
+ ];
+ label.className = labelClasses.join(' ');
+ var checkbox = document.createElement('input');
+ checkbox.type = 'checkbox';
+ checkbox.classList.add('mdl-checkbox__input');
+ if (row) {
+ checkbox.checked = row.classList.contains(this.CssClasses_.IS_SELECTED);
+ checkbox.addEventListener('change', this.selectRow_(checkbox, row));
+ } else if (opt_rows) {
+ checkbox.addEventListener('change', this.selectRow_(checkbox, null, opt_rows));
+ }
+ label.appendChild(checkbox);
+ componentHandler.upgradeElement(label, 'MaterialCheckbox');
+ return label;
+ };
+ /**
+ * Initialize element.
+ */
+ MaterialDataTable.prototype.init = function () {
+ if (this.element_) {
+ var firstHeader = this.element_.querySelector('th');
+ var bodyRows = Array.prototype.slice.call(this.element_.querySelectorAll('tbody tr'));
+ var footRows = Array.prototype.slice.call(this.element_.querySelectorAll('tfoot tr'));
+ var rows = bodyRows.concat(footRows);
+ if (this.element_.classList.contains(this.CssClasses_.SELECTABLE)) {
+ var th = document.createElement('th');
+ var headerCheckbox = this.createCheckbox_(null, rows);
+ th.appendChild(headerCheckbox);
+ firstHeader.parentElement.insertBefore(th, firstHeader);
+ for (var i = 0; i < rows.length; i++) {
+ var firstCell = rows[i].querySelector('td');
+ if (firstCell) {
+ var td = document.createElement('td');
+ if (rows[i].parentNode.nodeName.toUpperCase() === 'TBODY') {
+ var rowCheckbox = this.createCheckbox_(rows[i]);
+ td.appendChild(rowCheckbox);
+ }
+ rows[i].insertBefore(td, firstCell);
+ }
+ }
+ this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
+ }
+ }
+ };
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ componentHandler.register({
+ constructor: MaterialDataTable,
+ classAsString: 'MaterialDataTable',
+ cssClass: 'mdl-js-data-table'
+ });
+ /**
+ * @license
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ /**
+ * Class constructor for Ripple MDL component.
+ * Implements MDL component design pattern defined at:
+ * https://github.com/jasonmayes/mdl-component-design-pattern
+ *
+ * @constructor
+ * @param {HTMLElement} element The element that will be upgraded.
+ */
+ var MaterialRipple = function MaterialRipple(element) {
+ this.element_ = element;
+ // Initialize instance.
+ this.init();
+ };
+ window['MaterialRipple'] = MaterialRipple;
+ /**
+ * Store constants in one place so they can be updated easily.
+ *
+ * @enum {string | number}
+ * @private
+ */
+ MaterialRipple.prototype.Constant_ = {
+ INITIAL_SCALE: 'scale(0.0001, 0.0001)',
+ INITIAL_SIZE: '1px',
+ INITIAL_OPACITY: '0.4',
+ FINAL_OPACITY: '0',
+ FINAL_SCALE: ''
+ };
+ /**
+ * Store strings for class names defined by this component that are used in
+ * JavaScript. This allows us to simply change it in one place should we
+ * decide to modify at a later date.
+ *
+ * @enum {string}
+ * @private
+ */
+ MaterialRipple.prototype.CssClasses_ = {
+ RIPPLE_CENTER: 'mdl-ripple--center',
+ RIPPLE_EFFECT_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
+ RIPPLE: 'mdl-ripple',
+ IS_ANIMATING: 'is-animating',
+ IS_VISIBLE: 'is-visible'
+ };
+ /**
+ * Handle mouse / finger down on element.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialRipple.prototype.downHandler_ = function (event) {
+ if (!this.rippleElement_.style.width && !this.rippleElement_.style.height) {
+ var rect = this.element_.getBoundingClientRect();
+ this.boundHeight = rect.height;
+ this.boundWidth = rect.width;
+ this.rippleSize_ = Math.sqrt(rect.width * rect.width + rect.height * rect.height) * 2 + 2;
+ this.rippleElement_.style.width = this.rippleSize_ + 'px';
+ this.rippleElement_.style.height = this.rippleSize_ + 'px';
+ }
+ this.rippleElement_.classList.add(this.CssClasses_.IS_VISIBLE);
+ if (event.type === 'mousedown' && this.ignoringMouseDown_) {
+ this.ignoringMouseDown_ = false;
+ } else {
+ if (event.type === 'touchstart') {
+ this.ignoringMouseDown_ = true;
+ }
+ var frameCount = this.getFrameCount();
+ if (frameCount > 0) {
+ return;
+ }
+ this.setFrameCount(1);
+ var bound = event.currentTarget.getBoundingClientRect();
+ var x;
+ var y;
+ // Check if we are handling a keyboard click.
+ if (event.clientX === 0 && event.clientY === 0) {
+ x = Math.round(bound.width / 2);
+ y = Math.round(bound.height / 2);
+ } else {
+ var clientX = event.clientX !== undefined ? event.clientX : event.touches[0].clientX;
+ var clientY = event.clientY !== undefined ? event.clientY : event.touches[0].clientY;
+ x = Math.round(clientX - bound.left);
+ y = Math.round(clientY - bound.top);
+ }
+ this.setRippleXY(x, y);
+ this.setRippleStyles(true);
+ window.requestAnimationFrame(this.animFrameHandler.bind(this));
+ }
+ };
+ /**
+ * Handle mouse / finger up on element.
+ *
+ * @param {Event} event The event that fired.
+ * @private
+ */
+ MaterialRipple.prototype.upHandler_ = function (event) {
+ // Don't fire for the artificial "mouseup" generated by a double-click.
+ if (event && event.detail !== 2) {
+ // Allow a repaint to occur before removing this class, so the animation
+ // shows for tap events, which seem to trigger a mouseup too soon after
+ // mousedown.
+ window.setTimeout(function () {
+ this.rippleElement_.classList.remove(this.CssClasses_.IS_VISIBLE);
+ }.bind(this), 0);
+ }
+ };
+ /**
+ * Initialize element.
+ */
+ MaterialRipple.prototype.init = function () {
+ if (this.element_) {
+ var recentering = this.element_.classList.contains(this.CssClasses_.RIPPLE_CENTER);
+ if (!this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT_IGNORE_EVENTS)) {
+ this.rippleElement_ = this.element_.querySelector('.' + this.CssClasses_.RIPPLE);
+ this.frameCount_ = 0;
+ this.rippleSize_ = 0;
+ this.x_ = 0;
+ this.y_ = 0;
+ // Touch start produces a compat mouse down event, which would cause a
+ // second ripples. To avoid that, we use this property to ignore the first
+ // mouse down after a touch start.
+ this.ignoringMouseDown_ = false;
+ this.boundDownHandler = this.downHandler_.bind(this);
+ this.element_.addEventListener('mousedown', this.boundDownHandler);
+ this.element_.addEventListener('touchstart', this.boundDownHandler);
+ this.boundUpHandler = this.upHandler_.bind(this);
+ this.element_.addEventListener('mouseup', this.boundUpHandler);
+ this.element_.addEventListener('mouseleave', this.boundUpHandler);
+ this.element_.addEventListener('touchend', this.boundUpHandler);
+ this.element_.addEventListener('blur', this.boundUpHandler);
+ /**
+ * Getter for frameCount_.
+ * @return {number} the frame count.
+ */
+ this.getFrameCount = function () {
+ return this.frameCount_;
+ };
+ /**
+ * Setter for frameCount_.
+ * @param {number} fC the frame count.
+ */
+ this.setFrameCount = function (fC) {
+ this.frameCount_ = fC;
+ };
+ /**
+ * Getter for rippleElement_.
+ * @return {Element} the ripple element.
+ */
+ this.getRippleElement = function () {
+ return this.rippleElement_;
+ };
+ /**
+ * Sets the ripple X and Y coordinates.
+ * @param {number} newX the new X coordinate
+ * @param {number} newY the new Y coordinate
+ */
+ this.setRippleXY = function (newX, newY) {
+ this.x_ = newX;
+ this.y_ = newY;
+ };
+ /**
+ * Sets the ripple styles.
+ * @param {boolean} start whether or not this is the start frame.
+ */
+ this.setRippleStyles = function (start) {
+ if (this.rippleElement_ !== null) {
+ var transformString;
+ var scale;
+ var size;
+ var offset = 'translate(' + this.x_ + 'px, ' + this.y_ + 'px)';
+ if (start) {
+ scale = this.Constant_.INITIAL_SCALE;
+ size = this.Constant_.INITIAL_SIZE;
+ } else {
+ scale = this.Constant_.FINAL_SCALE;
+ size = this.rippleSize_ + 'px';
+ if (recentering) {
+ offset = 'translate(' + this.boundWidth / 2 + 'px, ' + this.boundHeight / 2 + 'px)';
+ }
+ }
+ transformString = 'translate(-50%, -50%) ' + offset + scale;
+ this.rippleElement_.style.webkitTransform = transformString;
+ this.rippleElement_.style.msTransform = transformString;
+ this.rippleElement_.style.transform = transformString;
+ if (start) {
+ this.rippleElement_.classList.remove(this.CssClasses_.IS_ANIMATING);
+ } else {
+ this.rippleElement_.classList.add(this.CssClasses_.IS_ANIMATING);
+ }
+ }
+ };
+ /**
+ * Handles an animation frame.
+ */
+ this.animFrameHandler = function () {
+ if (this.frameCount_-- > 0) {
+ window.requestAnimationFrame(this.animFrameHandler.bind(this));
+ } else {
+ this.setRippleStyles(false);
+ }
+ };
+ }
+ }
+ };
+ // The component registers itself. It can assume componentHandler is available
+ // in the global scope.
+ componentHandler.register({
+ constructor: MaterialRipple,
+ classAsString: 'MaterialRipple',
+ cssClass: 'mdl-js-ripple-effect',
+ widget: false
+ });
+}()); \ No newline at end of file
diff --git a/js/script.js b/js/script.js
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/js/script.js
diff --git a/lib/Controller/NoteController.php b/lib/Controller/NoteController.php
new file mode 100755
index 0000000..8da3a16
--- /dev/null
+++ b/lib/Controller/NoteController.php
@@ -0,0 +1,323 @@
+<?php
+ namespace OCA\Carnet\Controller;
+ use OCP\IRequest;
+ use OCP\AppFramework\Controller;
+ //require_once 'vendor/autoload.php';
+
+ class MyZipFile extends \PhpZip\ZipFile {
+ public function getInputStream(){
+ return $this->inputStream;
+ }
+ }
+ class NoteController extends Controller {
+ private $userId;
+ private $bla;
+ private $storage;
+ private $CarnetFolder;
+ private $appFolder;
+ public function __construct($AppName, IRequest $request, $UserId, $RootFolder, $AppFolder){
+ parent::__construct($AppName, $request);
+ $this->userId = $UserId;
+ $this->appFolder= $AppFolder;
+ try {
+ $this->CarnetFolder = $RootFolder->getUserFolder($this->userId)->get('Documents/QuickDoc');
+ } catch(\OCP\Files\NotFoundException $e) {
+ $this->CarnetFolder = $RootFolder->getUserFolder($this->userId)->newFolder('Documents/QuickDoc');
+ }
+ // \OC_Util::tearDownFS();
+ // \OC_Util::setupFS($UserId);
+ }
+
+ /**
+ * CAUTION: the @Stuff turns off security checks; for this page no admin is
+ * required and no CSRF check. If you don't know what CSRF is, read
+ * it up in the docs or you might create a security hole. This is
+ * basically the only required method to add this exemption, don't
+ * add it to any other method if you don't exactly know what it does
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function listDir() {
+ $path = $_GET['path'];
+ if ($path == "/" || $path == ".")
+ $path = "";
+ else if(substr($path, -1) != '/' && path != "")
+ $path .= "/";
+
+ $data = array();
+ foreach($this->CarnetFolder->get($path)->getDirectoryListing() as $in){
+ $inf = $in->getFileInfo();
+ $file = array();
+ $file['name'] = $inf->getName();
+ $file['path'] = $path.$inf->getName();
+ $file['isDir'] = $inf->getType() == "dir";
+ $file['mtime'] = $inf->getMtime();
+ array_push($data,$file);
+ }
+
+ return $data;
+ }
+ /**
+ * CAUTION: the @Stuff turns off security checks; for this page no admin is
+ * required and no CSRF check. If you don't know what CSRF is, read
+ * it up in the docs or you might create a security hole. This is
+ * basically the only required method to add this exemption, don't
+ * add it to any other method if you don't exactly know what it does
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function index() {
+ $data = array();
+ $note1 = array();
+ $note2 = array();
+
+ $note1['path'] = $path;
+ array_push($data, $note1);
+ $note2['path'] = "path2".$this->CarnetFolder->getPath();
+ array_push($data, $note2);
+
+ return $data;
+ }
+
+ /**
+ * CAUTION: the @Stuff turns off security checks; for this page no admin is
+ * required and no CSRF check. If you don't know what CSRF is, read
+ * it up in the docs or you might create a security hole. This is
+ * basically the only required method to add this exemption, don't
+ * add it to any other method if you don't exactly know what it does
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function getRecent() {
+
+
+ return json_decode($this->getRecentFile()->getContent(),true);
+ }
+
+ private function getRecentFile(){
+ try {
+ return $this->CarnetFolder->get("quickdoc/recentdb/recentnc");
+ } catch(\OCP\Files\NotFoundException $e) {
+ $this->CarnetFolder->newFolder('/quickdoc/recentdb', 0777, true);
+ $file = $this->CarnetFolder->newFile("quickdoc/recentdb/recentnc");
+ $file->putContent("{\"data\":[]}");
+ return $file;
+ }
+ }
+
+ private function getCacheFolder(){
+ try {
+ return $this->appFolder->get("Carnet/cache/".$this->userId);
+ } catch(\OCP\Files\NotFoundException $e) {
+ $folder = $this->appFolder->newFolder("Carnet/cache/".$this->userId, 0777, true);
+ return $folder;
+ }
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function saveRecent($id) {
+ // check if file exists and write to it if possible
+ try {
+ try {
+ $file = $this->storage->get('/myfile.txt');
+ } catch(\OCP\Files\NotFoundException $e) {
+ $this->storage->touch('/myfile.txt');
+ $file = $this->storage->get('/myfile.txt');
+ }
+
+ // the id can be accessed by $file->getId();
+ $file->putContent($content);
+
+ } catch(\OCP\Files\NotPermittedException $e) {
+ // you have to create this exception by yourself ;)
+ throw new StorageException('Cant write to file');
+ }
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function internalSaveRecent($str) {
+ $this->getRecentFile()->putContent($str);
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function postActions(){
+ $recent = $this->getRecent();
+ foreach($_POST["data"] as $action){
+ array_push($recent['data'],$action);
+ }
+ $this->internalSaveRecent(json_encode($recent));
+ return $recent;
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function getMetadata($paths){
+ $array = array();
+ $pathsAr = explode(",",$paths);
+
+ foreach($pathsAr as $path){
+ if(empty($path))
+ continue;
+ try {
+ $zipFile = new \PhpZip\ZipFile();
+ $zipFile->openFromStream($this->CarnetFolder->get($path)->fopen("r"));
+ $array[$path] = array();
+ $array[$path]['metadata'] = json_decode($zipFile->getEntryContents("metadata.json"));
+ $array[$path]['shorttext'] = substr(trim(strip_tags($zipFile->getEntryContents("index.html"))),0, 100);
+ } catch(\OCP\Files\NotFoundException $e) {
+ }
+ }
+ return $array;
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function saveTextToOpenNote(){
+ $id = $_POST['id'];
+ $cache = $this->getCacheFolder();
+ $folder = $cache->get("currentnote".$id);
+ try{
+ $file = $folder->get("index.html");
+ } catch(\OCP\Files\NotFoundException $e) {
+ $file = $folder->newFile("index.html");
+ }
+ $file->putContent($_POST['html']);
+ try{
+ $file = $folder->get("metadata.json");
+ } catch(\OCP\Files\NotFoundException $e) {
+ $file = $folder->newFile("metadata.json");
+ }
+ $file->putContent($_POST['metadata']);
+
+ $this->saveOpenNote($_POST['path'],$id);
+ }
+
+ private function saveOpenNote($path,$id){
+ $cache = $this->getCacheFolder();
+ $folder = $cache->get("currentnote".$id);
+ $zipFile = new MyZipFile();
+ $this->addFolderContentToArchive($folder,$zipFile,"");
+ try{
+ $file = $this->CarnetFolder->get($path);
+ } catch(\OCP\Files\NotFoundException $e) {
+ $file = $this->CarnetFolder->newFile($path);
+ }
+ $zipFile->saveAsStream($file->fopen("w"));
+ }
+
+ private function addFolderContentToArchive($folder, $archive, $relativePath){
+ foreach($folder->getDirectoryListing() as $in){
+ $inf = $in->getFileInfo();
+ $path = $relativePath.$inf->getName();
+ if($inf->getType() == "dir"){
+ $archive->addEmptyDir($path);
+ $this->addFolderContentToArchive($in, $archive, $path."/");
+ }else {
+ $archive->addFromStream($in->fopen("r"), $path, \PhpZip\ZipFile::METHOD_STORED);
+ }
+
+ }
+ }
+
+ private function getCurrentnoteDir(){
+ $cache = $this->getCacheFolder();
+ //find current note folder
+ foreach($cache->getDirectoryListing() as $in){
+ if(substr($in->getName(), 0, strlen("currentnote")) === "currentnote"){
+ return $in;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function openNote(){
+ $editUniqueID = uniqid();
+ $data = array();
+ $path = $_GET['path'];
+ $cache = $this->getCacheFolder();
+ /*
+ because of an issue with nextcloud, working with a single currentnote folder is impossible...
+ */
+ $folder = $this->getCurrentnoteDir();
+ if($folder != null)
+ $folder->delete();
+
+ $folder = $cache->newFolder("currentnote".$editUniqueID);
+ try{
+ $tmppath = getcwd()."/".uniqid().".zip";
+ file_put_contents($tmppath,$this->CarnetFolder->get($path)->fopen("r"));
+
+ $zipFile = new MyZipFile();
+ $zipFile->openFile($tmppath);
+ foreach($zipFile as $entryName => $contents){
+ if($contents == "" AND $zipFile->isDirectory($entryName)){
+ $folder->newFolder($entryName);
+ }
+ else{
+ if($entryName == "index.html"){
+ $data['html'] = $contents;
+ } else if($entryName == "metadata.json"){
+ $data['metadata'] = json_decode($contents);
+ }
+ $folder->newFile($entryName)->putContent($contents);
+ }
+ }
+ unlink($tmppath);
+ } catch(\OCP\Files\NotFoundException $e) {
+ }
+ $data['id'] = $editUniqueID;
+ return $data;
+
+ }
+ /**
+ * @NoAdminRequired
+ *
+ * @param string $title
+ * @param string $content
+ */
+ public function create($title, $content) {
+ // empty for now
+ }
+
+ /**
+ * @NoAdminRequired
+ *
+ * @param int $id
+ * @param string $title
+ * @param string $content
+ */
+ public function update($id, $title, $content) {
+ // empty for now
+ }
+
+ /**
+ * @NoAdminRequired
+ *
+ * @param int $id
+ */
+ public function destroy($id) {
+ // empty for now
+ }
+
+ }
+?> \ No newline at end of file
diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php
new file mode 100755
index 0000000..bf1458d
--- /dev/null
+++ b/lib/Controller/PageController.php
@@ -0,0 +1,40 @@
+<?php
+namespace OCA\Carnet\Controller;
+
+use OCP\IRequest;
+use OCP\AppFramework\Http\TemplateResponse;
+use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\Controller;
+
+class PageController extends Controller {
+ private $userId;
+ private $RootFolder;
+ public function __construct($AppName, IRequest $request, $UserId, $RootFolder){
+ parent::__construct($AppName, $request);
+ $this->userId = $UserId;
+ $this->RootFolder = $RootFolder;
+ }
+
+ /**
+ * CAUTION: the @Stuff turns off security checks; for this page no admin is
+ * required and no CSRF check. If you don't know what CSRF is, read
+ * it up in the docs or you might create a security hole. This is
+ * basically the only required method to add this exemption, don't
+ * add it to any other method if you don't exactly know what it does
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function index() {
+ return new TemplateResponse($this->appName,"index"); // templates/index.php
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function writer() {
+ return new TemplateResponse($this->appName,"writer"); // templates/writer.php
+ }
+
+} \ No newline at end of file
diff --git a/phpunit.integration.xml b/phpunit.integration.xml
new file mode 100755
index 0000000..eae19f1
--- /dev/null
+++ b/phpunit.integration.xml
@@ -0,0 +1,7 @@
+<phpunit bootstrap="tests/bootstrap.php" colors="true">
+ <testsuites>
+ <testsuite name="integration">
+ <directory>./tests/Integration</directory>
+ </testsuite>
+ </testsuites>
+</phpunit>
diff --git a/phpunit.xml b/phpunit.xml
new file mode 100755
index 0000000..82c96d6
--- /dev/null
+++ b/phpunit.xml
@@ -0,0 +1,7 @@
+<phpunit bootstrap="tests/bootstrap.php" colors="true">
+ <testsuites>
+ <testsuite name="unit">
+ <directory>./tests/Unit</directory>
+ </testsuite>
+ </testsuites>
+</phpunit>
diff --git a/templates/content/index.php b/templates/content/index.php
new file mode 100755
index 0000000..159202e
--- /dev/null
+++ b/templates/content/index.php
@@ -0,0 +1 @@
+<h1>Hello world</h1>
diff --git a/templates/index.php b/templates/index.php
new file mode 100755
index 0000000..7bff5a8
--- /dev/null
+++ b/templates/index.php
@@ -0,0 +1,18 @@
+<?php
+
+$currentpath = substr(get_defined_vars()["file"],strlen(getcwd())+1, -strlen("index.php"))."/CarnetElectron/";
+
+$file = file_get_contents($currentpath."index.html");
+//
+$file = str_replace("href=\"","href=\"".substr(__DIR__, strlen($_SERVER['DOCUMENT_ROOT']))."/CarnetElectron/",$file);
+
+preg_match_all('/<script.*?src=\"(.*?\.js(?:\?.*?)?)"/si', $file, $matches, PREG_PATTERN_ORDER);
+for ($i = 0; $i < count($matches[1]); $i++) {
+ script("carnet","../templates/CarnetElectron/".substr($matches[1][$i],0,-3));
+}
+$file = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $file);
+$root = substr(__DIR__, strlen($_SERVER['DOCUMENT_ROOT']));
+$file = str_replace("src=\"","defer src=\"".$root."/CarnetElectron/",$file);
+echo $file;
+echo "<span style=\"display:none;\" id=\"root-url\">".$root."/CarnetElectron/</span>";
+?> \ No newline at end of file
diff --git a/templates/navigation/index.php b/templates/navigation/index.php
new file mode 100755
index 0000000..efa95c6
--- /dev/null
+++ b/templates/navigation/index.php
@@ -0,0 +1,10 @@
+<ul>
+ <li><a href="#">First level entry</a></li>
+ <li>
+ <a href="#">First level container</a>
+ <ul>
+ <li><a href="#">Second level entry</a></li>
+ <li><a href="#">Second level entry</a></li>
+ </ul>
+ </li>
+</ul>
diff --git a/templates/settings/index.php b/templates/settings/index.php
new file mode 100755
index 0000000..ac7c671
--- /dev/null
+++ b/templates/settings/index.php
@@ -0,0 +1,10 @@
+<div id="app-settings">
+ <div id="app-settings-header">
+ <button class="settings-button"
+ data-apps-slide-toggle="#app-settings-content"
+ ></button>
+ </div>
+ <div id="app-settings-content">
+ <!-- Your settings in here -->
+ </div>
+</div>
diff --git a/templates/writer.php b/templates/writer.php
new file mode 100755
index 0000000..7c46252
--- /dev/null
+++ b/templates/writer.php
@@ -0,0 +1,20 @@
+<?php
+$currentpath = substr(get_defined_vars()["file"],strlen(getcwd())+1, -strlen("writer.php"))."/CarnetElectron/";
+
+$file = file_get_contents($currentpath."reader/reader.html");
+//
+$file = str_replace("href=\"","href=\"".substr(__DIR__, strlen($_SERVER['DOCUMENT_ROOT']))."/CarnetElectron/",$file);
+$file = str_replace("<!ROOTPATH>", "", $file);
+preg_match_all('/<script.*?src=\"(.*?\.js(?:\?.*?)?)"/si', $file, $matches, PREG_PATTERN_ORDER);
+for ($i = 0; $i < count($matches[1]); $i++) {
+
+ $url = substr($matches[1][$i],0,-3);
+ if (strpos($url, 'jquery.min') == false) //jquery already in nextcloud
+ script("carnet","../templates/CarnetElectron/".$url);
+}
+$file = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $file);
+$root = substr(__DIR__, strlen($_SERVER['DOCUMENT_ROOT']));
+$file = str_replace("src=\"","defer src=\"".$root."/CarnetElectron/",$file);
+echo $file;
+echo "<span style=\"display:none;\" id=\"root-url\">".$root."/CarnetElectron/</span>";
+?> \ No newline at end of file
diff --git a/tests/Integration/AppTest.php b/tests/Integration/AppTest.php
new file mode 100755
index 0000000..3d2420b
--- /dev/null
+++ b/tests/Integration/AppTest.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace OCA\QuickDoc\Tests\Integration\Controller;
+
+use OCP\AppFramework\App;
+use Test\TestCase;
+
+
+/**
+ * This test shows how to make a small Integration Test. Query your class
+ * directly from the container, only pass in mocks if needed and run your tests
+ * against the database
+ */
+class AppTest extends TestCase {
+
+ private $container;
+
+ public function setUp() {
+ parent::setUp();
+ $app = new App('quickdoc');
+ $this->container = $app->getContainer();
+ }
+
+ public function testAppInstalled() {
+ $appManager = $this->container->query('OCP\App\IAppManager');
+ $this->assertTrue($appManager->isInstalled('quickdoc'));
+ }
+
+}
diff --git a/tests/Unit/Controller/PageControllerTest.php b/tests/Unit/Controller/PageControllerTest.php
new file mode 100755
index 0000000..4d34c71
--- /dev/null
+++ b/tests/Unit/Controller/PageControllerTest.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace OCA\QuickDoc\Tests\Unit\Controller;
+
+use PHPUnit_Framework_TestCase;
+
+use OCP\AppFramework\Http\TemplateResponse;
+
+use OCA\QuickDoc\Controller\PageController;
+
+
+class PageControllerTest extends PHPUnit_Framework_TestCase {
+ private $controller;
+ private $userId = 'john';
+
+ public function setUp() {
+ $request = $this->getMockBuilder('OCP\IRequest')->getMock();
+
+ $this->controller = new PageController(
+ 'quickdoc', $request, $this->userId
+ );
+ }
+
+ public function testIndex() {
+ $result = $this->controller->index();
+
+ $this->assertEquals('index', $result->getTemplateName());
+ $this->assertTrue($result instanceof TemplateResponse);
+ }
+
+}
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
new file mode 100755
index 0000000..318d169
--- /dev/null
+++ b/tests/bootstrap.php
@@ -0,0 +1,19 @@
+<?php
+
+if (!defined('PHPUNIT_RUN')) {
+ define('PHPUNIT_RUN', 1);
+}
+
+require_once __DIR__.'/../../../lib/base.php';
+
+// Fix for "Autoload path not allowed: .../tests/lib/testcase.php"
+\OC::$loader->addValidRoot(OC::$SERVERROOT . '/tests');
+
+// Fix for "Autoload path not allowed: .../quickdoc/tests/testcase.php"
+\OC_App::loadApp('quickdoc');
+
+if(!class_exists('PHPUnit_Framework_TestCase')) {
+ require_once('PHPUnit/Autoload.php');
+}
+
+OC_Hook::clear();
diff --git a/vendor/autoload.php b/vendor/autoload.php
new file mode 100644
index 0000000..1438fc8
--- /dev/null
+++ b/vendor/autoload.php
@@ -0,0 +1,7 @@
+<?php
+
+// autoload.php @generated by Composer
+
+require_once __DIR__ . '/composer/autoload_real.php';
+
+return ComposerAutoloaderInitff1ac78c68d0f00d4eb0afecddc10d83::getLoader();
diff --git a/vendor/bin/phpunit b/vendor/bin/phpunit
new file mode 120000
index 0000000..2c48930
--- /dev/null
+++ b/vendor/bin/phpunit
@@ -0,0 +1 @@
+../phpunit/phpunit/phpunit \ No newline at end of file
diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php
new file mode 100644
index 0000000..dc02dfb
--- /dev/null
+++ b/vendor/composer/ClassLoader.php
@@ -0,0 +1,445 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ * Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Autoload;
+
+/**
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
+ *
+ * $loader = new \Composer\Autoload\ClassLoader();
+ *
+ * // register classes with namespaces
+ * $loader->add('Symfony\Component', __DIR__.'/component');
+ * $loader->add('Symfony', __DIR__.'/framework');
+ *
+ * // activate the autoloader
+ * $loader->register();
+ *
+ * // to enable searching the include path (eg. for PEAR packages)
+ * $loader->setUseIncludePath(true);
+ *
+ * In this example, if you try to use a class in the Symfony\Component
+ * namespace or one of its children (Symfony\Component\Console for instance),
+ * the autoloader will first look for the class under the component/
+ * directory, and it will then fallback to the framework/ directory if not
+ * found before giving up.
+ *
+ * This class is loosely based on the Symfony UniversalClassLoader.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ * @see http://www.php-fig.org/psr/psr-0/
+ * @see http://www.php-fig.org/psr/psr-4/
+ */
+class ClassLoader
+{
+ // PSR-4
+ private $prefixLengthsPsr4 = array();
+ private $prefixDirsPsr4 = array();
+ private $fallbackDirsPsr4 = array();
+
+ // PSR-0
+ private $prefixesPsr0 = array();
+ private $fallbackDirsPsr0 = array();
+
+ private $useIncludePath = false;
+ private $classMap = array();
+ private $classMapAuthoritative = false;
+ private $missingClasses = array();
+ private $apcuPrefix;
+
+ public function getPrefixes()
+ {
+ if (!empty($this->prefixesPsr0)) {
+ return call_user_func_array('array_merge', $this->prefixesPsr0);
+ }
+
+ return array();
+ }
+
+ public function getPrefixesPsr4()
+ {
+ return $this->prefixDirsPsr4;
+ }
+
+ public function getFallbackDirs()
+ {
+ return $this->fallbackDirsPsr0;
+ }
+
+ public function getFallbackDirsPsr4()
+ {
+ return $this->fallbackDirsPsr4;
+ }
+
+ public function getClassMap()
+ {
+ return $this->classMap;
+ }
+
+ /**
+ * @param array $classMap Class to filename map
+ */
+ public function addClassMap(array $classMap)
+ {
+ if ($this->classMap) {
+ $this->classMap = array_merge($this->classMap, $classMap);
+ } else {
+ $this->classMap = $classMap;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix, either
+ * appending or prepending to the ones previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param array|string $paths The PSR-0 root directories
+ * @param bool $prepend Whether to prepend the directories
+ */
+ public function add($prefix, $paths, $prepend = false)
+ {
+ if (!$prefix) {
+ if ($prepend) {
+ $this->fallbackDirsPsr0 = array_merge(
+ (array) $paths,
+ $this->fallbackDirsPsr0
+ );
+ } else {
+ $this->fallbackDirsPsr0 = array_merge(
+ $this->fallbackDirsPsr0,
+ (array) $paths
+ );
+ }
+
+ return;
+ }
+
+ $first = $prefix[0];
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
+ $this->prefixesPsr0[$first][$prefix] = (array) $paths;
+
+ return;
+ }
+ if ($prepend) {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ (array) $paths,
+ $this->prefixesPsr0[$first][$prefix]
+ );
+ } else {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ $this->prefixesPsr0[$first][$prefix],
+ (array) $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace, either
+ * appending or prepending to the ones previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param array|string $paths The PSR-4 base directories
+ * @param bool $prepend Whether to prepend the directories
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function addPsr4($prefix, $paths, $prepend = false)
+ {
+ if (!$prefix) {
+ // Register directories for the root namespace.
+ if ($prepend) {
+ $this->fallbackDirsPsr4 = array_merge(
+ (array) $paths,
+ $this->fallbackDirsPsr4
+ );
+ } else {
+ $this->fallbackDirsPsr4 = array_merge(
+ $this->fallbackDirsPsr4,
+ (array) $paths
+ );
+ }
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
+ // Register directories for a new namespace.
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ } elseif ($prepend) {
+ // Prepend directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ (array) $paths,
+ $this->prefixDirsPsr4[$prefix]
+ );
+ } else {
+ // Append directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ $this->prefixDirsPsr4[$prefix],
+ (array) $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix,
+ * replacing any others previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param array|string $paths The PSR-0 base directories
+ */
+ public function set($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr0 = (array) $paths;
+ } else {
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace,
+ * replacing any others previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param array|string $paths The PSR-4 base directories
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function setPsr4($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr4 = (array) $paths;
+ } else {
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Turns on searching the include path for class files.
+ *
+ * @param bool $useIncludePath
+ */
+ public function setUseIncludePath($useIncludePath)
+ {
+ $this->useIncludePath = $useIncludePath;
+ }
+
+ /**
+ * Can be used to check if the autoloader uses the include path to check
+ * for classes.
+ *
+ * @return bool
+ */
+ public function getUseIncludePath()
+ {
+ return $this->useIncludePath;
+ }
+
+ /**
+ * Turns off searching the prefix and fallback directories for classes
+ * that have not been registered with the class map.
+ *
+ * @param bool $classMapAuthoritative
+ */
+ public function setClassMapAuthoritative($classMapAuthoritative)
+ {
+ $this->classMapAuthoritative = $classMapAuthoritative;
+ }
+
+ /**
+ * Should class lookup fail if not found in the current class map?
+ *
+ * @return bool
+ */
+ public function isClassMapAuthoritative()
+ {
+ return $this->classMapAuthoritative;
+ }
+
+ /**
+ * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
+ *
+ * @param string|null $apcuPrefix
+ */
+ public function setApcuPrefix($apcuPrefix)
+ {
+ $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
+ }
+
+ /**
+ * The APCu prefix in use, or null if APCu caching is not enabled.
+ *
+ * @return string|null
+ */
+ public function getApcuPrefix()
+ {
+ return $this->apcuPrefix;
+ }
+
+ /**
+ * Registers this instance as an autoloader.
+ *
+ * @param bool $prepend Whether to prepend the autoloader or not
+ */
+ public function register($prepend = false)
+ {
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+ }
+
+ /**
+ * Unregisters this instance as an autoloader.
+ */
+ public function unregister()
+ {
+ spl_autoload_unregister(array($this, 'loadClass'));
+ }
+
+ /**
+ * Loads the given class or interface.
+ *
+ * @param string $class The name of the class
+ * @return bool|null True if loaded, null otherwise
+ */
+ public function loadClass($class)
+ {
+ if ($file = $this->findFile($class)) {
+ includeFile($file);
+
+ return true;
+ }
+ }
+
+ /**
+ * Finds the path to the file where the class is defined.
+ *
+ * @param string $class The name of the class
+ *
+ * @return string|false The path if found, false otherwise
+ */
+ public function findFile($class)
+ {
+ // class map lookup
+ if (isset($this->classMap[$class])) {
+ return $this->classMap[$class];
+ }
+ if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
+ return false;
+ }
+ if (null !== $this->apcuPrefix) {
+ $file = apcu_fetch($this->apcuPrefix.$class, $hit);
+ if ($hit) {
+ return $file;
+ }
+ }
+
+ $file = $this->findFileWithExtension($class, '.php');
+
+ // Search for Hack files if we are running on HHVM
+ if (false === $file && defined('HHVM_VERSION')) {
+ $file = $this->findFileWithExtension($class, '.hh');
+ }
+
+ if (null !== $this->apcuPrefix) {
+ apcu_add($this->apcuPrefix.$class, $file);
+ }
+
+ if (false === $file) {
+ // Remember that this class does not exist.
+ $this->missingClasses[$class] = true;
+ }
+
+ return $file;
+ }
+
+ private function findFileWithExtension($class, $ext)
+ {
+ // PSR-4 lookup
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
+
+ $first = $class[0];
+ if (isset($this->prefixLengthsPsr4[$first])) {
+ $subPath = $class;
+ while (false !== $lastPos = strrpos($subPath, '\\')) {
+ $subPath = substr($subPath, 0, $lastPos);
+ $search = $subPath.'\\';
+ if (isset($this->prefixDirsPsr4[$search])) {
+ $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
+ foreach ($this->prefixDirsPsr4[$search] as $dir) {
+ if (file_exists($file = $dir . $pathEnd)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-4 fallback dirs
+ foreach ($this->fallbackDirsPsr4 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 lookup
+ if (false !== $pos = strrpos($class, '\\')) {
+ // namespaced class name
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
+ } else {
+ // PEAR-like class name
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
+ }
+
+ if (isset($this->prefixesPsr0[$first])) {
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
+ if (0 === strpos($class, $prefix)) {
+ foreach ($dirs as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-0 fallback dirs
+ foreach ($this->fallbackDirsPsr0 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 include paths.
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
+ return $file;
+ }
+
+ return false;
+ }
+}
+
+/**
+ * Scope isolated include.
+ *
+ * Prevents access to $this/self from included files.
+ */
+function includeFile($file)
+{
+ include $file;
+}
diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE
new file mode 100644
index 0000000..f0157a6
--- /dev/null
+++ b/vendor/composer/LICENSE
@@ -0,0 +1,56 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: Composer
+Upstream-Contact: Jordi Boggiano <j.boggiano@seld.be>
+Source: https://github.com/composer/composer
+
+Files: *
+Copyright: 2016, Nils Adermann <naderman@naderman.de>
+ 2016, Jordi Boggiano <j.boggiano@seld.be>
+License: Expat
+
+Files: src/Composer/Util/TlsHelper.php
+Copyright: 2016, Nils Adermann <naderman@naderman.de>
+ 2016, Jordi Boggiano <j.boggiano@seld.be>
+ 2013, Evan Coury <me@evancoury.com>
+License: Expat and BSD-2-Clause
+
+License: BSD-2-Clause
+ 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.
+ .
+ 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.
+
+License: Expat
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is furnished
+ to do so, subject to the following conditions:
+ .
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php
new file mode 100644
index 0000000..7c468f3
--- /dev/null
+++ b/vendor/composer/autoload_classmap.php
@@ -0,0 +1,474 @@
+<?php
+
+// autoload_classmap.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+ 'File_Iterator' => $vendorDir . '/phpunit/php-file-iterator/src/Iterator.php',
+ 'File_Iterator_Facade' => $vendorDir . '/phpunit/php-file-iterator/src/Facade.php',
+ 'File_Iterator_Factory' => $vendorDir . '/phpunit/php-file-iterator/src/Factory.php',
+ 'PHPUnit\\Framework\\Assert' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/Assert.php',
+ 'PHPUnit\\Framework\\AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/AssertionFailedError.php',
+ 'PHPUnit\\Framework\\BaseTestListener' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/BaseTestListener.php',
+ 'PHPUnit\\Framework\\Test' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/Test.php',
+ 'PHPUnit\\Framework\\TestCase' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/TestCase.php',
+ 'PHPUnit\\Framework\\TestListener' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/TestListener.php',
+ 'PHPUnit\\Framework\\TestSuite' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/TestSuite.php',
+ 'PHPUnit_Exception' => $vendorDir . '/phpunit/phpunit/src/Exception.php',
+ 'PHPUnit_Extensions_GroupTestSuite' => $vendorDir . '/phpunit/phpunit/src/Extensions/GroupTestSuite.php',
+ 'PHPUnit_Extensions_PhptTestCase' => $vendorDir . '/phpunit/phpunit/src/Extensions/PhptTestCase.php',
+ 'PHPUnit_Extensions_PhptTestSuite' => $vendorDir . '/phpunit/phpunit/src/Extensions/PhptTestSuite.php',
+ 'PHPUnit_Extensions_RepeatedTest' => $vendorDir . '/phpunit/phpunit/src/Extensions/RepeatedTest.php',
+ 'PHPUnit_Extensions_TestDecorator' => $vendorDir . '/phpunit/phpunit/src/Extensions/TestDecorator.php',
+ 'PHPUnit_Extensions_TicketListener' => $vendorDir . '/phpunit/phpunit/src/Extensions/TicketListener.php',
+ 'PHPUnit_Framework_Assert' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert.php',
+ 'PHPUnit_Framework_AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/Framework/AssertionFailedError.php',
+ 'PHPUnit_Framework_BaseTestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/BaseTestListener.php',
+ 'PHPUnit_Framework_CodeCoverageException' => $vendorDir . '/phpunit/phpunit/src/Framework/CodeCoverageException.php',
+ 'PHPUnit_Framework_Constraint' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint.php',
+ 'PHPUnit_Framework_Constraint_And' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/And.php',
+ 'PHPUnit_Framework_Constraint_ArrayHasKey' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php',
+ 'PHPUnit_Framework_Constraint_ArraySubset' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php',
+ 'PHPUnit_Framework_Constraint_Attribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php',
+ 'PHPUnit_Framework_Constraint_Callback' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Callback.php',
+ 'PHPUnit_Framework_Constraint_ClassHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php',
+ 'PHPUnit_Framework_Constraint_ClassHasStaticAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php',
+ 'PHPUnit_Framework_Constraint_Composite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Composite.php',
+ 'PHPUnit_Framework_Constraint_Count' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Count.php',
+ 'PHPUnit_Framework_Constraint_DirectoryExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php',
+ 'PHPUnit_Framework_Constraint_Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Exception.php',
+ 'PHPUnit_Framework_Constraint_ExceptionCode' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php',
+ 'PHPUnit_Framework_Constraint_ExceptionMessage' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php',
+ 'PHPUnit_Framework_Constraint_ExceptionMessageRegExp' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegExp.php',
+ 'PHPUnit_Framework_Constraint_FileExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php',
+ 'PHPUnit_Framework_Constraint_GreaterThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php',
+ 'PHPUnit_Framework_Constraint_IsAnything' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php',
+ 'PHPUnit_Framework_Constraint_IsEmpty' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php',
+ 'PHPUnit_Framework_Constraint_IsEqual' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php',
+ 'PHPUnit_Framework_Constraint_IsFalse' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php',
+ 'PHPUnit_Framework_Constraint_IsFinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php',
+ 'PHPUnit_Framework_Constraint_IsIdentical' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php',
+ 'PHPUnit_Framework_Constraint_IsInfinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php',
+ 'PHPUnit_Framework_Constraint_IsInstanceOf' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php',
+ 'PHPUnit_Framework_Constraint_IsJson' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php',
+ 'PHPUnit_Framework_Constraint_IsNan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php',
+ 'PHPUnit_Framework_Constraint_IsNull' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php',
+ 'PHPUnit_Framework_Constraint_IsReadable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsReadable.php',
+ 'PHPUnit_Framework_Constraint_IsTrue' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php',
+ 'PHPUnit_Framework_Constraint_IsType' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsType.php',
+ 'PHPUnit_Framework_Constraint_IsWritable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsWritable.php',
+ 'PHPUnit_Framework_Constraint_JsonMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php',
+ 'PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches/ErrorMessageProvider.php',
+ 'PHPUnit_Framework_Constraint_LessThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php',
+ 'PHPUnit_Framework_Constraint_Not' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Not.php',
+ 'PHPUnit_Framework_Constraint_ObjectHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php',
+ 'PHPUnit_Framework_Constraint_Or' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Or.php',
+ 'PHPUnit_Framework_Constraint_PCREMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/PCREMatch.php',
+ 'PHPUnit_Framework_Constraint_SameSize' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php',
+ 'PHPUnit_Framework_Constraint_StringContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php',
+ 'PHPUnit_Framework_Constraint_StringEndsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php',
+ 'PHPUnit_Framework_Constraint_StringMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringMatches.php',
+ 'PHPUnit_Framework_Constraint_StringStartsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php',
+ 'PHPUnit_Framework_Constraint_TraversableContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php',
+ 'PHPUnit_Framework_Constraint_TraversableContainsOnly' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php',
+ 'PHPUnit_Framework_Constraint_Xor' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Xor.php',
+ 'PHPUnit_Framework_CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php',
+ 'PHPUnit_Framework_Error' => $vendorDir . '/phpunit/phpunit/src/Framework/Error.php',
+ 'PHPUnit_Framework_Error_Deprecated' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Deprecated.php',
+ 'PHPUnit_Framework_Error_Notice' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Notice.php',
+ 'PHPUnit_Framework_Error_Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Warning.php',
+ 'PHPUnit_Framework_Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception.php',
+ 'PHPUnit_Framework_ExceptionWrapper' => $vendorDir . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php',
+ 'PHPUnit_Framework_ExpectationFailedException' => $vendorDir . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php',
+ 'PHPUnit_Framework_IncompleteTest' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTest.php',
+ 'PHPUnit_Framework_IncompleteTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php',
+ 'PHPUnit_Framework_IncompleteTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestError.php',
+ 'PHPUnit_Framework_InvalidCoversTargetException' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php',
+ 'PHPUnit_Framework_MissingCoversAnnotationException' => $vendorDir . '/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php',
+ 'PHPUnit_Framework_MockObject_BadMethodCallException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/BadMethodCallException.php',
+ 'PHPUnit_Framework_MockObject_Builder_Identity' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Identity.php',
+ 'PHPUnit_Framework_MockObject_Builder_InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/InvocationMocker.php',
+ 'PHPUnit_Framework_MockObject_Builder_Match' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Match.php',
+ 'PHPUnit_Framework_MockObject_Builder_MethodNameMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/MethodNameMatch.php',
+ 'PHPUnit_Framework_MockObject_Builder_Namespace' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Namespace.php',
+ 'PHPUnit_Framework_MockObject_Builder_ParametersMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/ParametersMatch.php',
+ 'PHPUnit_Framework_MockObject_Builder_Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Stub.php',
+ 'PHPUnit_Framework_MockObject_Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/Exception.php',
+ 'PHPUnit_Framework_MockObject_Generator' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php',
+ 'PHPUnit_Framework_MockObject_Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation.php',
+ 'PHPUnit_Framework_MockObject_InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/InvocationMocker.php',
+ 'PHPUnit_Framework_MockObject_Invocation_Object' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Object.php',
+ 'PHPUnit_Framework_MockObject_Invocation_Static' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Static.php',
+ 'PHPUnit_Framework_MockObject_Invokable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invokable.php',
+ 'PHPUnit_Framework_MockObject_Matcher' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher.php',
+ 'PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyInvokedCount.php',
+ 'PHPUnit_Framework_MockObject_Matcher_AnyParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyParameters.php',
+ 'PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/ConsecutiveParameters.php',
+ 'PHPUnit_Framework_MockObject_Matcher_Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Invocation.php',
+ 'PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtIndex.php',
+ 'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php',
+ 'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php',
+ 'PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtMostCount.php',
+ 'PHPUnit_Framework_MockObject_Matcher_InvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedCount.php',
+ 'PHPUnit_Framework_MockObject_Matcher_InvokedRecorder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedRecorder.php',
+ 'PHPUnit_Framework_MockObject_Matcher_MethodName' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/MethodName.php',
+ 'PHPUnit_Framework_MockObject_Matcher_Parameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Parameters.php',
+ 'PHPUnit_Framework_MockObject_Matcher_StatelessInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/StatelessInvocation.php',
+ 'PHPUnit_Framework_MockObject_MockBuilder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockBuilder.php',
+ 'PHPUnit_Framework_MockObject_MockObject' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockObject.php',
+ 'PHPUnit_Framework_MockObject_RuntimeException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/RuntimeException.php',
+ 'PHPUnit_Framework_MockObject_Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub.php',
+ 'PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ConsecutiveCalls.php',
+ 'PHPUnit_Framework_MockObject_Stub_Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Exception.php',
+ 'PHPUnit_Framework_MockObject_Stub_MatcherCollection' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/MatcherCollection.php',
+ 'PHPUnit_Framework_MockObject_Stub_Return' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Return.php',
+ 'PHPUnit_Framework_MockObject_Stub_ReturnArgument' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnArgument.php',
+ 'PHPUnit_Framework_MockObject_Stub_ReturnCallback' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnCallback.php',
+ 'PHPUnit_Framework_MockObject_Stub_ReturnReference' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnReference.php',
+ 'PHPUnit_Framework_MockObject_Stub_ReturnSelf' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnSelf.php',
+ 'PHPUnit_Framework_MockObject_Stub_ReturnValueMap' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnValueMap.php',
+ 'PHPUnit_Framework_MockObject_Verifiable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Verifiable.php',
+ 'PHPUnit_Framework_OutputError' => $vendorDir . '/phpunit/phpunit/src/Framework/OutputError.php',
+ 'PHPUnit_Framework_RiskyTest' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTest.php',
+ 'PHPUnit_Framework_RiskyTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTestError.php',
+ 'PHPUnit_Framework_SelfDescribing' => $vendorDir . '/phpunit/phpunit/src/Framework/SelfDescribing.php',
+ 'PHPUnit_Framework_SkippedTest' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTest.php',
+ 'PHPUnit_Framework_SkippedTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestCase.php',
+ 'PHPUnit_Framework_SkippedTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestError.php',
+ 'PHPUnit_Framework_SkippedTestSuiteError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php',
+ 'PHPUnit_Framework_SyntheticError' => $vendorDir . '/phpunit/phpunit/src/Framework/SyntheticError.php',
+ 'PHPUnit_Framework_Test' => $vendorDir . '/phpunit/phpunit/src/Framework/Test.php',
+ 'PHPUnit_Framework_TestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/TestCase.php',
+ 'PHPUnit_Framework_TestFailure' => $vendorDir . '/phpunit/phpunit/src/Framework/TestFailure.php',
+ 'PHPUnit_Framework_TestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListener.php',
+ 'PHPUnit_Framework_TestResult' => $vendorDir . '/phpunit/phpunit/src/Framework/TestResult.php',
+ 'PHPUnit_Framework_TestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite.php',
+ 'PHPUnit_Framework_TestSuite_DataProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite/DataProvider.php',
+ 'PHPUnit_Framework_UnintentionallyCoveredCodeError' => $vendorDir . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php',
+ 'PHPUnit_Framework_Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Warning.php',
+ 'PHPUnit_Framework_WarningTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/WarningTestCase.php',
+ 'PHPUnit_Runner_BaseTestRunner' => $vendorDir . '/phpunit/phpunit/src/Runner/BaseTestRunner.php',
+ 'PHPUnit_Runner_Exception' => $vendorDir . '/phpunit/phpunit/src/Runner/Exception.php',
+ 'PHPUnit_Runner_Filter_Factory' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Factory.php',
+ 'PHPUnit_Runner_Filter_GroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group.php',
+ 'PHPUnit_Runner_Filter_Group_Exclude' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group/Exclude.php',
+ 'PHPUnit_Runner_Filter_Group_Include' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group/Include.php',
+ 'PHPUnit_Runner_Filter_Test' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Test.php',
+ 'PHPUnit_Runner_StandardTestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php',
+ 'PHPUnit_Runner_TestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php',
+ 'PHPUnit_Runner_Version' => $vendorDir . '/phpunit/phpunit/src/Runner/Version.php',
+ 'PHPUnit_TextUI_Command' => $vendorDir . '/phpunit/phpunit/src/TextUI/Command.php',
+ 'PHPUnit_TextUI_ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/TextUI/ResultPrinter.php',
+ 'PHPUnit_TextUI_TestRunner' => $vendorDir . '/phpunit/phpunit/src/TextUI/TestRunner.php',
+ 'PHPUnit_Util_Blacklist' => $vendorDir . '/phpunit/phpunit/src/Util/Blacklist.php',
+ 'PHPUnit_Util_Configuration' => $vendorDir . '/phpunit/phpunit/src/Util/Configuration.php',
+ 'PHPUnit_Util_ConfigurationGenerator' => $vendorDir . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php',
+ 'PHPUnit_Util_ErrorHandler' => $vendorDir . '/phpunit/phpunit/src/Util/ErrorHandler.php',
+ 'PHPUnit_Util_Fileloader' => $vendorDir . '/phpunit/phpunit/src/Util/Fileloader.php',
+ 'PHPUnit_Util_Filesystem' => $vendorDir . '/phpunit/phpunit/src/Util/Filesystem.php',
+ 'PHPUnit_Util_Filter' => $vendorDir . '/phpunit/phpunit/src/Util/Filter.php',
+ 'PHPUnit_Util_Getopt' => $vendorDir . '/phpunit/phpunit/src/Util/Getopt.php',
+ 'PHPUnit_Util_GlobalState' => $vendorDir . '/phpunit/phpunit/src/Util/GlobalState.php',
+ 'PHPUnit_Util_InvalidArgumentHelper' => $vendorDir . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php',
+ 'PHPUnit_Util_Log_JSON' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JSON.php',
+ 'PHPUnit_Util_Log_JUnit' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JUnit.php',
+ 'PHPUnit_Util_Log_TAP' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TAP.php',
+ 'PHPUnit_Util_Log_TeamCity' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TeamCity.php',
+ 'PHPUnit_Util_PHP' => $vendorDir . '/phpunit/phpunit/src/Util/PHP.php',
+ 'PHPUnit_Util_PHP_Default' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/Default.php',
+ 'PHPUnit_Util_PHP_Windows' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/Windows.php',
+ 'PHPUnit_Util_Printer' => $vendorDir . '/phpunit/phpunit/src/Util/Printer.php',
+ 'PHPUnit_Util_Regex' => $vendorDir . '/phpunit/phpunit/src/Util/Regex.php',
+ 'PHPUnit_Util_String' => $vendorDir . '/phpunit/phpunit/src/Util/String.php',
+ 'PHPUnit_Util_Test' => $vendorDir . '/phpunit/phpunit/src/Util/Test.php',
+ 'PHPUnit_Util_TestDox_NamePrettifier' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php',
+ 'PHPUnit_Util_TestDox_ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php',
+ 'PHPUnit_Util_TestDox_ResultPrinter_HTML' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/HTML.php',
+ 'PHPUnit_Util_TestDox_ResultPrinter_Text' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/Text.php',
+ 'PHPUnit_Util_TestDox_ResultPrinter_XML' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/XML.php',
+ 'PHPUnit_Util_TestSuiteIterator' => $vendorDir . '/phpunit/phpunit/src/Util/TestSuiteIterator.php',
+ 'PHPUnit_Util_Type' => $vendorDir . '/phpunit/phpunit/src/Util/Type.php',
+ 'PHPUnit_Util_XML' => $vendorDir . '/phpunit/phpunit/src/Util/XML.php',
+ 'PHP_Timer' => $vendorDir . '/phpunit/php-timer/src/Timer.php',
+ 'PHP_Token' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_TokenWithScope' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_TokenWithScopeAndVisibility' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ABSTRACT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_AMPERSAND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_AND_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ARRAY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ARRAY_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_AS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ASYNC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_AT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_AWAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BACKTICK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BAD_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BOOLEAN_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BOOLEAN_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BOOL_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BREAK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CALLABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CARET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CASE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CATCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLASS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLASS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLASS_NAME_CONSTANT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLONE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLOSE_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLOSE_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLOSE_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLOSE_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_COALESCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_COMMA' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_COMPILER_HALT_OFFSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CONCAT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CONST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CONSTANT_ENCAPSED_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CONTINUE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CURLY_OPEN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DEC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DEFAULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DIR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DIV' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DIV_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOC_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOLLAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOUBLE_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOUBLE_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOUBLE_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOUBLE_QUOTES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ELLIPSIS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ELSE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ELSEIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EMPTY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENCAPSED_AND_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDDECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDFOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDFOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDSWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDWHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_END_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENUM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EQUALS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EVAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EXCLAMATION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EXIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EXTENDS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FINAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FINALLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FUNC_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_GLOBAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_GOTO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_HALT_COMPILER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IMPLEMENTS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INCLUDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INCLUDE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INLINE_HTML' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INSTANCEOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INSTEADOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INTERFACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ISSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_GREATER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_NOT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_NOT_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_SMALLER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_Includes' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_JOIN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LAMBDA_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LAMBDA_CP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LAMBDA_OP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LINE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LIST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LOGICAL_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LOGICAL_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LOGICAL_XOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_METHOD_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MINUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MINUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MOD_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MUL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NAMESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NEW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NS_SEPARATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NULLSAFE_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NUM_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OBJECT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ONUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_TAG_WITH_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PERCENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PIPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PLUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PLUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_POW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_POW_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PRINT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PRIVATE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PROTECTED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PUBLIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_QUESTION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_REQUIRE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_REQUIRE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_RETURN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SEMICOLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SHAPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SPACESHIP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_START_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_STATIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_STRING_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_STRING_VARNAME' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SUPER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_Stream' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream.php',
+ 'PHP_Token_Stream_CachingFactory' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php',
+ 'PHP_Token_THROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TILDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TRAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TRAIT_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TRY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TYPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TYPELIST_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TYPELIST_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_UNSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_UNSET_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_USE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_USE_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_VAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_VARIABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_WHERE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_WHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XHP_ATTRIBUTE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XHP_CATEGORY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XHP_CATEGORY_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XHP_CHILDREN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XHP_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XHP_REQUIRED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XHP_TAG_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XHP_TAG_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XHP_TEXT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XOR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_YIELD' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_YIELD_FROM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
+ 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage.php',
+ 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php',
+ 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Driver.php',
+ 'SebastianBergmann\\CodeCoverage\\Driver\\HHVM' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/HHVM.php',
+ 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php',
+ 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Xdebug.php',
+ 'SebastianBergmann\\CodeCoverage\\Exception' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/Exception.php',
+ 'SebastianBergmann\\CodeCoverage\\Filter' => $vendorDir . '/phpunit/php-code-coverage/src/Filter.php',
+ 'SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php',
+ 'SebastianBergmann\\CodeCoverage\\MissingCoversAnnotationException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => $vendorDir . '/phpunit/php-code-coverage/src/Node/AbstractNode.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\Builder' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Builder.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Directory.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Node/File.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\Iterator' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Iterator.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Clover' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Clover.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Crap4j.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Facade.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => $vendorDir . '/phpunit/php-code-coverage/src/Report/PHP.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Text' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Text.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/File.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Method.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Node.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Project.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Report.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php',
+ 'SebastianBergmann\\CodeCoverage\\RuntimeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php',
+ 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php',
+ 'SebastianBergmann\\CodeCoverage\\Util' => $vendorDir . '/phpunit/php-code-coverage/src/Util.php',
+ 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => $vendorDir . '/sebastian/code-unit-reverse-lookup/src/Wizard.php',
+ 'SebastianBergmann\\Comparator\\ArrayComparator' => $vendorDir . '/sebastian/comparator/src/ArrayComparator.php',
+ 'SebastianBergmann\\Comparator\\Comparator' => $vendorDir . '/sebastian/comparator/src/Comparator.php',
+ 'SebastianBergmann\\Comparator\\ComparisonFailure' => $vendorDir . '/sebastian/comparator/src/ComparisonFailure.php',
+ 'SebastianBergmann\\Comparator\\DOMNodeComparator' => $vendorDir . '/sebastian/comparator/src/DOMNodeComparator.php',
+ 'SebastianBergmann\\Comparator\\DateTimeComparator' => $vendorDir . '/sebastian/comparator/src/DateTimeComparator.php',
+ 'SebastianBergmann\\Comparator\\DoubleComparator' => $vendorDir . '/sebastian/comparator/src/DoubleComparator.php',
+ 'SebastianBergmann\\Comparator\\ExceptionComparator' => $vendorDir . '/sebastian/comparator/src/ExceptionComparator.php',
+ 'SebastianBergmann\\Comparator\\Factory' => $vendorDir . '/sebastian/comparator/src/Factory.php',
+ 'SebastianBergmann\\Comparator\\MockObjectComparator' => $vendorDir . '/sebastian/comparator/src/MockObjectComparator.php',
+ 'SebastianBergmann\\Comparator\\NumericComparator' => $vendorDir . '/sebastian/comparator/src/NumericComparator.php',
+ 'SebastianBergmann\\Comparator\\ObjectComparator' => $vendorDir . '/sebastian/comparator/src/ObjectComparator.php',
+ 'SebastianBergmann\\Comparator\\ResourceComparator' => $vendorDir . '/sebastian/comparator/src/ResourceComparator.php',
+ 'SebastianBergmann\\Comparator\\ScalarComparator' => $vendorDir . '/sebastian/comparator/src/ScalarComparator.php',
+ 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => $vendorDir . '/sebastian/comparator/src/SplObjectStorageComparator.php',
+ 'SebastianBergmann\\Comparator\\TypeComparator' => $vendorDir . '/sebastian/comparator/src/TypeComparator.php',
+ 'SebastianBergmann\\Diff\\Chunk' => $vendorDir . '/sebastian/diff/src/Chunk.php',
+ 'SebastianBergmann\\Diff\\Diff' => $vendorDir . '/sebastian/diff/src/Diff.php',
+ 'SebastianBergmann\\Diff\\Differ' => $vendorDir . '/sebastian/diff/src/Differ.php',
+ 'SebastianBergmann\\Diff\\LCS\\LongestCommonSubsequence' => $vendorDir . '/sebastian/diff/src/LCS/LongestCommonSubsequence.php',
+ 'SebastianBergmann\\Diff\\LCS\\MemoryEfficientImplementation' => $vendorDir . '/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php',
+ 'SebastianBergmann\\Diff\\LCS\\TimeEfficientImplementation' => $vendorDir . '/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php',
+ 'SebastianBergmann\\Diff\\Line' => $vendorDir . '/sebastian/diff/src/Line.php',
+ 'SebastianBergmann\\Diff\\Parser' => $vendorDir . '/sebastian/diff/src/Parser.php',
+ 'SebastianBergmann\\Environment\\Console' => $vendorDir . '/sebastian/environment/src/Console.php',
+ 'SebastianBergmann\\Environment\\Runtime' => $vendorDir . '/sebastian/environment/src/Runtime.php',
+ 'SebastianBergmann\\Exporter\\Exporter' => $vendorDir . '/sebastian/exporter/src/Exporter.php',
+ 'SebastianBergmann\\GlobalState\\Blacklist' => $vendorDir . '/sebastian/global-state/src/Blacklist.php',
+ 'SebastianBergmann\\GlobalState\\CodeExporter' => $vendorDir . '/sebastian/global-state/src/CodeExporter.php',
+ 'SebastianBergmann\\GlobalState\\Exception' => $vendorDir . '/sebastian/global-state/src/Exception.php',
+ 'SebastianBergmann\\GlobalState\\Restorer' => $vendorDir . '/sebastian/global-state/src/Restorer.php',
+ 'SebastianBergmann\\GlobalState\\RuntimeException' => $vendorDir . '/sebastian/global-state/src/RuntimeException.php',
+ 'SebastianBergmann\\GlobalState\\Snapshot' => $vendorDir . '/sebastian/global-state/src/Snapshot.php',
+ 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => $vendorDir . '/sebastian/object-enumerator/src/Enumerator.php',
+ 'SebastianBergmann\\ObjectEnumerator\\Exception' => $vendorDir . '/sebastian/object-enumerator/src/Exception.php',
+ 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => $vendorDir . '/sebastian/object-enumerator/src/InvalidArgumentException.php',
+ 'SebastianBergmann\\RecursionContext\\Context' => $vendorDir . '/sebastian/recursion-context/src/Context.php',
+ 'SebastianBergmann\\RecursionContext\\Exception' => $vendorDir . '/sebastian/recursion-context/src/Exception.php',
+ 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => $vendorDir . '/sebastian/recursion-context/src/InvalidArgumentException.php',
+ 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => $vendorDir . '/sebastian/resource-operations/src/ResourceOperations.php',
+ 'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php',
+ 'Text_Template' => $vendorDir . '/phpunit/php-text-template/src/Template.php',
+);
diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php
new file mode 100644
index 0000000..814add3
--- /dev/null
+++ b/vendor/composer/autoload_files.php
@@ -0,0 +1,11 @@
+<?php
+
+// autoload_files.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+ '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
+ '6124b4c8570aa390c21fafd04a26c69f' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
+);
diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php
new file mode 100644
index 0000000..b24b217
--- /dev/null
+++ b/vendor/composer/autoload_namespaces.php
@@ -0,0 +1,10 @@
+<?php
+
+// autoload_namespaces.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+ 'Prophecy\\' => array($vendorDir . '/phpspec/prophecy/src'),
+);
diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php
new file mode 100644
index 0000000..f23ddb1
--- /dev/null
+++ b/vendor/composer/autoload_psr4.php
@@ -0,0 +1,17 @@
+<?php
+
+// autoload_psr4.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+ 'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/reflection-docblock/src', $vendorDir . '/phpdocumentor/type-resolver/src'),
+ 'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'),
+ 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
+ 'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
+ 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
+ 'PhpZip\\' => array($vendorDir . '/nelexa/zip/src/PhpZip'),
+ 'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'),
+ 'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'),
+);
diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php
new file mode 100644
index 0000000..962dd34
--- /dev/null
+++ b/vendor/composer/autoload_real.php
@@ -0,0 +1,70 @@
+<?php
+
+// autoload_real.php @generated by Composer
+
+class ComposerAutoloaderInitff1ac78c68d0f00d4eb0afecddc10d83
+{
+ private static $loader;
+
+ public static function loadClassLoader($class)
+ {
+ if ('Composer\Autoload\ClassLoader' === $class) {
+ require __DIR__ . '/ClassLoader.php';
+ }
+ }
+
+ public static function getLoader()
+ {
+ if (null !== self::$loader) {
+ return self::$loader;
+ }
+
+ spl_autoload_register(array('ComposerAutoloaderInitff1ac78c68d0f00d4eb0afecddc10d83', 'loadClassLoader'), true, true);
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader();
+ spl_autoload_unregister(array('ComposerAutoloaderInitff1ac78c68d0f00d4eb0afecddc10d83', 'loadClassLoader'));
+
+ $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
+ if ($useStaticLoader) {
+ require_once __DIR__ . '/autoload_static.php';
+
+ call_user_func(\Composer\Autoload\ComposerStaticInitff1ac78c68d0f00d4eb0afecddc10d83::getInitializer($loader));
+ } else {
+ $map = require __DIR__ . '/autoload_namespaces.php';
+ foreach ($map as $namespace => $path) {
+ $loader->set($namespace, $path);
+ }
+
+ $map = require __DIR__ . '/autoload_psr4.php';
+ foreach ($map as $namespace => $path) {
+ $loader->setPsr4($namespace, $path);
+ }
+
+ $classMap = require __DIR__ . '/autoload_classmap.php';
+ if ($classMap) {
+ $loader->addClassMap($classMap);
+ }
+ }
+
+ $loader->register(true);
+
+ if ($useStaticLoader) {
+ $includeFiles = Composer\Autoload\ComposerStaticInitff1ac78c68d0f00d4eb0afecddc10d83::$files;
+ } else {
+ $includeFiles = require __DIR__ . '/autoload_files.php';
+ }
+ foreach ($includeFiles as $fileIdentifier => $file) {
+ composerRequireff1ac78c68d0f00d4eb0afecddc10d83($fileIdentifier, $file);
+ }
+
+ return $loader;
+ }
+}
+
+function composerRequireff1ac78c68d0f00d4eb0afecddc10d83($fileIdentifier, $file)
+{
+ if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
+ require $file;
+
+ $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
+ }
+}
diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
new file mode 100644
index 0000000..9855433
--- /dev/null
+++ b/vendor/composer/autoload_static.php
@@ -0,0 +1,565 @@
+<?php
+
+// autoload_static.php @generated by Composer
+
+namespace Composer\Autoload;
+
+class ComposerStaticInitff1ac78c68d0f00d4eb0afecddc10d83
+{
+ public static $files = array (
+ '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
+ '6124b4c8570aa390c21fafd04a26c69f' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
+ );
+
+ public static $prefixLengthsPsr4 = array (
+ 'p' =>
+ array (
+ 'phpDocumentor\\Reflection\\' => 25,
+ ),
+ 'W' =>
+ array (
+ 'Webmozart\\Assert\\' => 17,
+ ),
+ 'S' =>
+ array (
+ 'Symfony\\Polyfill\\Ctype\\' => 23,
+ 'Symfony\\Component\\Yaml\\' => 23,
+ ),
+ 'P' =>
+ array (
+ 'Psr\\Http\\Message\\' => 17,
+ 'PhpZip\\' => 7,
+ ),
+ 'D' =>
+ array (
+ 'Doctrine\\Instantiator\\' => 22,
+ 'DeepCopy\\' => 9,
+ ),
+ );
+
+ public static $prefixDirsPsr4 = array (
+ 'phpDocumentor\\Reflection\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src',
+ 1 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src',
+ 2 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src',
+ ),
+ 'Webmozart\\Assert\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/webmozart/assert/src',
+ ),
+ 'Symfony\\Polyfill\\Ctype\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
+ ),
+ 'Symfony\\Component\\Yaml\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/symfony/yaml',
+ ),
+ 'Psr\\Http\\Message\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/psr/http-message/src',
+ ),
+ 'PhpZip\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/nelexa/zip/src/PhpZip',
+ ),
+ 'Doctrine\\Instantiator\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/doctrine/instantiator/src/Doctrine/Instantiator',
+ ),
+ 'DeepCopy\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy',
+ ),
+ );
+
+ public static $prefixesPsr0 = array (
+ 'P' =>
+ array (
+ 'Prophecy\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/phpspec/prophecy/src',
+ ),
+ ),
+ );
+
+ public static $classMap = array (
+ 'File_Iterator' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Iterator.php',
+ 'File_Iterator_Facade' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Facade.php',
+ 'File_Iterator_Factory' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Factory.php',
+ 'PHPUnit\\Framework\\Assert' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/Assert.php',
+ 'PHPUnit\\Framework\\AssertionFailedError' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/AssertionFailedError.php',
+ 'PHPUnit\\Framework\\BaseTestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/BaseTestListener.php',
+ 'PHPUnit\\Framework\\Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/Test.php',
+ 'PHPUnit\\Framework\\TestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/TestCase.php',
+ 'PHPUnit\\Framework\\TestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/TestListener.php',
+ 'PHPUnit\\Framework\\TestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/TestSuite.php',
+ 'PHPUnit_Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Exception.php',
+ 'PHPUnit_Extensions_GroupTestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Extensions/GroupTestSuite.php',
+ 'PHPUnit_Extensions_PhptTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Extensions/PhptTestCase.php',
+ 'PHPUnit_Extensions_PhptTestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Extensions/PhptTestSuite.php',
+ 'PHPUnit_Extensions_RepeatedTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Extensions/RepeatedTest.php',
+ 'PHPUnit_Extensions_TestDecorator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Extensions/TestDecorator.php',
+ 'PHPUnit_Extensions_TicketListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Extensions/TicketListener.php',
+ 'PHPUnit_Framework_Assert' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Assert.php',
+ 'PHPUnit_Framework_AssertionFailedError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/AssertionFailedError.php',
+ 'PHPUnit_Framework_BaseTestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/BaseTestListener.php',
+ 'PHPUnit_Framework_CodeCoverageException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/CodeCoverageException.php',
+ 'PHPUnit_Framework_Constraint' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint.php',
+ 'PHPUnit_Framework_Constraint_And' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/And.php',
+ 'PHPUnit_Framework_Constraint_ArrayHasKey' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php',
+ 'PHPUnit_Framework_Constraint_ArraySubset' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php',
+ 'PHPUnit_Framework_Constraint_Attribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php',
+ 'PHPUnit_Framework_Constraint_Callback' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Callback.php',
+ 'PHPUnit_Framework_Constraint_ClassHasAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php',
+ 'PHPUnit_Framework_Constraint_ClassHasStaticAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php',
+ 'PHPUnit_Framework_Constraint_Composite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Composite.php',
+ 'PHPUnit_Framework_Constraint_Count' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Count.php',
+ 'PHPUnit_Framework_Constraint_DirectoryExists' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php',
+ 'PHPUnit_Framework_Constraint_Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Exception.php',
+ 'PHPUnit_Framework_Constraint_ExceptionCode' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php',
+ 'PHPUnit_Framework_Constraint_ExceptionMessage' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php',
+ 'PHPUnit_Framework_Constraint_ExceptionMessageRegExp' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegExp.php',
+ 'PHPUnit_Framework_Constraint_FileExists' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php',
+ 'PHPUnit_Framework_Constraint_GreaterThan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php',
+ 'PHPUnit_Framework_Constraint_IsAnything' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php',
+ 'PHPUnit_Framework_Constraint_IsEmpty' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php',
+ 'PHPUnit_Framework_Constraint_IsEqual' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php',
+ 'PHPUnit_Framework_Constraint_IsFalse' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php',
+ 'PHPUnit_Framework_Constraint_IsFinite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php',
+ 'PHPUnit_Framework_Constraint_IsIdentical' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php',
+ 'PHPUnit_Framework_Constraint_IsInfinite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php',
+ 'PHPUnit_Framework_Constraint_IsInstanceOf' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php',
+ 'PHPUnit_Framework_Constraint_IsJson' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php',
+ 'PHPUnit_Framework_Constraint_IsNan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php',
+ 'PHPUnit_Framework_Constraint_IsNull' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php',
+ 'PHPUnit_Framework_Constraint_IsReadable' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsReadable.php',
+ 'PHPUnit_Framework_Constraint_IsTrue' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php',
+ 'PHPUnit_Framework_Constraint_IsType' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsType.php',
+ 'PHPUnit_Framework_Constraint_IsWritable' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsWritable.php',
+ 'PHPUnit_Framework_Constraint_JsonMatches' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php',
+ 'PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches/ErrorMessageProvider.php',
+ 'PHPUnit_Framework_Constraint_LessThan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php',
+ 'PHPUnit_Framework_Constraint_Not' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Not.php',
+ 'PHPUnit_Framework_Constraint_ObjectHasAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php',
+ 'PHPUnit_Framework_Constraint_Or' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Or.php',
+ 'PHPUnit_Framework_Constraint_PCREMatch' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/PCREMatch.php',
+ 'PHPUnit_Framework_Constraint_SameSize' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php',
+ 'PHPUnit_Framework_Constraint_StringContains' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php',
+ 'PHPUnit_Framework_Constraint_StringEndsWith' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php',
+ 'PHPUnit_Framework_Constraint_StringMatches' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringMatches.php',
+ 'PHPUnit_Framework_Constraint_StringStartsWith' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php',
+ 'PHPUnit_Framework_Constraint_TraversableContains' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php',
+ 'PHPUnit_Framework_Constraint_TraversableContainsOnly' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php',
+ 'PHPUnit_Framework_Constraint_Xor' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Xor.php',
+ 'PHPUnit_Framework_CoveredCodeNotExecutedException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php',
+ 'PHPUnit_Framework_Error' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error.php',
+ 'PHPUnit_Framework_Error_Deprecated' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Deprecated.php',
+ 'PHPUnit_Framework_Error_Notice' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Notice.php',
+ 'PHPUnit_Framework_Error_Warning' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Warning.php',
+ 'PHPUnit_Framework_Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception.php',
+ 'PHPUnit_Framework_ExceptionWrapper' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php',
+ 'PHPUnit_Framework_ExpectationFailedException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php',
+ 'PHPUnit_Framework_IncompleteTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTest.php',
+ 'PHPUnit_Framework_IncompleteTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php',
+ 'PHPUnit_Framework_IncompleteTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTestError.php',
+ 'PHPUnit_Framework_InvalidCoversTargetException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php',
+ 'PHPUnit_Framework_MissingCoversAnnotationException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php',
+ 'PHPUnit_Framework_MockObject_BadMethodCallException' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/BadMethodCallException.php',
+ 'PHPUnit_Framework_MockObject_Builder_Identity' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Identity.php',
+ 'PHPUnit_Framework_MockObject_Builder_InvocationMocker' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/InvocationMocker.php',
+ 'PHPUnit_Framework_MockObject_Builder_Match' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Match.php',
+ 'PHPUnit_Framework_MockObject_Builder_MethodNameMatch' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/MethodNameMatch.php',
+ 'PHPUnit_Framework_MockObject_Builder_Namespace' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Namespace.php',
+ 'PHPUnit_Framework_MockObject_Builder_ParametersMatch' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/ParametersMatch.php',
+ 'PHPUnit_Framework_MockObject_Builder_Stub' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Stub.php',
+ 'PHPUnit_Framework_MockObject_Exception' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/Exception.php',
+ 'PHPUnit_Framework_MockObject_Generator' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php',
+ 'PHPUnit_Framework_MockObject_Invocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation.php',
+ 'PHPUnit_Framework_MockObject_InvocationMocker' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/InvocationMocker.php',
+ 'PHPUnit_Framework_MockObject_Invocation_Object' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Object.php',
+ 'PHPUnit_Framework_MockObject_Invocation_Static' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Static.php',
+ 'PHPUnit_Framework_MockObject_Invokable' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invokable.php',
+ 'PHPUnit_Framework_MockObject_Matcher' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher.php',
+ 'PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyInvokedCount.php',
+ 'PHPUnit_Framework_MockObject_Matcher_AnyParameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyParameters.php',
+ 'PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/ConsecutiveParameters.php',
+ 'PHPUnit_Framework_MockObject_Matcher_Invocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Invocation.php',
+ 'PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtIndex.php',
+ 'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php',
+ 'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php',
+ 'PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtMostCount.php',
+ 'PHPUnit_Framework_MockObject_Matcher_InvokedCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedCount.php',
+ 'PHPUnit_Framework_MockObject_Matcher_InvokedRecorder' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedRecorder.php',
+ 'PHPUnit_Framework_MockObject_Matcher_MethodName' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/MethodName.php',
+ 'PHPUnit_Framework_MockObject_Matcher_Parameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Parameters.php',
+ 'PHPUnit_Framework_MockObject_Matcher_StatelessInvocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/StatelessInvocation.php',
+ 'PHPUnit_Framework_MockObject_MockBuilder' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockBuilder.php',
+ 'PHPUnit_Framework_MockObject_MockObject' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockObject.php',
+ 'PHPUnit_Framework_MockObject_RuntimeException' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/RuntimeException.php',
+ 'PHPUnit_Framework_MockObject_Stub' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub.php',
+ 'PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ConsecutiveCalls.php',
+ 'PHPUnit_Framework_MockObject_Stub_Exception' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Exception.php',
+ 'PHPUnit_Framework_MockObject_Stub_MatcherCollection' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/MatcherCollection.php',
+ 'PHPUnit_Framework_MockObject_Stub_Return' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Return.php',
+ 'PHPUnit_Framework_MockObject_Stub_ReturnArgument' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnArgument.php',
+ 'PHPUnit_Framework_MockObject_Stub_ReturnCallback' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnCallback.php',
+ 'PHPUnit_Framework_MockObject_Stub_ReturnReference' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnReference.php',
+ 'PHPUnit_Framework_MockObject_Stub_ReturnSelf' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnSelf.php',
+ 'PHPUnit_Framework_MockObject_Stub_ReturnValueMap' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnValueMap.php',
+ 'PHPUnit_Framework_MockObject_Verifiable' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Verifiable.php',
+ 'PHPUnit_Framework_OutputError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/OutputError.php',
+ 'PHPUnit_Framework_RiskyTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/RiskyTest.php',
+ 'PHPUnit_Framework_RiskyTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/RiskyTestError.php',
+ 'PHPUnit_Framework_SelfDescribing' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SelfDescribing.php',
+ 'PHPUnit_Framework_SkippedTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTest.php',
+ 'PHPUnit_Framework_SkippedTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestCase.php',
+ 'PHPUnit_Framework_SkippedTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestError.php',
+ 'PHPUnit_Framework_SkippedTestSuiteError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php',
+ 'PHPUnit_Framework_SyntheticError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SyntheticError.php',
+ 'PHPUnit_Framework_Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Test.php',
+ 'PHPUnit_Framework_TestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestCase.php',
+ 'PHPUnit_Framework_TestFailure' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestFailure.php',
+ 'PHPUnit_Framework_TestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestListener.php',
+ 'PHPUnit_Framework_TestResult' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestResult.php',
+ 'PHPUnit_Framework_TestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestSuite.php',
+ 'PHPUnit_Framework_TestSuite_DataProvider' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestSuite/DataProvider.php',
+ 'PHPUnit_Framework_UnintentionallyCoveredCodeError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php',
+ 'PHPUnit_Framework_Warning' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Warning.php',
+ 'PHPUnit_Framework_WarningTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/WarningTestCase.php',
+ 'PHPUnit_Runner_BaseTestRunner' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/BaseTestRunner.php',
+ 'PHPUnit_Runner_Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Exception.php',
+ 'PHPUnit_Runner_Filter_Factory' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Factory.php',
+ 'PHPUnit_Runner_Filter_GroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Group.php',
+ 'PHPUnit_Runner_Filter_Group_Exclude' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Group/Exclude.php',
+ 'PHPUnit_Runner_Filter_Group_Include' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Group/Include.php',
+ 'PHPUnit_Runner_Filter_Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Test.php',
+ 'PHPUnit_Runner_StandardTestSuiteLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php',
+ 'PHPUnit_Runner_TestSuiteLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php',
+ 'PHPUnit_Runner_Version' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Version.php',
+ 'PHPUnit_TextUI_Command' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/Command.php',
+ 'PHPUnit_TextUI_ResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/ResultPrinter.php',
+ 'PHPUnit_TextUI_TestRunner' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/TestRunner.php',
+ 'PHPUnit_Util_Blacklist' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Blacklist.php',
+ 'PHPUnit_Util_Configuration' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Configuration.php',
+ 'PHPUnit_Util_ConfigurationGenerator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php',
+ 'PHPUnit_Util_ErrorHandler' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/ErrorHandler.php',
+ 'PHPUnit_Util_Fileloader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Fileloader.php',
+ 'PHPUnit_Util_Filesystem' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Filesystem.php',
+ 'PHPUnit_Util_Filter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Filter.php',
+ 'PHPUnit_Util_Getopt' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Getopt.php',
+ 'PHPUnit_Util_GlobalState' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/GlobalState.php',
+ 'PHPUnit_Util_InvalidArgumentHelper' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php',
+ 'PHPUnit_Util_Log_JSON' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/JSON.php',
+ 'PHPUnit_Util_Log_JUnit' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/JUnit.php',
+ 'PHPUnit_Util_Log_TAP' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/TAP.php',
+ 'PHPUnit_Util_Log_TeamCity' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/TeamCity.php',
+ 'PHPUnit_Util_PHP' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP.php',
+ 'PHPUnit_Util_PHP_Default' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/Default.php',
+ 'PHPUnit_Util_PHP_Windows' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/Windows.php',
+ 'PHPUnit_Util_Printer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Printer.php',
+ 'PHPUnit_Util_Regex' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Regex.php',
+ 'PHPUnit_Util_String' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/String.php',
+ 'PHPUnit_Util_Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Test.php',
+ 'PHPUnit_Util_TestDox_NamePrettifier' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php',
+ 'PHPUnit_Util_TestDox_ResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php',
+ 'PHPUnit_Util_TestDox_ResultPrinter_HTML' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/HTML.php',
+ 'PHPUnit_Util_TestDox_ResultPrinter_Text' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/Text.php',
+ 'PHPUnit_Util_TestDox_ResultPrinter_XML' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/XML.php',
+ 'PHPUnit_Util_TestSuiteIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestSuiteIterator.php',
+ 'PHPUnit_Util_Type' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Type.php',
+ 'PHPUnit_Util_XML' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/XML.php',
+ 'PHP_Timer' => __DIR__ . '/..' . '/phpunit/php-timer/src/Timer.php',
+ 'PHP_Token' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_TokenWithScope' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_TokenWithScopeAndVisibility' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ABSTRACT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_AMPERSAND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_AND_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ARRAY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ARRAY_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_AS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ASYNC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_AT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_AWAIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BACKTICK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BAD_CHARACTER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BOOLEAN_AND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BOOLEAN_OR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BOOL_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_BREAK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CALLABLE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CARET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CASE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CATCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CHARACTER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLASS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLASS_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLASS_NAME_CONSTANT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLONE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLOSE_BRACKET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLOSE_CURLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLOSE_SQUARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CLOSE_TAG' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_COALESCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_COLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_COMMA' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_COMMENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_COMPILER_HALT_OFFSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CONCAT_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CONST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CONSTANT_ENCAPSED_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CONTINUE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_CURLY_OPEN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DEC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DECLARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DEFAULT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DIR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DIV' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DIV_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DNUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOC_COMMENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOLLAR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOUBLE_ARROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOUBLE_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOUBLE_COLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_DOUBLE_QUOTES' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ECHO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ELLIPSIS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ELSE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ELSEIF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EMPTY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENCAPSED_AND_WHITESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDDECLARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDFOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDFOREACH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDIF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDSWITCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENDWHILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_END_HEREDOC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ENUM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EQUALS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EVAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EXCLAMATION_MARK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EXIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_EXTENDS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FINAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FINALLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FOREACH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FUNCTION' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_FUNC_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_GLOBAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_GOTO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_HALT_COMPILER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IMPLEMENTS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INCLUDE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INCLUDE_ONCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INLINE_HTML' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INSTANCEOF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INSTEADOF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INTERFACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_INT_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ISSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_GREATER_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_IDENTICAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_NOT_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_NOT_IDENTICAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_IS_SMALLER_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_Includes' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_JOIN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LAMBDA_ARROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LAMBDA_CP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LAMBDA_OP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LINE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LIST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LNUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LOGICAL_AND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LOGICAL_OR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LOGICAL_XOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_METHOD_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MINUS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MINUS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MOD_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MULT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_MUL_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NAMESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NEW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NS_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NS_SEPARATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NULLSAFE_OBJECT_OPERATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_NUM_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OBJECT_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OBJECT_OPERATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_ONUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_BRACKET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_CURLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_SQUARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_TAG' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OPEN_TAG_WITH_ECHO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PERCENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PIPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PLUS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PLUS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_POW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_POW_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PRINT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PRIVATE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PROTECTED' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_PUBLIC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_QUESTION_MARK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_REQUIRE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_REQUIRE_ONCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_RETURN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SEMICOLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SHAPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SL_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SPACESHIP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_START_HEREDOC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_STATIC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_STRING_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_STRING_VARNAME' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SUPER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_SWITCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_Stream' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Stream.php',
+ 'PHP_Token_Stream_CachingFactory' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php',
+ 'PHP_Token_THROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TILDE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TRAIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TRAIT_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TRY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TYPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TYPELIST_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_TYPELIST_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_UNSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_UNSET_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_USE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_USE_FUNCTION' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_VAR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_VARIABLE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_WHERE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_WHILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_WHITESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XHP_ATTRIBUTE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XHP_CATEGORY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XHP_CATEGORY_LABEL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XHP_CHILDREN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XHP_LABEL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XHP_REQUIRED' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XHP_TAG_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XHP_TAG_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XHP_TEXT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_XOR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_YIELD' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'PHP_Token_YIELD_FROM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php',
+ 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage.php',
+ 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php',
+ 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/Driver.php',
+ 'SebastianBergmann\\CodeCoverage\\Driver\\HHVM' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/HHVM.php',
+ 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php',
+ 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/Xdebug.php',
+ 'SebastianBergmann\\CodeCoverage\\Exception' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/Exception.php',
+ 'SebastianBergmann\\CodeCoverage\\Filter' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Filter.php',
+ 'SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php',
+ 'SebastianBergmann\\CodeCoverage\\MissingCoversAnnotationException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/AbstractNode.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\Builder' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Builder.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Directory.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/File.php',
+ 'SebastianBergmann\\CodeCoverage\\Node\\Iterator' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Iterator.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Clover' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Clover.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Crap4j.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Facade.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/PHP.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Text' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Text.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/File.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Method.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Node.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Project.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Report.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php',
+ 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php',
+ 'SebastianBergmann\\CodeCoverage\\RuntimeException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php',
+ 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php',
+ 'SebastianBergmann\\CodeCoverage\\Util' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Util.php',
+ 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => __DIR__ . '/..' . '/sebastian/code-unit-reverse-lookup/src/Wizard.php',
+ 'SebastianBergmann\\Comparator\\ArrayComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ArrayComparator.php',
+ 'SebastianBergmann\\Comparator\\Comparator' => __DIR__ . '/..' . '/sebastian/comparator/src/Comparator.php',
+ 'SebastianBergmann\\Comparator\\ComparisonFailure' => __DIR__ . '/..' . '/sebastian/comparator/src/ComparisonFailure.php',
+ 'SebastianBergmann\\Comparator\\DOMNodeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DOMNodeComparator.php',
+ 'SebastianBergmann\\Comparator\\DateTimeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DateTimeComparator.php',
+ 'SebastianBergmann\\Comparator\\DoubleComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DoubleComparator.php',
+ 'SebastianBergmann\\Comparator\\ExceptionComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ExceptionComparator.php',
+ 'SebastianBergmann\\Comparator\\Factory' => __DIR__ . '/..' . '/sebastian/comparator/src/Factory.php',
+ 'SebastianBergmann\\Comparator\\MockObjectComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/MockObjectComparator.php',
+ 'SebastianBergmann\\Comparator\\NumericComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/NumericComparator.php',
+ 'SebastianBergmann\\Comparator\\ObjectComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ObjectComparator.php',
+ 'SebastianBergmann\\Comparator\\ResourceComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ResourceComparator.php',
+ 'SebastianBergmann\\Comparator\\ScalarComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ScalarComparator.php',
+ 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/SplObjectStorageComparator.php',
+ 'SebastianBergmann\\Comparator\\TypeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/TypeComparator.php',
+ 'SebastianBergmann\\Diff\\Chunk' => __DIR__ . '/..' . '/sebastian/diff/src/Chunk.php',
+ 'SebastianBergmann\\Diff\\Diff' => __DIR__ . '/..' . '/sebastian/diff/src/Diff.php',
+ 'SebastianBergmann\\Diff\\Differ' => __DIR__ . '/..' . '/sebastian/diff/src/Differ.php',
+ 'SebastianBergmann\\Diff\\LCS\\LongestCommonSubsequence' => __DIR__ . '/..' . '/sebastian/diff/src/LCS/LongestCommonSubsequence.php',
+ 'SebastianBergmann\\Diff\\LCS\\MemoryEfficientImplementation' => __DIR__ . '/..' . '/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php',
+ 'SebastianBergmann\\Diff\\LCS\\TimeEfficientImplementation' => __DIR__ . '/..' . '/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php',
+ 'SebastianBergmann\\Diff\\Line' => __DIR__ . '/..' . '/sebastian/diff/src/Line.php',
+ 'SebastianBergmann\\Diff\\Parser' => __DIR__ . '/..' . '/sebastian/diff/src/Parser.php',
+ 'SebastianBergmann\\Environment\\Console' => __DIR__ . '/..' . '/sebastian/environment/src/Console.php',
+ 'SebastianBergmann\\Environment\\Runtime' => __DIR__ . '/..' . '/sebastian/environment/src/Runtime.php',
+ 'SebastianBergmann\\Exporter\\Exporter' => __DIR__ . '/..' . '/sebastian/exporter/src/Exporter.php',
+ 'SebastianBergmann\\GlobalState\\Blacklist' => __DIR__ . '/..' . '/sebastian/global-state/src/Blacklist.php',
+ 'SebastianBergmann\\GlobalState\\CodeExporter' => __DIR__ . '/..' . '/sebastian/global-state/src/CodeExporter.php',
+ 'SebastianBergmann\\GlobalState\\Exception' => __DIR__ . '/..' . '/sebastian/global-state/src/Exception.php',
+ 'SebastianBergmann\\GlobalState\\Restorer' => __DIR__ . '/..' . '/sebastian/global-state/src/Restorer.php',
+ 'SebastianBergmann\\GlobalState\\RuntimeException' => __DIR__ . '/..' . '/sebastian/global-state/src/RuntimeException.php',
+ 'SebastianBergmann\\GlobalState\\Snapshot' => __DIR__ . '/..' . '/sebastian/global-state/src/Snapshot.php',
+ 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/Enumerator.php',
+ 'SebastianBergmann\\ObjectEnumerator\\Exception' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/Exception.php',
+ 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/InvalidArgumentException.php',
+ 'SebastianBergmann\\RecursionContext\\Context' => __DIR__ . '/..' . '/sebastian/recursion-context/src/Context.php',
+ 'SebastianBergmann\\RecursionContext\\Exception' => __DIR__ . '/..' . '/sebastian/recursion-context/src/Exception.php',
+ 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/recursion-context/src/InvalidArgumentException.php',
+ 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => __DIR__ . '/..' . '/sebastian/resource-operations/src/ResourceOperations.php',
+ 'SebastianBergmann\\Version' => __DIR__ . '/..' . '/sebastian/version/src/Version.php',
+ 'Text_Template' => __DIR__ . '/..' . '/phpunit/php-text-template/src/Template.php',
+ );
+
+ public static function getInitializer(ClassLoader $loader)
+ {
+ return \Closure::bind(function () use ($loader) {
+ $loader->prefixLengthsPsr4 = ComposerStaticInitff1ac78c68d0f00d4eb0afecddc10d83::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInitff1ac78c68d0f00d4eb0afecddc10d83::$prefixDirsPsr4;
+ $loader->prefixesPsr0 = ComposerStaticInitff1ac78c68d0f00d4eb0afecddc10d83::$prefixesPsr0;
+ $loader->classMap = ComposerStaticInitff1ac78c68d0f00d4eb0afecddc10d83::$classMap;
+
+ }, null, ClassLoader::class);
+ }
+}
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
new file mode 100644
index 0000000..01cf8e0
--- /dev/null
+++ b/vendor/composer/installed.json
@@ -0,0 +1,1552 @@
+[
+ {
+ "name": "doctrine/instantiator",
+ "version": "1.1.0",
+ "version_normalized": "1.1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
+ "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "athletic/athletic": "~0.1.8",
+ "ext-pdo": "*",
+ "ext-phar": "*",
+ "phpunit/phpunit": "^6.2.3",
+ "squizlabs/php_codesniffer": "^3.0.2"
+ },
+ "time": "2017-07-22T11:58:36+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "http://ocramius.github.com/"
+ }
+ ],
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://github.com/doctrine/instantiator",
+ "keywords": [
+ "constructor",
+ "instantiate"
+ ]
+ },
+ {
+ "name": "myclabs/deep-copy",
+ "version": "1.8.1",
+ "version_normalized": "1.8.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8",
+ "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1"
+ },
+ "replace": {
+ "myclabs/deep-copy": "self.version"
+ },
+ "require-dev": {
+ "doctrine/collections": "^1.0",
+ "doctrine/common": "^2.6",
+ "phpunit/phpunit": "^7.1"
+ },
+ "time": "2018-06-11T23:09:50+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "DeepCopy\\": "src/DeepCopy/"
+ },
+ "files": [
+ "src/DeepCopy/deep_copy.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Create deep copies (clones) of your objects",
+ "keywords": [
+ "clone",
+ "copy",
+ "duplicate",
+ "object",
+ "object graph"
+ ]
+ },
+ {
+ "name": "nelexa/zip",
+ "version": "3.1.5",
+ "version_normalized": "3.1.5.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Ne-Lexa/php-zip.git",
+ "reference": "251ce11bdc4754962f29cd2d31014549377ea617"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Ne-Lexa/php-zip/zipball/251ce11bdc4754962f29cd2d31014549377ea617",
+ "reference": "251ce11bdc4754962f29cd2d31014549377ea617",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.5 || ^7.0",
+ "psr/http-message": "^1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8|~5.7",
+ "zendframework/zend-diactoros": "^1.4"
+ },
+ "suggest": {
+ "ext-bz2": "Needed to support BZIP2 compression",
+ "ext-mcrypt": "Needed to support encrypt zip entries or use ext-openssl",
+ "ext-openssl": "Needed to support encrypt zip entries or use ext-mcrypt"
+ },
+ "time": "2018-04-25T09:44:11+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "PhpZip\\": "src/PhpZip"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ne-Lexa",
+ "email": "alexey@nelexa.ru",
+ "role": "Developer"
+ }
+ ],
+ "description": "PhpZip is a php-library for extended work with ZIP-archives. Open, create, update, delete, extract and get info tool. Supports appending to existing ZIP files, WinZip AES encryption, Traditional PKWARE Encryption, ZipAlign tool, BZIP2 compression, external file attributes and ZIP64 extensions. Alternative ZipArchive. It does not require php-zip extension.",
+ "homepage": "https://github.com/Ne-Lexa/php-zip",
+ "keywords": [
+ "archive",
+ "extract",
+ "unzip",
+ "winzip",
+ "zip",
+ "zipalign",
+ "ziparchive"
+ ]
+ },
+ {
+ "name": "phpdocumentor/reflection-common",
+ "version": "1.0.1",
+ "version_normalized": "1.0.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+ "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
+ "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6"
+ },
+ "time": "2017-09-11T18:02:19+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jaap van Otterdijk",
+ "email": "opensource@ijaap.nl"
+ }
+ ],
+ "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+ "homepage": "http://www.phpdoc.org",
+ "keywords": [
+ "FQSEN",
+ "phpDocumentor",
+ "phpdoc",
+ "reflection",
+ "static analysis"
+ ]
+ },
+ {
+ "name": "phpdocumentor/reflection-docblock",
+ "version": "4.3.0",
+ "version_normalized": "4.3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+ "reference": "94fd0001232e47129dd3504189fa1c7225010d08"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08",
+ "reference": "94fd0001232e47129dd3504189fa1c7225010d08",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0",
+ "phpdocumentor/reflection-common": "^1.0.0",
+ "phpdocumentor/type-resolver": "^0.4.0",
+ "webmozart/assert": "^1.0"
+ },
+ "require-dev": {
+ "doctrine/instantiator": "~1.0.5",
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^6.4"
+ },
+ "time": "2017-11-30T07:14:17+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ],
+ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock."
+ },
+ {
+ "name": "phpdocumentor/type-resolver",
+ "version": "0.4.0",
+ "version_normalized": "0.4.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/TypeResolver.git",
+ "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7",
+ "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.5 || ^7.0",
+ "phpdocumentor/reflection-common": "^1.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^0.9.4",
+ "phpunit/phpunit": "^5.2||^4.8.24"
+ },
+ "time": "2017-07-14T14:27:02+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "phpDocumentor\\Reflection\\": [
+ "src/"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ]
+ },
+ {
+ "name": "phpspec/prophecy",
+ "version": "1.8.0",
+ "version_normalized": "1.8.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpspec/prophecy.git",
+ "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
+ "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.2",
+ "php": "^5.3|^7.0",
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
+ "sebastian/comparator": "^1.1|^2.0|^3.0",
+ "sebastian/recursion-context": "^1.0|^2.0|^3.0"
+ },
+ "require-dev": {
+ "phpspec/phpspec": "^2.5|^3.2",
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
+ },
+ "time": "2018-08-05T17:53:17+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.8.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Prophecy\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com",
+ "homepage": "http://everzet.com"
+ },
+ {
+ "name": "Marcello Duarte",
+ "email": "marcello.duarte@gmail.com"
+ }
+ ],
+ "description": "Highly opinionated mocking framework for PHP 5.3+",
+ "homepage": "https://github.com/phpspec/prophecy",
+ "keywords": [
+ "Double",
+ "Dummy",
+ "fake",
+ "mock",
+ "spy",
+ "stub"
+ ]
+ },
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "4.0.8",
+ "version_normalized": "4.0.8.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d",
+ "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-xmlwriter": "*",
+ "php": "^5.6 || ^7.0",
+ "phpunit/php-file-iterator": "^1.3",
+ "phpunit/php-text-template": "^1.2",
+ "phpunit/php-token-stream": "^1.4.2 || ^2.0",
+ "sebastian/code-unit-reverse-lookup": "^1.0",
+ "sebastian/environment": "^1.3.2 || ^2.0",
+ "sebastian/version": "^1.0 || ^2.0"
+ },
+ "require-dev": {
+ "ext-xdebug": "^2.1.4",
+ "phpunit/phpunit": "^5.7"
+ },
+ "suggest": {
+ "ext-xdebug": "^2.5.1"
+ },
+ "time": "2017-04-02T07:44:40+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+ "keywords": [
+ "coverage",
+ "testing",
+ "xunit"
+ ]
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "1.4.5",
+ "version_normalized": "1.4.5.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4",
+ "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "time": "2017-11-27T13:52:08+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+ "keywords": [
+ "filesystem",
+ "iterator"
+ ]
+ },
+ {
+ "name": "phpunit/php-text-template",
+ "version": "1.2.1",
+ "version_normalized": "1.2.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "time": "2015-06-21T13:50:34+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Simple template engine.",
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+ "keywords": [
+ "template"
+ ]
+ },
+ {
+ "name": "phpunit/php-timer",
+ "version": "1.0.9",
+ "version_normalized": "1.0.9.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
+ "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
+ },
+ "time": "2017-02-26T11:10:40+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Utility class for timing",
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
+ "keywords": [
+ "timer"
+ ]
+ },
+ {
+ "name": "phpunit/php-token-stream",
+ "version": "2.0.2",
+ "version_normalized": "2.0.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+ "reference": "791198a2c6254db10131eecfe8c06670700904db"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db",
+ "reference": "791198a2c6254db10131eecfe8c06670700904db",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": "^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.2.4"
+ },
+ "time": "2017-11-27T05:48:46+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Wrapper around PHP's tokenizer extension.",
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
+ "keywords": [
+ "tokenizer"
+ ]
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "5.7.27",
+ "version_normalized": "5.7.27.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c",
+ "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "myclabs/deep-copy": "~1.3",
+ "php": "^5.6 || ^7.0",
+ "phpspec/prophecy": "^1.6.2",
+ "phpunit/php-code-coverage": "^4.0.4",
+ "phpunit/php-file-iterator": "~1.4",
+ "phpunit/php-text-template": "~1.2",
+ "phpunit/php-timer": "^1.0.6",
+ "phpunit/phpunit-mock-objects": "^3.2",
+ "sebastian/comparator": "^1.2.4",
+ "sebastian/diff": "^1.4.3",
+ "sebastian/environment": "^1.3.4 || ^2.0",
+ "sebastian/exporter": "~2.0",
+ "sebastian/global-state": "^1.1",
+ "sebastian/object-enumerator": "~2.0",
+ "sebastian/resource-operations": "~1.0",
+ "sebastian/version": "^1.0.6|^2.0.1",
+ "symfony/yaml": "~2.1|~3.0|~4.0"
+ },
+ "conflict": {
+ "phpdocumentor/reflection-docblock": "3.0.2"
+ },
+ "require-dev": {
+ "ext-pdo": "*"
+ },
+ "suggest": {
+ "ext-xdebug": "*",
+ "phpunit/php-invoker": "~1.1"
+ },
+ "time": "2018-02-01T05:50:59+00:00",
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.7.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "The PHP Unit Testing framework.",
+ "homepage": "https://phpunit.de/",
+ "keywords": [
+ "phpunit",
+ "testing",
+ "xunit"
+ ]
+ },
+ {
+ "name": "phpunit/phpunit-mock-objects",
+ "version": "3.4.4",
+ "version_normalized": "3.4.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
+ "reference": "a23b761686d50a560cc56233b9ecf49597cc9118"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/a23b761686d50a560cc56233b9ecf49597cc9118",
+ "reference": "a23b761686d50a560cc56233b9ecf49597cc9118",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.0.2",
+ "php": "^5.6 || ^7.0",
+ "phpunit/php-text-template": "^1.2",
+ "sebastian/exporter": "^1.2 || ^2.0"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<5.4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.4"
+ },
+ "suggest": {
+ "ext-soap": "*"
+ },
+ "time": "2017-06-30T09:13:00+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Mock Object library for PHPUnit",
+ "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
+ "keywords": [
+ "mock",
+ "xunit"
+ ]
+ },
+ {
+ "name": "psr/http-message",
+ "version": "1.0.1",
+ "version_normalized": "1.0.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "time": "2016-08-06T14:39:51+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ]
+ },
+ {
+ "name": "sebastian/code-unit-reverse-lookup",
+ "version": "1.0.1",
+ "version_normalized": "1.0.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+ "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
+ "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7 || ^6.0"
+ },
+ "time": "2017-03-04T06:30:41+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Looks up which function or method a line of code belongs to",
+ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "1.2.4",
+ "version_normalized": "1.2.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
+ "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "sebastian/diff": "~1.2",
+ "sebastian/exporter": "~1.2 || ~2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "time": "2017-01-29T09:50:25+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides the functionality to compare PHP values for equality",
+ "homepage": "http://www.github.com/sebastianbergmann/comparator",
+ "keywords": [
+ "comparator",
+ "compare",
+ "equality"
+ ]
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "1.4.3",
+ "version_normalized": "1.4.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4",
+ "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
+ },
+ "time": "2017-05-22T07:24:03+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Diff implementation",
+ "homepage": "https://github.com/sebastianbergmann/diff",
+ "keywords": [
+ "diff"
+ ]
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "2.0.0",
+ "version_normalized": "2.0.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
+ "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.0"
+ },
+ "time": "2016-11-26T07:53:53+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides functionality to handle HHVM/PHP environments",
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
+ "keywords": [
+ "Xdebug",
+ "environment",
+ "hhvm"
+ ]
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "2.0.0",
+ "version_normalized": "2.0.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
+ "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "sebastian/recursion-context": "~2.0"
+ },
+ "require-dev": {
+ "ext-mbstring": "*",
+ "phpunit/phpunit": "~4.4"
+ },
+ "time": "2016-11-19T08:54:04+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
+ "keywords": [
+ "export",
+ "exporter"
+ ]
+ },
+ {
+ "name": "sebastian/global-state",
+ "version": "1.1.1",
+ "version_normalized": "1.1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/global-state.git",
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.2"
+ },
+ "suggest": {
+ "ext-uopz": "*"
+ },
+ "time": "2015-10-12T03:26:01+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Snapshotting of global state",
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
+ "keywords": [
+ "global state"
+ ]
+ },
+ {
+ "name": "sebastian/object-enumerator",
+ "version": "2.0.1",
+ "version_normalized": "2.0.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+ "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7",
+ "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6",
+ "sebastian/recursion-context": "~2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~5"
+ },
+ "time": "2017-02-18T15:18:39+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+ "homepage": "https://github.com/sebastianbergmann/object-enumerator/"
+ },
+ {
+ "name": "sebastian/recursion-context",
+ "version": "2.0.0",
+ "version_normalized": "2.0.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
+ "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a",
+ "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "time": "2016-11-19T07:33:16+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides functionality to recursively process PHP variables",
+ "homepage": "http://www.github.com/sebastianbergmann/recursion-context"
+ },
+ {
+ "name": "sebastian/resource-operations",
+ "version": "1.0.0",
+ "version_normalized": "1.0.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/resource-operations.git",
+ "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
+ "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6.0"
+ },
+ "time": "2015-07-28T20:34:47+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides a list of PHP built-in functions that operate on resources",
+ "homepage": "https://www.github.com/sebastianbergmann/resource-operations"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "2.0.1",
+ "version_normalized": "2.0.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
+ "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "time": "2016-10-03T07:35:21+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+ "homepage": "https://github.com/sebastianbergmann/version"
+ },
+ {
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.9.0",
+ "version_normalized": "1.9.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "e3d826245268269cd66f8326bd8bc066687b4a19"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19",
+ "reference": "e3d826245268269cd66f8326bd8bc066687b4a19",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "time": "2018-08-06T14:22:27+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.9-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ },
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ]
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "v4.1.3",
+ "version_normalized": "4.1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "46bc69aa91fc4ab78a96ce67873a6b0c148fd48c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/46bc69aa91fc4ab78a96ce67873a6b0c148fd48c",
+ "reference": "46bc69aa91fc4ab78a96ce67873a6b0c148fd48c",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1.3",
+ "symfony/polyfill-ctype": "~1.8"
+ },
+ "conflict": {
+ "symfony/console": "<3.4"
+ },
+ "require-dev": {
+ "symfony/console": "~3.4|~4.0"
+ },
+ "suggest": {
+ "symfony/console": "For validating YAML files using the lint command"
+ },
+ "time": "2018-07-26T11:24:31+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.1-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Yaml\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Yaml Component",
+ "homepage": "https://symfony.com"
+ },
+ {
+ "name": "webmozart/assert",
+ "version": "1.3.0",
+ "version_normalized": "1.3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/webmozart/assert.git",
+ "reference": "0df1908962e7a3071564e857d86874dad1ef204a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a",
+ "reference": "0df1908962e7a3071564e857d86874dad1ef204a",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6",
+ "sebastian/version": "^1.0.1"
+ },
+ "time": "2018-01-29T19:49:41+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Webmozart\\Assert\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ }
+ ],
+ "description": "Assertions to validate method input/output with nice error messages.",
+ "keywords": [
+ "assert",
+ "check",
+ "validate"
+ ]
+ }
+]
diff --git a/vendor/doctrine/instantiator/CONTRIBUTING.md b/vendor/doctrine/instantiator/CONTRIBUTING.md
new file mode 100644
index 0000000..75b84b2
--- /dev/null
+++ b/vendor/doctrine/instantiator/CONTRIBUTING.md
@@ -0,0 +1,35 @@
+# Contributing
+
+ * Coding standard for the project is [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)
+ * The project will follow strict [object calisthenics](http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php)
+ * Any contribution must provide tests for additional introduced conditions
+ * Any un-confirmed issue needs a failing test case before being accepted
+ * Pull requests must be sent from a new hotfix/feature branch, not from `master`.
+
+## Installation
+
+To install the project and run the tests, you need to clone it first:
+
+```sh
+$ git clone git://github.com/doctrine/instantiator.git
+```
+
+You will then need to run a composer installation:
+
+```sh
+$ cd Instantiator
+$ curl -s https://getcomposer.org/installer | php
+$ php composer.phar update
+```
+
+## Testing
+
+The PHPUnit version to be used is the one installed as a dev- dependency via composer:
+
+```sh
+$ ./vendor/bin/phpunit
+```
+
+Accepted coverage for new contributions is 80%. Any contribution not satisfying this requirement
+won't be merged.
+
diff --git a/vendor/doctrine/instantiator/LICENSE b/vendor/doctrine/instantiator/LICENSE
new file mode 100644
index 0000000..4d983d1
--- /dev/null
+++ b/vendor/doctrine/instantiator/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2014 Doctrine Project
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/doctrine/instantiator/README.md b/vendor/doctrine/instantiator/README.md
new file mode 100644
index 0000000..b66064b
--- /dev/null
+++ b/vendor/doctrine/instantiator/README.md
@@ -0,0 +1,40 @@
+# Instantiator
+
+This library provides a way of avoiding usage of constructors when instantiating PHP classes.
+
+[![Build Status](https://travis-ci.org/doctrine/instantiator.svg?branch=master)](https://travis-ci.org/doctrine/instantiator)
+[![Code Coverage](https://scrutinizer-ci.com/g/doctrine/instantiator/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/doctrine/instantiator/?branch=master)
+[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/doctrine/instantiator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/doctrine/instantiator/?branch=master)
+[![Dependency Status](https://www.versioneye.com/package/php--doctrine--instantiator/badge.svg)](https://www.versioneye.com/package/php--doctrine--instantiator)
+[![HHVM Status](http://hhvm.h4cc.de/badge/doctrine/instantiator.png)](http://hhvm.h4cc.de/package/doctrine/instantiator)
+
+[![Latest Stable Version](https://poser.pugx.org/doctrine/instantiator/v/stable.png)](https://packagist.org/packages/doctrine/instantiator)
+[![Latest Unstable Version](https://poser.pugx.org/doctrine/instantiator/v/unstable.png)](https://packagist.org/packages/doctrine/instantiator)
+
+## Installation
+
+The suggested installation method is via [composer](https://getcomposer.org/):
+
+```sh
+php composer.phar require "doctrine/instantiator:~1.0.3"
+```
+
+## Usage
+
+The instantiator is able to create new instances of any class without using the constructor or any API of the class
+itself:
+
+```php
+$instantiator = new \Doctrine\Instantiator\Instantiator();
+
+$instance = $instantiator->instantiate(\My\ClassName\Here::class);
+```
+
+## Contributing
+
+Please read the [CONTRIBUTING.md](CONTRIBUTING.md) contents if you wish to help out!
+
+## Credits
+
+This library was migrated from [ocramius/instantiator](https://github.com/Ocramius/Instantiator), which
+has been donated to the doctrine organization, and which is now deprecated in favour of this package.
diff --git a/vendor/doctrine/instantiator/composer.json b/vendor/doctrine/instantiator/composer.json
new file mode 100644
index 0000000..403ee8e
--- /dev/null
+++ b/vendor/doctrine/instantiator/composer.json
@@ -0,0 +1,45 @@
+{
+ "name": "doctrine/instantiator",
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "type": "library",
+ "license": "MIT",
+ "homepage": "https://github.com/doctrine/instantiator",
+ "keywords": [
+ "instantiate",
+ "constructor"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "http://ocramius.github.com/"
+ }
+ ],
+ "require": {
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "ext-phar": "*",
+ "ext-pdo": "*",
+ "phpunit/phpunit": "^6.2.3",
+ "squizlabs/php_codesniffer": "^3.0.2",
+ "athletic/athletic": "~0.1.8"
+ },
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+ }
+ },
+ "autoload-dev": {
+ "psr-0": {
+ "DoctrineTest\\InstantiatorPerformance\\": "tests",
+ "DoctrineTest\\InstantiatorTest\\": "tests",
+ "DoctrineTest\\InstantiatorTestAsset\\": "tests"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ }
+}
diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..3065375
--- /dev/null
+++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php
@@ -0,0 +1,29 @@
+<?php
+/*
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Instantiator\Exception;
+
+/**
+ * Base exception marker interface for the instantiator component
+ *
+ * @author Marco Pivetta <ocramius@gmail.com>
+ */
+interface ExceptionInterface
+{
+}
diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php
new file mode 100644
index 0000000..cb57aa8
--- /dev/null
+++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php
@@ -0,0 +1,52 @@
+<?php
+/*
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Instantiator\Exception;
+
+use InvalidArgumentException as BaseInvalidArgumentException;
+use ReflectionClass;
+
+/**
+ * Exception for invalid arguments provided to the instantiator
+ *
+ * @author Marco Pivetta <ocramius@gmail.com>
+ */
+class InvalidArgumentException extends BaseInvalidArgumentException implements ExceptionInterface
+{
+ public static function fromNonExistingClass(string $className) : self
+ {
+ if (interface_exists($className)) {
+ return new self(sprintf('The provided type "%s" is an interface, and can not be instantiated', $className));
+ }
+
+ if (PHP_VERSION_ID >= 50400 && trait_exists($className)) {
+ return new self(sprintf('The provided type "%s" is a trait, and can not be instantiated', $className));
+ }
+
+ return new self(sprintf('The provided class "%s" does not exist', $className));
+ }
+
+ public static function fromAbstractClass(ReflectionClass $reflectionClass) : self
+ {
+ return new self(sprintf(
+ 'The provided class "%s" is abstract, and can not be instantiated',
+ $reflectionClass->getName()
+ ));
+ }
+}
diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php
new file mode 100644
index 0000000..2b704b9
--- /dev/null
+++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php
@@ -0,0 +1,66 @@
+<?php
+/*
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Instantiator\Exception;
+
+use Exception;
+use ReflectionClass;
+use UnexpectedValueException as BaseUnexpectedValueException;
+
+/**
+ * Exception for given parameters causing invalid/unexpected state on instantiation
+ *
+ * @author Marco Pivetta <ocramius@gmail.com>
+ */
+class UnexpectedValueException extends BaseUnexpectedValueException implements ExceptionInterface
+{
+ public static function fromSerializationTriggeredException(
+ ReflectionClass $reflectionClass,
+ Exception $exception
+ ) : self {
+ return new self(
+ sprintf(
+ 'An exception was raised while trying to instantiate an instance of "%s" via un-serialization',
+ $reflectionClass->getName()
+ ),
+ 0,
+ $exception
+ );
+ }
+
+ public static function fromUncleanUnSerialization(
+ ReflectionClass $reflectionClass,
+ string $errorString,
+ int $errorCode,
+ string $errorFile,
+ int $errorLine
+ ) : self {
+ return new self(
+ sprintf(
+ 'Could not produce an instance of "%s" via un-serialization, since an error was triggered '
+ . 'in file "%s" at line "%d"',
+ $reflectionClass->getName(),
+ $errorFile,
+ $errorLine
+ ),
+ 0,
+ new Exception($errorString, $errorCode)
+ );
+ }
+}
diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php
new file mode 100644
index 0000000..69fe65d
--- /dev/null
+++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php
@@ -0,0 +1,216 @@
+<?php
+/*
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Instantiator;
+
+use Doctrine\Instantiator\Exception\InvalidArgumentException;
+use Doctrine\Instantiator\Exception\UnexpectedValueException;
+use Exception;
+use ReflectionClass;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Marco Pivetta <ocramius@gmail.com>
+ */
+final class Instantiator implements InstantiatorInterface
+{
+ /**
+ * Markers used internally by PHP to define whether {@see \unserialize} should invoke
+ * the method {@see \Serializable::unserialize()} when dealing with classes implementing
+ * the {@see \Serializable} interface.
+ */
+ const SERIALIZATION_FORMAT_USE_UNSERIALIZER = 'C';
+ const SERIALIZATION_FORMAT_AVOID_UNSERIALIZER = 'O';
+
+ /**
+ * @var \callable[] used to instantiate specific classes, indexed by class name
+ */
+ private static $cachedInstantiators = [];
+
+ /**
+ * @var object[] of objects that can directly be cloned, indexed by class name
+ */
+ private static $cachedCloneables = [];
+
+ /**
+ * {@inheritDoc}
+ */
+ public function instantiate($className)
+ {
+ if (isset(self::$cachedCloneables[$className])) {
+ return clone self::$cachedCloneables[$className];
+ }
+
+ if (isset(self::$cachedInstantiators[$className])) {
+ $factory = self::$cachedInstantiators[$className];
+
+ return $factory();
+ }
+
+ return $this->buildAndCacheFromFactory($className);
+ }
+
+ /**
+ * Builds the requested object and caches it in static properties for performance
+ *
+ * @return object
+ */
+ private function buildAndCacheFromFactory(string $className)
+ {
+ $factory = self::$cachedInstantiators[$className] = $this->buildFactory($className);
+ $instance = $factory();
+
+ if ($this->isSafeToClone(new ReflectionClass($instance))) {
+ self::$cachedCloneables[$className] = clone $instance;
+ }
+
+ return $instance;
+ }
+
+ /**
+ * Builds a callable capable of instantiating the given $className without
+ * invoking its constructor.
+ *
+ * @throws InvalidArgumentException
+ * @throws UnexpectedValueException
+ * @throws \ReflectionException
+ */
+ private function buildFactory(string $className) : callable
+ {
+ $reflectionClass = $this->getReflectionClass($className);
+
+ if ($this->isInstantiableViaReflection($reflectionClass)) {
+ return [$reflectionClass, 'newInstanceWithoutConstructor'];
+ }
+
+ $serializedString = sprintf(
+ '%s:%d:"%s":0:{}',
+ self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER,
+ strlen($className),
+ $className
+ );
+
+ $this->checkIfUnSerializationIsSupported($reflectionClass, $serializedString);
+
+ return function () use ($serializedString) {
+ return unserialize($serializedString);
+ };
+ }
+
+ /**
+ * @param string $className
+ *
+ * @return ReflectionClass
+ *
+ * @throws InvalidArgumentException
+ * @throws \ReflectionException
+ */
+ private function getReflectionClass($className) : ReflectionClass
+ {
+ if (! class_exists($className)) {
+ throw InvalidArgumentException::fromNonExistingClass($className);
+ }
+
+ $reflection = new ReflectionClass($className);
+
+ if ($reflection->isAbstract()) {
+ throw InvalidArgumentException::fromAbstractClass($reflection);
+ }
+
+ return $reflection;
+ }
+
+ /**
+ * @param ReflectionClass $reflectionClass
+ * @param string $serializedString
+ *
+ * @throws UnexpectedValueException
+ *
+ * @return void
+ */
+ private function checkIfUnSerializationIsSupported(ReflectionClass $reflectionClass, $serializedString) : void
+ {
+ set_error_handler(function ($code, $message, $file, $line) use ($reflectionClass, & $error) : void {
+ $error = UnexpectedValueException::fromUncleanUnSerialization(
+ $reflectionClass,
+ $message,
+ $code,
+ $file,
+ $line
+ );
+ });
+
+ $this->attemptInstantiationViaUnSerialization($reflectionClass, $serializedString);
+
+ restore_error_handler();
+
+ if ($error) {
+ throw $error;
+ }
+ }
+
+ /**
+ * @param ReflectionClass $reflectionClass
+ * @param string $serializedString
+ *
+ * @throws UnexpectedValueException
+ *
+ * @return void
+ */
+ private function attemptInstantiationViaUnSerialization(ReflectionClass $reflectionClass, $serializedString) : void
+ {
+ try {
+ unserialize($serializedString);
+ } catch (Exception $exception) {
+ restore_error_handler();
+
+ throw UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $exception);
+ }
+ }
+
+ private function isInstantiableViaReflection(ReflectionClass $reflectionClass) : bool
+ {
+ return ! ($this->hasInternalAncestors($reflectionClass) && $reflectionClass->isFinal());
+ }
+
+ /**
+ * Verifies whether the given class is to be considered internal
+ */
+ private function hasInternalAncestors(ReflectionClass $reflectionClass) : bool
+ {
+ do {
+ if ($reflectionClass->isInternal()) {
+ return true;
+ }
+ } while ($reflectionClass = $reflectionClass->getParentClass());
+
+ return false;
+ }
+
+ /**
+ * Checks if a class is cloneable
+ *
+ * Classes implementing `__clone` cannot be safely cloned, as that may cause side-effects.
+ */
+ private function isSafeToClone(ReflectionClass $reflection) : bool
+ {
+ return $reflection->isCloneable() && ! $reflection->hasMethod('__clone');
+ }
+}
diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php
new file mode 100644
index 0000000..b665bea
--- /dev/null
+++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php
@@ -0,0 +1,37 @@
+<?php
+/*
+ * 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.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Instantiator;
+
+/**
+ * Instantiator provides utility methods to build objects without invoking their constructors
+ *
+ * @author Marco Pivetta <ocramius@gmail.com>
+ */
+interface InstantiatorInterface
+{
+ /**
+ * @param string $className
+ *
+ * @return object
+ *
+ * @throws \Doctrine\Instantiator\Exception\ExceptionInterface
+ */
+ public function instantiate($className);
+}
diff --git a/vendor/myclabs/deep-copy/.gitattributes b/vendor/myclabs/deep-copy/.gitattributes
new file mode 100755
index 0000000..8018068
--- /dev/null
+++ b/vendor/myclabs/deep-copy/.gitattributes
@@ -0,0 +1,7 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+*.png binary
+
+tests/ export-ignore
+phpunit.xml.dist export-ignore
diff --git a/vendor/myclabs/deep-copy/.gitignore b/vendor/myclabs/deep-copy/.gitignore
new file mode 100755
index 0000000..eef72f7
--- /dev/null
+++ b/vendor/myclabs/deep-copy/.gitignore
@@ -0,0 +1,3 @@
+/composer.phar
+/composer.lock
+/vendor/*
diff --git a/vendor/myclabs/deep-copy/.scrutinizer.yml b/vendor/myclabs/deep-copy/.scrutinizer.yml
new file mode 100644
index 0000000..6934299
--- /dev/null
+++ b/vendor/myclabs/deep-copy/.scrutinizer.yml
@@ -0,0 +1,4 @@
+build:
+ environment:
+ variables:
+ COMPOSER_ROOT_VERSION: '1.8.0'
diff --git a/vendor/myclabs/deep-copy/.travis.yml b/vendor/myclabs/deep-copy/.travis.yml
new file mode 100755
index 0000000..88f9d2e
--- /dev/null
+++ b/vendor/myclabs/deep-copy/.travis.yml
@@ -0,0 +1,40 @@
+language: php
+
+sudo: false
+
+env:
+ global:
+ - COMPOSER_ROOT_VERSION=1.8.0
+
+php:
+ - '7.1'
+ - '7.2'
+ - nightly
+
+matrix:
+ fast_finish: true
+ include:
+ - php: '7.1'
+ env: COMPOSER_FLAGS="--prefer-lowest"
+ allow_failures:
+ - php: nightly
+
+cache:
+ directories:
+ - $HOME/.composer/cache/files
+
+install:
+ - composer update --no-interaction --no-progress --no-suggest --prefer-dist $COMPOSER_FLAGS
+ - wget https://github.com/satooshi/php-coveralls/releases/download/v1.0.0/coveralls.phar
+
+before_script:
+ - mkdir -p build/logs
+
+script:
+ - vendor/bin/phpunit --coverage-clover build/logs/clover.xml
+
+after_script:
+ - php coveralls.phar -v
+
+notifications:
+ email: false
diff --git a/vendor/myclabs/deep-copy/LICENSE b/vendor/myclabs/deep-copy/LICENSE
new file mode 100644
index 0000000..c3e8350
--- /dev/null
+++ b/vendor/myclabs/deep-copy/LICENSE
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2013 My C-Sense
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/myclabs/deep-copy/README.md b/vendor/myclabs/deep-copy/README.md
new file mode 100644
index 0000000..7abe5dc
--- /dev/null
+++ b/vendor/myclabs/deep-copy/README.md
@@ -0,0 +1,376 @@
+# DeepCopy
+
+DeepCopy helps you create deep copies (clones) of your objects. It is designed to handle cycles in the association graph.
+
+[![Build Status](https://travis-ci.org/myclabs/DeepCopy.png?branch=1.x)](https://travis-ci.org/myclabs/DeepCopy)
+[![Coverage Status](https://coveralls.io/repos/myclabs/DeepCopy/badge.png?branch=1.x)](https://coveralls.io/r/myclabs/DeepCopy?branch=1.x)
+[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/myclabs/DeepCopy/badges/quality-score.png?s=2747100c19b275f93a777e3297c6c12d1b68b934)](https://scrutinizer-ci.com/g/myclabs/DeepCopy/)
+[![Total Downloads](https://poser.pugx.org/myclabs/deep-copy/downloads.svg)](https://packagist.org/packages/myclabs/deep-copy)
+
+
+**You are browsing the 1.x version, this version is in maintenance mode only. Please check the new
+[2.x](https://github.com/myclabs/DeepCopy/tree/2.x) version.**
+
+
+## Table of Contents
+
+1. [How](#how)
+1. [Why](#why)
+ 1. [Using simply `clone`](#using-simply-clone)
+ 1. [Overridding `__clone()`](#overridding-__clone)
+ 1. [With `DeepCopy`](#with-deepcopy)
+1. [How it works](#how-it-works)
+1. [Going further](#going-further)
+ 1. [Matchers](#matchers)
+ 1. [Property name](#property-name)
+ 1. [Specific property](#specific-property)
+ 1. [Type](#type)
+ 1. [Filters](#filters)
+ 1. [`SetNullFilter`](#setnullfilter-filter)
+ 1. [`KeepFilter`](#keepfilter-filter)
+ 1. [`DoctrineCollectionFilter`](#doctrinecollectionfilter-filter)
+ 1. [`DoctrineEmptyCollectionFilter`](#doctrineemptycollectionfilter-filter)
+ 1. [`DoctrineProxyFilter`](#doctrineproxyfilter-filter)
+ 1. [`ReplaceFilter`](#replacefilter-type-filter)
+ 1. [`ShallowCopyFilter`](#shallowcopyfilter-type-filter)
+1. [Edge cases](#edge-cases)
+1. [Contributing](#contributing)
+ 1. [Tests](#tests)
+
+
+## How?
+
+Install with Composer:
+
+```json
+composer require myclabs/deep-copy
+```
+
+Use simply:
+
+```php
+use DeepCopy\DeepCopy;
+
+$copier = new DeepCopy();
+$myCopy = $copier->copy($myObject);
+```
+
+
+## Why?
+
+- How do you create copies of your objects?
+
+```php
+$myCopy = clone $myObject;
+```
+
+- How do you create **deep** copies of your objects (i.e. copying also all the objects referenced in the properties)?
+
+You use [`__clone()`](http://www.php.net/manual/en/language.oop5.cloning.php#object.clone) and implement the behavior
+yourself.
+
+- But how do you handle **cycles** in the association graph?
+
+Now you're in for a big mess :(
+
+![association graph](doc/graph.png)
+
+
+### Using simply `clone`
+
+![Using clone](doc/clone.png)
+
+
+### Overridding `__clone()`
+
+![Overridding __clone](doc/deep-clone.png)
+
+
+### With `DeepCopy`
+
+![With DeepCopy](doc/deep-copy.png)
+
+
+## How it works
+
+DeepCopy recursively traverses all the object's properties and clones them. To avoid cloning the same object twice it
+keeps a hash map of all instances and thus preserves the object graph.
+
+To use it:
+
+```php
+use function DeepCopy\deep_copy;
+
+$copy = deep_copy($var);
+```
+
+Alternatively, you can create your own `DeepCopy` instance to configure it differently for example:
+
+```php
+use DeepCopy\DeepCopy;
+
+$copier = new DeepCopy(true);
+
+$copy = $copier->copy($var);
+```
+
+You may want to roll your own deep copy function:
+
+```php
+namespace Acme;
+
+use DeepCopy\DeepCopy;
+
+function deep_copy($var)
+{
+ static $copier = null;
+
+ if (null === $copier) {
+ $copier = new DeepCopy(true);
+ }
+
+ return $copier->copy($var);
+}
+```
+
+
+## Going further
+
+You can add filters to customize the copy process.
+
+The method to add a filter is `DeepCopy\DeepCopy::addFilter($filter, $matcher)`,
+with `$filter` implementing `DeepCopy\Filter\Filter`
+and `$matcher` implementing `DeepCopy\Matcher\Matcher`.
+
+We provide some generic filters and matchers.
+
+
+### Matchers
+
+ - `DeepCopy\Matcher` applies on a object attribute.
+ - `DeepCopy\TypeMatcher` applies on any element found in graph, including array elements.
+
+
+#### Property name
+
+The `PropertyNameMatcher` will match a property by its name:
+
+```php
+use DeepCopy\Matcher\PropertyNameMatcher;
+
+// Will apply a filter to any property of any objects named "id"
+$matcher = new PropertyNameMatcher('id');
+```
+
+
+#### Specific property
+
+The `PropertyMatcher` will match a specific property of a specific class:
+
+```php
+use DeepCopy\Matcher\PropertyMatcher;
+
+// Will apply a filter to the property "id" of any objects of the class "MyClass"
+$matcher = new PropertyMatcher('MyClass', 'id');
+```
+
+
+#### Type
+
+The `TypeMatcher` will match any element by its type (instance of a class or any value that could be parameter of
+[gettype()](http://php.net/manual/en/function.gettype.php) function):
+
+```php
+use DeepCopy\TypeMatcher\TypeMatcher;
+
+// Will apply a filter to any object that is an instance of Doctrine\Common\Collections\Collection
+$matcher = new TypeMatcher('Doctrine\Common\Collections\Collection');
+```
+
+
+### Filters
+
+- `DeepCopy\Filter` applies a transformation to the object attribute matched by `DeepCopy\Matcher`
+- `DeepCopy\TypeFilter` applies a transformation to any element matched by `DeepCopy\TypeMatcher`
+
+
+#### `SetNullFilter` (filter)
+
+Let's say for example that you are copying a database record (or a Doctrine entity), so you want the copy not to have
+any ID:
+
+```php
+use DeepCopy\DeepCopy;
+use DeepCopy\Filter\SetNullFilter;
+use DeepCopy\Matcher\PropertyNameMatcher;
+
+$object = MyClass::load(123);
+echo $object->id; // 123
+
+$copier = new DeepCopy();
+$copier->addFilter(new SetNullFilter(), new PropertyNameMatcher('id'));
+
+$copy = $copier->copy($object);
+
+echo $copy->id; // null
+```
+
+
+#### `KeepFilter` (filter)
+
+If you want a property to remain untouched (for example, an association to an object):
+
+```php
+use DeepCopy\DeepCopy;
+use DeepCopy\Filter\KeepFilter;
+use DeepCopy\Matcher\PropertyMatcher;
+
+$copier = new DeepCopy();
+$copier->addFilter(new KeepFilter(), new PropertyMatcher('MyClass', 'category'));
+
+$copy = $copier->copy($object);
+// $copy->category has not been touched
+```
+
+
+#### `DoctrineCollectionFilter` (filter)
+
+If you use Doctrine and want to copy an entity, you will need to use the `DoctrineCollectionFilter`:
+
+```php
+use DeepCopy\DeepCopy;
+use DeepCopy\Filter\Doctrine\DoctrineCollectionFilter;
+use DeepCopy\Matcher\PropertyTypeMatcher;
+
+$copier = new DeepCopy();
+$copier->addFilter(new DoctrineCollectionFilter(), new PropertyTypeMatcher('Doctrine\Common\Collections\Collection'));
+
+$copy = $copier->copy($object);
+```
+
+
+#### `DoctrineEmptyCollectionFilter` (filter)
+
+If you use Doctrine and want to copy an entity who contains a `Collection` that you want to be reset, you can use the
+`DoctrineEmptyCollectionFilter`
+
+```php
+use DeepCopy\DeepCopy;
+use DeepCopy\Filter\Doctrine\DoctrineEmptyCollectionFilter;
+use DeepCopy\Matcher\PropertyMatcher;
+
+$copier = new DeepCopy();
+$copier->addFilter(new DoctrineEmptyCollectionFilter(), new PropertyMatcher('MyClass', 'myProperty'));
+
+$copy = $copier->copy($object);
+
+// $copy->myProperty will return an empty collection
+```
+
+
+#### `DoctrineProxyFilter` (filter)
+
+If you use Doctrine and use cloning on lazy loaded entities, you might encounter errors mentioning missing fields on a
+Doctrine proxy class (...\\\_\_CG\_\_\Proxy).
+You can use the `DoctrineProxyFilter` to load the actual entity behind the Doctrine proxy class.
+**Make sure, though, to put this as one of your very first filters in the filter chain so that the entity is loaded
+before other filters are applied!**
+
+```php
+use DeepCopy\DeepCopy;
+use DeepCopy\Filter\Doctrine\DoctrineProxyFilter;
+use DeepCopy\Matcher\Doctrine\DoctrineProxyMatcher;
+
+$copier = new DeepCopy();
+$copier->addFilter(new DoctrineProxyFilter(), new DoctrineProxyMatcher());
+
+$copy = $copier->copy($object);
+
+// $copy should now contain a clone of all entities, including those that were not yet fully loaded.
+```
+
+
+#### `ReplaceFilter` (type filter)
+
+1. If you want to replace the value of a property:
+
+```php
+use DeepCopy\DeepCopy;
+use DeepCopy\Filter\ReplaceFilter;
+use DeepCopy\Matcher\PropertyMatcher;
+
+$copier = new DeepCopy();
+$callback = function ($currentValue) {
+ return $currentValue . ' (copy)'
+};
+$copier->addFilter(new ReplaceFilter($callback), new PropertyMatcher('MyClass', 'title'));
+
+$copy = $copier->copy($object);
+
+// $copy->title will contain the data returned by the callback, e.g. 'The title (copy)'
+```
+
+2. If you want to replace whole element:
+
+```php
+use DeepCopy\DeepCopy;
+use DeepCopy\TypeFilter\ReplaceFilter;
+use DeepCopy\TypeMatcher\TypeMatcher;
+
+$copier = new DeepCopy();
+$callback = function (MyClass $myClass) {
+ return get_class($myClass);
+};
+$copier->addTypeFilter(new ReplaceFilter($callback), new TypeMatcher('MyClass'));
+
+$copy = $copier->copy([new MyClass, 'some string', new MyClass]);
+
+// $copy will contain ['MyClass', 'some string', 'MyClass']
+```
+
+
+The `$callback` parameter of the `ReplaceFilter` constructor accepts any PHP callable.
+
+
+#### `ShallowCopyFilter` (type filter)
+
+Stop *DeepCopy* from recursively copying element, using standard `clone` instead:
+
+```php
+use DeepCopy\DeepCopy;
+use DeepCopy\TypeFilter\ShallowCopyFilter;
+use DeepCopy\TypeMatcher\TypeMatcher;
+use Mockery as m;
+
+$this->deepCopy = new DeepCopy();
+$this->deepCopy->addTypeFilter(
+ new ShallowCopyFilter,
+ new TypeMatcher(m\MockInterface::class)
+);
+
+$myServiceWithMocks = new MyService(m::mock(MyDependency1::class), m::mock(MyDependency2::class));
+// All mocks will be just cloned, not deep copied
+```
+
+
+## Edge cases
+
+The following structures cannot be deep-copied with PHP Reflection. As a result they are shallow cloned and filters are
+not applied. There is two ways for you to handle them:
+
+- Implement your own `__clone()` method
+- Use a filter with a type matcher
+
+
+## Contributing
+
+DeepCopy is distributed under the MIT license.
+
+
+### Tests
+
+Running the tests is simple:
+
+```php
+vendor/bin/phpunit
+```
diff --git a/vendor/myclabs/deep-copy/composer.json b/vendor/myclabs/deep-copy/composer.json
new file mode 100644
index 0000000..4108a23
--- /dev/null
+++ b/vendor/myclabs/deep-copy/composer.json
@@ -0,0 +1,38 @@
+{
+ "name": "myclabs/deep-copy",
+ "type": "library",
+ "description": "Create deep copies (clones) of your objects",
+ "keywords": ["clone", "copy", "duplicate", "object", "object graph"],
+ "license": "MIT",
+
+ "autoload": {
+ "psr-4": {
+ "DeepCopy\\": "src/DeepCopy/"
+ },
+ "files": [
+ "src/DeepCopy/deep_copy.php"
+ ]
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "DeepCopy\\": "fixtures/",
+ "DeepCopyTest\\": "tests/DeepCopyTest/"
+ }
+ },
+
+ "require": {
+ "php": "^7.1"
+ },
+ "require-dev": {
+ "doctrine/collections": "^1.0",
+ "doctrine/common": "^2.6",
+ "phpunit/phpunit": "^7.1"
+ },
+ "replace": {
+ "myclabs/deep-copy": "self.version"
+ },
+
+ "config": {
+ "sort-packages": true
+ }
+}
diff --git a/vendor/myclabs/deep-copy/doc/clone.png b/vendor/myclabs/deep-copy/doc/clone.png
new file mode 100644
index 0000000..376afd4
--- /dev/null
+++ b/vendor/myclabs/deep-copy/doc/clone.png
Binary files differ
diff --git a/vendor/myclabs/deep-copy/doc/deep-clone.png b/vendor/myclabs/deep-copy/doc/deep-clone.png
new file mode 100644
index 0000000..2b37a6d
--- /dev/null
+++ b/vendor/myclabs/deep-copy/doc/deep-clone.png
Binary files differ
diff --git a/vendor/myclabs/deep-copy/doc/deep-copy.png b/vendor/myclabs/deep-copy/doc/deep-copy.png
new file mode 100644
index 0000000..68c508a
--- /dev/null
+++ b/vendor/myclabs/deep-copy/doc/deep-copy.png
Binary files differ
diff --git a/vendor/myclabs/deep-copy/doc/graph.png b/vendor/myclabs/deep-copy/doc/graph.png
new file mode 100644
index 0000000..4d5c942
--- /dev/null
+++ b/vendor/myclabs/deep-copy/doc/graph.png
Binary files differ
diff --git a/vendor/myclabs/deep-copy/fixtures/f001/A.php b/vendor/myclabs/deep-copy/fixtures/f001/A.php
new file mode 100644
index 0000000..648d5df
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f001/A.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace DeepCopy\f001;
+
+class A
+{
+ private $aProp;
+
+ public function getAProp()
+ {
+ return $this->aProp;
+ }
+
+ public function setAProp($prop)
+ {
+ $this->aProp = $prop;
+
+ return $this;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f001/B.php b/vendor/myclabs/deep-copy/fixtures/f001/B.php
new file mode 100644
index 0000000..462bb44
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f001/B.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace DeepCopy\f001;
+
+class B extends A
+{
+ private $bProp;
+
+ public function getBProp()
+ {
+ return $this->bProp;
+ }
+
+ public function setBProp($prop)
+ {
+ $this->bProp = $prop;
+
+ return $this;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f002/A.php b/vendor/myclabs/deep-copy/fixtures/f002/A.php
new file mode 100644
index 0000000..d9aa5c3
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f002/A.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace DeepCopy\f002;
+
+class A
+{
+ private $prop1;
+ private $prop2;
+
+ public function getProp1()
+ {
+ return $this->prop1;
+ }
+
+ public function setProp1($prop)
+ {
+ $this->prop1 = $prop;
+
+ return $this;
+ }
+
+ public function getProp2()
+ {
+ return $this->prop2;
+ }
+
+ public function setProp2($prop)
+ {
+ $this->prop2 = $prop;
+
+ return $this;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f003/Foo.php b/vendor/myclabs/deep-copy/fixtures/f003/Foo.php
new file mode 100644
index 0000000..9cd7622
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f003/Foo.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace DeepCopy\f003;
+
+class Foo
+{
+ private $name;
+ private $prop;
+
+ public function __construct($name)
+ {
+ $this->name = $name;
+ }
+
+ public function getProp()
+ {
+ return $this->prop;
+ }
+
+ public function setProp($prop)
+ {
+ $this->prop = $prop;
+
+ return $this;
+ }
+} \ No newline at end of file
diff --git a/vendor/myclabs/deep-copy/fixtures/f004/UnclonableItem.php b/vendor/myclabs/deep-copy/fixtures/f004/UnclonableItem.php
new file mode 100644
index 0000000..82c6c67
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f004/UnclonableItem.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace DeepCopy\f004;
+
+use BadMethodCallException;
+
+class UnclonableItem
+{
+ private function __clone()
+ {
+ throw new BadMethodCallException('Unsupported call.');
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f005/Foo.php b/vendor/myclabs/deep-copy/fixtures/f005/Foo.php
new file mode 100644
index 0000000..a4c86c6
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f005/Foo.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace DeepCopy\f005;
+
+class Foo
+{
+ public $cloned = false;
+
+ public function __clone()
+ {
+ $this->cloned = true;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f006/A.php b/vendor/myclabs/deep-copy/fixtures/f006/A.php
new file mode 100644
index 0000000..d9efb11
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f006/A.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace DeepCopy\f006;
+
+class A
+{
+ public $cloned = false;
+ private $aProp;
+
+ public function getAProp()
+ {
+ return $this->aProp;
+ }
+
+ public function setAProp($prop)
+ {
+ $this->aProp = $prop;
+
+ return $this;
+ }
+
+ public function __clone()
+ {
+ $this->cloned = true;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f006/B.php b/vendor/myclabs/deep-copy/fixtures/f006/B.php
new file mode 100644
index 0000000..1f80b3d
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f006/B.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace DeepCopy\f006;
+
+class B
+{
+ public $cloned = false;
+ private $bProp;
+
+ public function getBProp()
+ {
+ return $this->bProp;
+ }
+
+ public function setBProp($prop)
+ {
+ $this->bProp = $prop;
+
+ return $this;
+ }
+
+ public function __clone()
+ {
+ $this->cloned = true;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f007/FooDateInterval.php b/vendor/myclabs/deep-copy/fixtures/f007/FooDateInterval.php
new file mode 100644
index 0000000..e16bc6a
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f007/FooDateInterval.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace DeepCopy\f007;
+
+use DateInterval;
+
+class FooDateInterval extends DateInterval
+{
+ public $cloned = false;
+
+ public function __clone()
+ {
+ $this->cloned = true;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f007/FooDateTimeZone.php b/vendor/myclabs/deep-copy/fixtures/f007/FooDateTimeZone.php
new file mode 100644
index 0000000..6f4e61f
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f007/FooDateTimeZone.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace DeepCopy\f007;
+
+use DateTimeZone;
+
+class FooDateTimeZone extends DateTimeZone
+{
+ public $cloned = false;
+
+ public function __clone()
+ {
+ $this->cloned = true;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f008/A.php b/vendor/myclabs/deep-copy/fixtures/f008/A.php
new file mode 100644
index 0000000..88471d0
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f008/A.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace DeepCopy\f008;
+
+class A
+{
+ private $foo;
+
+ public function __construct($foo)
+ {
+ $this->foo = $foo;
+ }
+
+ public function getFoo()
+ {
+ return $this->foo;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/fixtures/f008/B.php b/vendor/myclabs/deep-copy/fixtures/f008/B.php
new file mode 100644
index 0000000..6053092
--- /dev/null
+++ b/vendor/myclabs/deep-copy/fixtures/f008/B.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace DeepCopy\f008;
+
+class B extends A
+{
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/DeepCopy.php b/vendor/myclabs/deep-copy/src/DeepCopy/DeepCopy.php
new file mode 100644
index 0000000..d461ff6
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/DeepCopy.php
@@ -0,0 +1,281 @@
+<?php
+
+namespace DeepCopy;
+
+use DateInterval;
+use DateTimeInterface;
+use DateTimeZone;
+use DeepCopy\Exception\CloneException;
+use DeepCopy\Filter\Filter;
+use DeepCopy\Matcher\Matcher;
+use DeepCopy\TypeFilter\Date\DateIntervalFilter;
+use DeepCopy\TypeFilter\Spl\SplDoublyLinkedListFilter;
+use DeepCopy\TypeFilter\TypeFilter;
+use DeepCopy\TypeMatcher\TypeMatcher;
+use ReflectionObject;
+use ReflectionProperty;
+use DeepCopy\Reflection\ReflectionHelper;
+use SplDoublyLinkedList;
+
+/**
+ * @final
+ */
+class DeepCopy
+{
+ /**
+ * @var object[] List of objects copied.
+ */
+ private $hashMap = [];
+
+ /**
+ * Filters to apply.
+ *
+ * @var array Array of ['filter' => Filter, 'matcher' => Matcher] pairs.
+ */
+ private $filters = [];
+
+ /**
+ * Type Filters to apply.
+ *
+ * @var array Array of ['filter' => Filter, 'matcher' => Matcher] pairs.
+ */
+ private $typeFilters = [];
+
+ /**
+ * @var bool
+ */
+ private $skipUncloneable = false;
+
+ /**
+ * @var bool
+ */
+ private $useCloneMethod;
+
+ /**
+ * @param bool $useCloneMethod If set to true, when an object implements the __clone() function, it will be used
+ * instead of the regular deep cloning.
+ */
+ public function __construct($useCloneMethod = false)
+ {
+ $this->useCloneMethod = $useCloneMethod;
+
+ $this->addTypeFilter(new DateIntervalFilter(), new TypeMatcher(DateInterval::class));
+ $this->addTypeFilter(new SplDoublyLinkedListFilter($this), new TypeMatcher(SplDoublyLinkedList::class));
+ }
+
+ /**
+ * If enabled, will not throw an exception when coming across an uncloneable property.
+ *
+ * @param $skipUncloneable
+ *
+ * @return $this
+ */
+ public function skipUncloneable($skipUncloneable = true)
+ {
+ $this->skipUncloneable = $skipUncloneable;
+
+ return $this;
+ }
+
+ /**
+ * Deep copies the given object.
+ *
+ * @param mixed $object
+ *
+ * @return mixed
+ */
+ public function copy($object)
+ {
+ $this->hashMap = [];
+
+ return $this->recursiveCopy($object);
+ }
+
+ public function addFilter(Filter $filter, Matcher $matcher)
+ {
+ $this->filters[] = [
+ 'matcher' => $matcher,
+ 'filter' => $filter,
+ ];
+ }
+
+ public function addTypeFilter(TypeFilter $filter, TypeMatcher $matcher)
+ {
+ $this->typeFilters[] = [
+ 'matcher' => $matcher,
+ 'filter' => $filter,
+ ];
+ }
+
+ private function recursiveCopy($var)
+ {
+ // Matches Type Filter
+ if ($filter = $this->getFirstMatchedTypeFilter($this->typeFilters, $var)) {
+ return $filter->apply($var);
+ }
+
+ // Resource
+ if (is_resource($var)) {
+ return $var;
+ }
+
+ // Array
+ if (is_array($var)) {
+ return $this->copyArray($var);
+ }
+
+ // Scalar
+ if (! is_object($var)) {
+ return $var;
+ }
+
+ // Object
+ return $this->copyObject($var);
+ }
+
+ /**
+ * Copy an array
+ * @param array $array
+ * @return array
+ */
+ private function copyArray(array $array)
+ {
+ foreach ($array as $key => $value) {
+ $array[$key] = $this->recursiveCopy($value);
+ }
+
+ return $array;
+ }
+
+ /**
+ * Copies an object.
+ *
+ * @param object $object
+ *
+ * @throws CloneException
+ *
+ * @return object
+ */
+ private function copyObject($object)
+ {
+ $objectHash = spl_object_hash($object);
+
+ if (isset($this->hashMap[$objectHash])) {
+ return $this->hashMap[$objectHash];
+ }
+
+ $reflectedObject = new ReflectionObject($object);
+ $isCloneable = $reflectedObject->isCloneable();
+
+ if (false === $isCloneable) {
+ if ($this->skipUncloneable) {
+ $this->hashMap[$objectHash] = $object;
+
+ return $object;
+ }
+
+ throw new CloneException(
+ sprintf(
+ 'The class "%s" is not cloneable.',
+ $reflectedObject->getName()
+ )
+ );
+ }
+
+ $newObject = clone $object;
+ $this->hashMap[$objectHash] = $newObject;
+
+ if ($this->useCloneMethod && $reflectedObject->hasMethod('__clone')) {
+ return $newObject;
+ }
+
+ if ($newObject instanceof DateTimeInterface || $newObject instanceof DateTimeZone) {
+ return $newObject;
+ }
+
+ foreach (ReflectionHelper::getProperties($reflectedObject) as $property) {
+ $this->copyObjectProperty($newObject, $property);
+ }
+
+ return $newObject;
+ }
+
+ private function copyObjectProperty($object, ReflectionProperty $property)
+ {
+ // Ignore static properties
+ if ($property->isStatic()) {
+ return;
+ }
+
+ // Apply the filters
+ foreach ($this->filters as $item) {
+ /** @var Matcher $matcher */
+ $matcher = $item['matcher'];
+ /** @var Filter $filter */
+ $filter = $item['filter'];
+
+ if ($matcher->matches($object, $property->getName())) {
+ $filter->apply(
+ $object,
+ $property->getName(),
+ function ($object) {
+ return $this->recursiveCopy($object);
+ }
+ );
+
+ // If a filter matches, we stop processing this property
+ return;
+ }
+ }
+
+ $property->setAccessible(true);
+ $propertyValue = $property->getValue($object);
+
+ // Copy the property
+ $property->setValue($object, $this->recursiveCopy($propertyValue));
+ }
+
+ /**
+ * Returns first filter that matches variable, `null` if no such filter found.
+ *
+ * @param array $filterRecords Associative array with 2 members: 'filter' with value of type {@see TypeFilter} and
+ * 'matcher' with value of type {@see TypeMatcher}
+ * @param mixed $var
+ *
+ * @return TypeFilter|null
+ */
+ private function getFirstMatchedTypeFilter(array $filterRecords, $var)
+ {
+ $matched = $this->first(
+ $filterRecords,
+ function (array $record) use ($var) {
+ /* @var TypeMatcher $matcher */
+ $matcher = $record['matcher'];
+
+ return $matcher->matches($var);
+ }
+ );
+
+ return isset($matched) ? $matched['filter'] : null;
+ }
+
+ /**
+ * Returns first element that matches predicate, `null` if no such element found.
+ *
+ * @param array $elements Array of ['filter' => Filter, 'matcher' => Matcher] pairs.
+ * @param callable $predicate Predicate arguments are: element.
+ *
+ * @return array|null Associative array with 2 members: 'filter' with value of type {@see TypeFilter} and 'matcher'
+ * with value of type {@see TypeMatcher} or `null`.
+ */
+ private function first(array $elements, callable $predicate)
+ {
+ foreach ($elements as $element) {
+ if (call_user_func($predicate, $element)) {
+ return $element;
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php b/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php
new file mode 100644
index 0000000..c046706
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php
@@ -0,0 +1,9 @@
+<?php
+
+namespace DeepCopy\Exception;
+
+use UnexpectedValueException;
+
+class CloneException extends UnexpectedValueException
+{
+} \ No newline at end of file
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Exception/PropertyException.php b/vendor/myclabs/deep-copy/src/DeepCopy/Exception/PropertyException.php
new file mode 100644
index 0000000..9702101
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Exception/PropertyException.php
@@ -0,0 +1,9 @@
+<?php
+
+namespace DeepCopy\Exception;
+
+use ReflectionException;
+
+class PropertyException extends ReflectionException
+{
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php
new file mode 100644
index 0000000..e6d9377
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace DeepCopy\Filter\Doctrine;
+
+use DeepCopy\Filter\Filter;
+use DeepCopy\Reflection\ReflectionHelper;
+
+/**
+ * @final
+ */
+class DoctrineCollectionFilter implements Filter
+{
+ /**
+ * Copies the object property doctrine collection.
+ *
+ * {@inheritdoc}
+ */
+ public function apply($object, $property, $objectCopier)
+ {
+ $reflectionProperty = ReflectionHelper::getProperty($object, $property);
+
+ $reflectionProperty->setAccessible(true);
+ $oldCollection = $reflectionProperty->getValue($object);
+
+ $newCollection = $oldCollection->map(
+ function ($item) use ($objectCopier) {
+ return $objectCopier($item);
+ }
+ );
+
+ $reflectionProperty->setValue($object, $newCollection);
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php
new file mode 100644
index 0000000..7b33fd5
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace DeepCopy\Filter\Doctrine;
+
+use DeepCopy\Filter\Filter;
+use DeepCopy\Reflection\ReflectionHelper;
+use Doctrine\Common\Collections\ArrayCollection;
+
+/**
+ * @final
+ */
+class DoctrineEmptyCollectionFilter implements Filter
+{
+ /**
+ * Sets the object property to an empty doctrine collection.
+ *
+ * @param object $object
+ * @param string $property
+ * @param callable $objectCopier
+ */
+ public function apply($object, $property, $objectCopier)
+ {
+ $reflectionProperty = ReflectionHelper::getProperty($object, $property);
+ $reflectionProperty->setAccessible(true);
+
+ $reflectionProperty->setValue($object, new ArrayCollection());
+ }
+} \ No newline at end of file
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php
new file mode 100644
index 0000000..8bee8f7
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace DeepCopy\Filter\Doctrine;
+
+use DeepCopy\Filter\Filter;
+
+/**
+ * @final
+ */
+class DoctrineProxyFilter implements Filter
+{
+ /**
+ * Triggers the magic method __load() on a Doctrine Proxy class to load the
+ * actual entity from the database.
+ *
+ * {@inheritdoc}
+ */
+ public function apply($object, $property, $objectCopier)
+ {
+ $object->__load();
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php
new file mode 100644
index 0000000..85ba18c
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace DeepCopy\Filter;
+
+/**
+ * Filter to apply to a property while copying an object
+ */
+interface Filter
+{
+ /**
+ * Applies the filter to the object.
+ *
+ * @param object $object
+ * @param string $property
+ * @param callable $objectCopier
+ */
+ public function apply($object, $property, $objectCopier);
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Filter/KeepFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/KeepFilter.php
new file mode 100644
index 0000000..4b11a08
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/KeepFilter.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace DeepCopy\Filter;
+
+class KeepFilter implements Filter
+{
+ /**
+ * Keeps the value of the object property.
+ *
+ * {@inheritdoc}
+ */
+ public function apply($object, $property, $objectCopier)
+ {
+ // Nothing to do
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Filter/ReplaceFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/ReplaceFilter.php
new file mode 100644
index 0000000..7aca593
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/ReplaceFilter.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace DeepCopy\Filter;
+
+use DeepCopy\Reflection\ReflectionHelper;
+
+/**
+ * @final
+ */
+class ReplaceFilter implements Filter
+{
+ /**
+ * @var callable
+ */
+ protected $callback;
+
+ /**
+ * @param callable $callable Will be called to get the new value for each property to replace
+ */
+ public function __construct(callable $callable)
+ {
+ $this->callback = $callable;
+ }
+
+ /**
+ * Replaces the object property by the result of the callback called with the object property.
+ *
+ * {@inheritdoc}
+ */
+ public function apply($object, $property, $objectCopier)
+ {
+ $reflectionProperty = ReflectionHelper::getProperty($object, $property);
+ $reflectionProperty->setAccessible(true);
+
+ $value = call_user_func($this->callback, $reflectionProperty->getValue($object));
+
+ $reflectionProperty->setValue($object, $value);
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php
new file mode 100644
index 0000000..bea86b8
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace DeepCopy\Filter;
+
+use DeepCopy\Reflection\ReflectionHelper;
+
+/**
+ * @final
+ */
+class SetNullFilter implements Filter
+{
+ /**
+ * Sets the object property to null.
+ *
+ * {@inheritdoc}
+ */
+ public function apply($object, $property, $objectCopier)
+ {
+ $reflectionProperty = ReflectionHelper::getProperty($object, $property);
+
+ $reflectionProperty->setAccessible(true);
+ $reflectionProperty->setValue($object, null);
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php
new file mode 100644
index 0000000..ec8856f
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace DeepCopy\Matcher\Doctrine;
+
+use DeepCopy\Matcher\Matcher;
+use Doctrine\Common\Persistence\Proxy;
+
+/**
+ * @final
+ */
+class DoctrineProxyMatcher implements Matcher
+{
+ /**
+ * Matches a Doctrine Proxy class.
+ *
+ * {@inheritdoc}
+ */
+ public function matches($object, $property)
+ {
+ return $object instanceof Proxy;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Matcher.php b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Matcher.php
new file mode 100644
index 0000000..d67f3ca
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Matcher.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace DeepCopy\Matcher;
+
+interface Matcher
+{
+ /**
+ * @param object $object
+ * @param string $property
+ *
+ * @return boolean
+ */
+ public function matches($object, $property);
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyMatcher.php b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyMatcher.php
new file mode 100644
index 0000000..073b20c
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyMatcher.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace DeepCopy\Matcher;
+
+/**
+ * @final
+ */
+class PropertyMatcher implements Matcher
+{
+ /**
+ * @var string
+ */
+ private $class;
+
+ /**
+ * @var string
+ */
+ private $property;
+
+ /**
+ * @param string $class Class name
+ * @param string $property Property name
+ */
+ public function __construct($class, $property)
+ {
+ $this->class = $class;
+ $this->property = $property;
+ }
+
+ /**
+ * Matches a specific property of a specific class.
+ *
+ * {@inheritdoc}
+ */
+ public function matches($object, $property)
+ {
+ return ($object instanceof $this->class) && $property == $this->property;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php
new file mode 100644
index 0000000..c8ec0d2
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace DeepCopy\Matcher;
+
+/**
+ * @final
+ */
+class PropertyNameMatcher implements Matcher
+{
+ /**
+ * @var string
+ */
+ private $property;
+
+ /**
+ * @param string $property Property name
+ */
+ public function __construct($property)
+ {
+ $this->property = $property;
+ }
+
+ /**
+ * Matches a property by its name.
+ *
+ * {@inheritdoc}
+ */
+ public function matches($object, $property)
+ {
+ return $property == $this->property;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php
new file mode 100644
index 0000000..a6b0c0b
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace DeepCopy\Matcher;
+
+use DeepCopy\Reflection\ReflectionHelper;
+use ReflectionException;
+
+/**
+ * Matches a property by its type.
+ *
+ * It is recommended to use {@see DeepCopy\TypeFilter\TypeFilter} instead, as it applies on all occurrences
+ * of given type in copied context (eg. array elements), not just on object properties.
+ *
+ * @final
+ */
+class PropertyTypeMatcher implements Matcher
+{
+ /**
+ * @var string
+ */
+ private $propertyType;
+
+ /**
+ * @param string $propertyType Property type
+ */
+ public function __construct($propertyType)
+ {
+ $this->propertyType = $propertyType;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function matches($object, $property)
+ {
+ try {
+ $reflectionProperty = ReflectionHelper::getProperty($object, $property);
+ } catch (ReflectionException $exception) {
+ return false;
+ }
+
+ $reflectionProperty->setAccessible(true);
+
+ return $reflectionProperty->getValue($object) instanceof $this->propertyType;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php b/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php
new file mode 100644
index 0000000..742410c
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php
@@ -0,0 +1,78 @@
+<?php
+
+namespace DeepCopy\Reflection;
+
+use DeepCopy\Exception\PropertyException;
+use ReflectionClass;
+use ReflectionException;
+use ReflectionObject;
+use ReflectionProperty;
+
+class ReflectionHelper
+{
+ /**
+ * Retrieves all properties (including private ones), from object and all its ancestors.
+ *
+ * Standard \ReflectionClass->getProperties() does not return private properties from ancestor classes.
+ *
+ * @author muratyaman@gmail.com
+ * @see http://php.net/manual/en/reflectionclass.getproperties.php
+ *
+ * @param ReflectionClass $ref
+ *
+ * @return ReflectionProperty[]
+ */
+ public static function getProperties(ReflectionClass $ref)
+ {
+ $props = $ref->getProperties();
+ $propsArr = array();
+
+ foreach ($props as $prop) {
+ $propertyName = $prop->getName();
+ $propsArr[$propertyName] = $prop;
+ }
+
+ if ($parentClass = $ref->getParentClass()) {
+ $parentPropsArr = self::getProperties($parentClass);
+ foreach ($propsArr as $key => $property) {
+ $parentPropsArr[$key] = $property;
+ }
+
+ return $parentPropsArr;
+ }
+
+ return $propsArr;
+ }
+
+ /**
+ * Retrieves property by name from object and all its ancestors.
+ *
+ * @param object|string $object
+ * @param string $name
+ *
+ * @throws PropertyException
+ * @throws ReflectionException
+ *
+ * @return ReflectionProperty
+ */
+ public static function getProperty($object, $name)
+ {
+ $reflection = is_object($object) ? new ReflectionObject($object) : new ReflectionClass($object);
+
+ if ($reflection->hasProperty($name)) {
+ return $reflection->getProperty($name);
+ }
+
+ if ($parentClass = $reflection->getParentClass()) {
+ return self::getProperty($parentClass->getName(), $name);
+ }
+
+ throw new PropertyException(
+ sprintf(
+ 'The class "%s" doesn\'t have a property with the given name: "%s".',
+ is_object($object) ? get_class($object) : $object,
+ $name
+ )
+ );
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php
new file mode 100644
index 0000000..becd1cf
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace DeepCopy\TypeFilter\Date;
+
+use DateInterval;
+use DeepCopy\TypeFilter\TypeFilter;
+
+/**
+ * @final
+ *
+ * @deprecated Will be removed in 2.0. This filter will no longer be necessary in PHP 7.1+.
+ */
+class DateIntervalFilter implements TypeFilter
+{
+
+ /**
+ * {@inheritdoc}
+ *
+ * @param DateInterval $element
+ *
+ * @see http://news.php.net/php.bugs/205076
+ */
+ public function apply($element)
+ {
+ $copy = new DateInterval('P0D');
+
+ foreach ($element as $propertyName => $propertyValue) {
+ $copy->{$propertyName} = $propertyValue;
+ }
+
+ return $copy;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php
new file mode 100644
index 0000000..164f8b8
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace DeepCopy\TypeFilter;
+
+/**
+ * @final
+ */
+class ReplaceFilter implements TypeFilter
+{
+ /**
+ * @var callable
+ */
+ protected $callback;
+
+ /**
+ * @param callable $callable Will be called to get the new value for each element to replace
+ */
+ public function __construct(callable $callable)
+ {
+ $this->callback = $callable;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function apply($element)
+ {
+ return call_user_func($this->callback, $element);
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php
new file mode 100644
index 0000000..a5fbd7a
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace DeepCopy\TypeFilter;
+
+/**
+ * @final
+ */
+class ShallowCopyFilter implements TypeFilter
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function apply($element)
+ {
+ return clone $element;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php
new file mode 100644
index 0000000..c5644cf
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace DeepCopy\TypeFilter\Spl;
+
+/**
+ * @deprecated Use {@see SplDoublyLinkedListFilter} instead.
+ */
+class SplDoublyLinkedList extends SplDoublyLinkedListFilter
+{
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedListFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedListFilter.php
new file mode 100644
index 0000000..c33be45
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedListFilter.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace DeepCopy\TypeFilter\Spl;
+
+use Closure;
+use DeepCopy\DeepCopy;
+use DeepCopy\TypeFilter\TypeFilter;
+use SplDoublyLinkedList;
+
+/**
+ * @final
+ */
+class SplDoublyLinkedListFilter implements TypeFilter
+{
+ private $copier;
+
+ public function __construct(DeepCopy $copier)
+ {
+ $this->copier = $copier;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function apply($element)
+ {
+ $newElement = clone $element;
+
+ $copy = $this->createCopyClosure();
+
+ return $copy($newElement);
+ }
+
+ private function createCopyClosure()
+ {
+ $copier = $this->copier;
+
+ $copy = function (SplDoublyLinkedList $list) use ($copier) {
+ // Replace each element in the list with a deep copy of itself
+ for ($i = 1; $i <= $list->count(); $i++) {
+ $copy = $copier->recursiveCopy($list->shift());
+
+ $list->push($copy);
+ }
+
+ return $list;
+ };
+
+ return Closure::bind($copy, null, DeepCopy::class);
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php
new file mode 100644
index 0000000..5785a7d
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace DeepCopy\TypeFilter;
+
+interface TypeFilter
+{
+ /**
+ * Applies the filter to the object.
+ *
+ * @param mixed $element
+ */
+ public function apply($element);
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/TypeMatcher/TypeMatcher.php b/vendor/myclabs/deep-copy/src/DeepCopy/TypeMatcher/TypeMatcher.php
new file mode 100644
index 0000000..a563cb2
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/TypeMatcher/TypeMatcher.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace DeepCopy\TypeMatcher;
+
+class TypeMatcher
+{
+ /**
+ * @var string
+ */
+ private $type;
+
+ /**
+ * @param string $type
+ */
+ public function __construct($type)
+ {
+ $this->type = $type;
+ }
+
+ /**
+ * @param mixed $element
+ *
+ * @return boolean
+ */
+ public function matches($element)
+ {
+ return is_object($element) ? is_a($element, $this->type) : gettype($element) === $this->type;
+ }
+}
diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/deep_copy.php b/vendor/myclabs/deep-copy/src/DeepCopy/deep_copy.php
new file mode 100644
index 0000000..55dcc92
--- /dev/null
+++ b/vendor/myclabs/deep-copy/src/DeepCopy/deep_copy.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace DeepCopy;
+
+use function function_exists;
+
+if (false === function_exists('DeepCopy\deep_copy')) {
+ /**
+ * Deep copies the given value.
+ *
+ * @param mixed $value
+ * @param bool $useCloneMethod
+ *
+ * @return mixed
+ */
+ function deep_copy($value, $useCloneMethod = false)
+ {
+ return (new DeepCopy($useCloneMethod))->copy($value);
+ }
+}
diff --git a/vendor/nelexa/zip/.gitignore b/vendor/nelexa/zip/.gitignore
new file mode 100644
index 0000000..7ec2d22
--- /dev/null
+++ b/vendor/nelexa/zip/.gitignore
@@ -0,0 +1,5 @@
+/vendor
+*.iml
+/.idea
+/composer.lock
+/.php_cs.cache \ No newline at end of file
diff --git a/vendor/nelexa/zip/.travis.yml b/vendor/nelexa/zip/.travis.yml
new file mode 100644
index 0000000..281a057
--- /dev/null
+++ b/vendor/nelexa/zip/.travis.yml
@@ -0,0 +1,24 @@
+language: php
+php:
+ - '5.5'
+ - '5.6'
+ - '7.0'
+ - '7.1'
+ - nightly
+
+# cache vendor dirs
+cache:
+ directories:
+ - vendor
+ - $HOME/.composer/cache
+
+install:
+ - travis_retry composer self-update && composer --version
+ - travis_retry composer install --prefer-dist --no-interaction
+
+before_script:
+ - sudo apt-get install p7zip-full
+
+script:
+ - composer validate --no-check-lock
+ - vendor/bin/phpunit -v -c phpunit.xml
diff --git a/vendor/nelexa/zip/CHANGELOG.md b/vendor/nelexa/zip/CHANGELOG.md
new file mode 100644
index 0000000..db811cf
--- /dev/null
+++ b/vendor/nelexa/zip/CHANGELOG.md
@@ -0,0 +1,42 @@
+# Changelog
+
+# 3.1.2 (2017-11-17)
+- Changed the algorithm for adding paddings to zipalign.
+ Now we will use the special field ExtraField c ID 0xD935,
+ which was implemented by Google in the apksigner library.
+ Now this field corresponds to the ZIP standard for storing
+ ExtraField records, and not just filling with zero bytes,
+ as in the zipalign console utility.
+
+## 3.1.1 (2017-11-15)
+- Fix resave zip aligned archive
+
+## 3.1.0 (2017-11-14)
+- Added class `ZipModel` for all changes.
+- All manipulations with incoming and outgoing streams are in separate files: `ZipInputStream` and `ZipOutputStream`.
+- Removed class `CentralDirectory`.
+- Optimized extra fields classes.
+- Fixed issue #4 (`count()` returns 0 when files are added in directories).
+- Implemented issue #8 - support inline Content-Disposition and empty output filename.
+- Optimized and tested on a php 32-bit platform (issue #5).
+- Added output as PSR-7 Response.
+- Added methods for canceling changes.
+- Added [russian documentation](README.RU.md).
+- Updated [documentation](README.md).
+- Declared deprecated methods:
+ + rename `ZipFile::withReadPassword` to `ZipFile::setReadPassword`
+ + rename `ZipFile::withNewPassword` to `ZipFile::setPassword`
+ + rename `ZipFile::withoutPassword` to `ZipFile::disableEncryption`
+
+## 3.0.3 (2017-11-11)
+Fix bug issue #8 - Error if the file is empty.
+
+## 3.0.0 (2017-03-15)
+Merge `ZipOutputFile` with ZipFile and optimize the zip archive update.
+
+See the update instructions in README.md.
+
+## 2.2.0 (2017-03-02)
+Features:
+ - create output object `ZipOutputFile` from `ZipFile` in method `ZipFile::edit()`.
+ - create output object `ZipOutputFile` from filename in static method `ZipOutputFile::openFromFile(string $filename)`. \ No newline at end of file
diff --git a/vendor/nelexa/zip/README.RU.md b/vendor/nelexa/zip/README.RU.md
new file mode 100644
index 0000000..d110d4f
--- /dev/null
+++ b/vendor/nelexa/zip/README.RU.md
@@ -0,0 +1,821 @@
+`PhpZip`
+========
+`PhpZip` - php библиотека для продвинутой работы с ZIP-архивами.
+
+[![Build Status](https://travis-ci.org/Ne-Lexa/php-zip.svg?branch=master)](https://travis-ci.org/Ne-Lexa/php-zip)
+[![Latest Stable Version](https://poser.pugx.org/nelexa/zip/v/stable)](https://packagist.org/packages/nelexa/zip)
+[![Total Downloads](https://poser.pugx.org/nelexa/zip/downloads)](https://packagist.org/packages/nelexa/zip)
+[![Minimum PHP Version](http://img.shields.io/badge/php-%3E%3D%205.5-8892BF.svg)](https://php.net/)
+[![License](https://poser.pugx.org/nelexa/zip/license)](https://packagist.org/packages/nelexa/zip)
+
+[English Documentation](README.md)
+
+Содержание
+----------
+- [Функционал](#Features)
+- [Требования](#Requirements)
+- [Установка](#Installation)
+- [Примеры](#Examples)
+- [Глоссарий](#Glossary)
+- [Документация](#Documentation)
+ + [Обзор методов класса `\PhpZip\ZipFile`](#Documentation-Overview)
+ + [Создание/Открытие ZIP-архива](#Documentation-Open-Zip-Archive)
+ + [Чтение записей из архива](#Documentation-Open-Zip-Entries)
+ + [Перебор записей/Итератор](#Documentation-Zip-Iterate)
+ + [Получение информации о записях](#Documentation-Zip-Info)
+ + [Добавление записей в архив](#Documentation-Add-Zip-Entries)
+ + [Удаление записей из архива](#Documentation-Remove-Zip-Entries)
+ + [Работа с записями и с архивом](#Documentation-Entries)
+ + [Работа с паролями](#Documentation-Password)
+ + [zipalign - выравнивание архива для оптимизации Android пакетов (APK)](#Documentation-ZipAlign-Usage)
+ + [Отмена изменений](#Documentation-Unchanged)
+ + [Сохранение файла или вывод в браузер](#Documentation-Save-Or-Output-Entries)
+ + [Закрытие архива](#Documentation-Close-Zip-Archive)
+- [Запуск тестов](#Running-Tests)
+- [История изменений](#Changelog)
+- [Обновление версий](#Upgrade)
+ + [Обновление с версии 2 до версии 3.0](#Upgrade-v2-to-v3)
+
+### <a name="Features"></a> Функционал
+- Открытие и разархивирование ZIP-архивов.
+- Создание ZIP-архивов.
+- Модификация ZIP-архивов.
+- Чистый php (не требуется расширение `php-zip` и класс `\ZipArchive`).
+- Поддерживается сохранение архива в файл, вывод архива в браузер или вывод в виде строки, без сохранения в файл.
+- Поддерживаются комментарии архива и комментарии отдельных записей.
+- Получение подробной информации о каждой записи в архиве.
+- Поддерживаются только следующие методы сжатия:
+ + Без сжатия (Stored).
+ + Deflate сжатие.
+ + BZIP2 сжатие при наличии расширения `php-bz2`.
+- Поддержка `ZIP64` (размер файла более 4 GB или количество записей в архиве более 65535).
+- Встроенная поддержка выравнивания архива для оптимизации Android пакетов (APK) [`zipalign`](https://developer.android.com/studio/command-line/zipalign.html).
+- Работа с паролями для PHP 5.5
+ > **Внимание!**
+ >
+ > Для 32-bit систем, в данный момент не поддерживается метод шифрование `Traditional PKWARE Encryption (ZipCrypto)`.
+ > Используйте метод шифрования `WinZIP AES Encryption`, когда это возможно.
+ + Установка пароля для чтения архива глобально или для некоторых записей.
+ + Изменение пароля архива, в том числе и для отдельных записей.
+ + Удаление пароля архива глобально или для отдельных записей.
+ + Установка пароля и/или метода шифрования, как для всех, так и для отдельных записей в архиве.
+ + Установка разных паролей и методов шифрования для разных записей.
+ + Удаление пароля для всех или для некоторых записей.
+ + Поддержка методов шифрования `Traditional PKWARE Encryption (ZipCrypto)` и `WinZIP AES Encryption (128, 192 или 256 bit)`.
+ + Установка метода шифрования для всех или для отдельных записей в архиве.
+
+### <a name="Requirements"></a> Требования
+- `PHP` >= 5.5 (предпочтительно 64-bit).
+- Опционально php-расширение `bzip2` для поддержки BZIP2 компрессии.
+- Опционально php-расширение `openssl` или `mcrypt` для `WinZip Aes Encryption` шифрования.
+
+### <a name="Installation"></a> Установка
+`composer require nelexa/zip`
+
+Последняя стабильная версия: [![Latest Stable Version](https://poser.pugx.org/nelexa/zip/v/stable)](https://packagist.org/packages/nelexa/zip)
+
+### <a name="Examples"></a> Примеры
+```php
+// создание нового архива
+$zipFile = new \PhpZip\ZipFile();
+$zipFile
+ ->addFromString("zip/entry/filename", "Is file content") // добавить запись из строки
+ ->addFile("/path/to/file", "data/tofile") // добавить запись из файла
+ ->addDir(__DIR__, "to/path/") // добавить файлы из директории
+ ->saveAsFile($outputFilename) // сохранить архив в файл
+ ->close(); // закрыть архив
+
+// открытие архива, извлечение файлов, удаление файлов, добавление файлов, установка пароля и вывод архива в браузер.
+$zipFile
+ ->openFile($outputFilename) // открыть архив из файла
+ ->extractTo($outputDirExtract) // извлечь файлы в заданную директорию
+ ->deleteFromRegex('~^\.~') // удалить все скрытые (Unix) файлы
+ ->addFromString('dir/file.txt', 'Test file') // добавить новую запись из строки
+ ->setPassword('password') // установить пароль на все записи
+ ->outputAsAttachment('library.jar'); // вывести в браузер без сохранения в файл
+```
+Другие примеры можно посмотреть в папке `tests/`.
+
+### <a name="Glossary"></a> Глоссарий
+**Запись в ZIP-архиве (Zip Entry)** - файл или папка в ZIP-архиве. У каждой записи в архиве есть определённые свойства, например: имя файла, метод сжатия, метод шифрования, размер файла до сжатия, размер файла после сжатия, CRC32 и другие.
+
+### <a name="Documentation"></a> Документация
+#### <a name="Documentation-Overview"></a> Обзор методов класса `\PhpZip\ZipFile`
+- [ZipFile::__construct](#Documentation-ZipFile-__construct) - инициализацирует ZIP-архив.
+- [ZipFile::addAll](#Documentation-ZipFile-addAll) - добавляет все записи из массива.
+- [ZipFile::addDir](#Documentation-ZipFile-addDir) - добавляет файлы из директории по указанному пути без вложенных директорий.
+- [ZipFile::addDirRecursive](#Documentation-ZipFile-addDirRecursive) - добавляет файлы из директории по указанному пути c вложенными директориями.
+- [ZipFile::addEmptyDir](#Documentation-ZipFile-addEmptyDir) - добавляет в ZIP-архив новую директорию.
+- [ZipFile::addFile](#Documentation-ZipFile-addFile) - добавляет в ZIP-архив файл по указанному пути.
+- [ZipFile::addFilesFromIterator](#Documentation-ZipFile-addFilesFromIterator) - добавляет файлы из итератора директорий.
+- [ZipFile::addFilesFromGlob](#Documentation-ZipFile-addFilesFromGlob) - добавляет файлы из директории в соответствии с glob шаблоном без вложенных директорий.
+- [ZipFile::addFilesFromGlobRecursive](#Documentation-ZipFile-addFilesFromGlobRecursive) - добавляет файлы из директории в соответствии с glob шаблоном c вложенными директориями.
+- [ZipFile::addFilesFromRegex](#Documentation-ZipFile-addFilesFromRegex) - добавляет файлы из директории в соответствии с регулярным выражением без вложенных директорий.
+- [ZipFile::addFilesFromRegexRecursive](#Documentation-ZipFile-addFilesFromRegexRecursive) - добавляет файлы из директории в соответствии с регулярным выражением c вложенными директориями.
+- [ZipFile::addFromStream](#Documentation-ZipFile-addFromStream) - добавляет в ZIP-архив запись из потока.
+- [ZipFile::addFromString](#Documentation-ZipFile-addFromString) - добавляет файл в ZIP-архив, используя его содержимое в виде строки.
+- [ZipFile::close](#Documentation-ZipFile-close) - закрывает ZIP-архив.
+- [ZipFile::count](#Documentation-ZipFile-count) - возвращает количество записей в архиве.
+- [ZipFile::deleteFromName](#Documentation-ZipFile-deleteFromName) - удаляет запись по имени.
+- [ZipFile::deleteFromGlob](#Documentation-ZipFile-deleteFromGlob) - удаляет записи в соответствии с glob шаблоном.
+- [ZipFile::deleteFromRegex](#Documentation-ZipFile-deleteFromRegex) - удаляет записи в соответствии с регулярным выражением.
+- [ZipFile::deleteAll](#Documentation-ZipFile-deleteAll) - удаляет все записи в ZIP-архиве.
+- [ZipFile::disableEncryption](#Documentation-ZipFile-disableEncryption) - отключает шифрования всех записей, находящихся в архиве.
+- [ZipFile::disableEncryptionEntry](#Documentation-ZipFile-disableEncryptionEntry) - отключает шифрование записи по её имени.
+- [ZipFile::extractTo](#Documentation-ZipFile-extractTo) - извлекает содержимое архива в заданную директорию.
+- [ZipFile::getAllInfo](#Documentation-ZipFile-getAllInfo) - возвращает подробную информацию обо всех записях в архиве.
+- [ZipFile::getArchiveComment](#Documentation-ZipFile-getArchiveComment) - возвращает комментарий ZIP-архива.
+- [ZipFile::getEntryComment](#Documentation-ZipFile-getEntryComment) - возвращает комментарий к записи, используя её имя.
+- [ZipFile::getEntryContent](#Documentation-ZipFile-getEntryContent) - возвращает содержимое записи.
+- [ZipFile::getEntryInfo](#Documentation-ZipFile-getEntryInfo) - возвращает подробную информацию о записи в архиве.
+- [ZipFile::getListFiles](#Documentation-ZipFile-getListFiles) - возвращает список файлов архива.
+- [ZipFile::hasEntry](#Documentation-ZipFile-hasEntry) - проверяет, присутствует ли запись в архиве.
+- [ZipFile::isDirectory](#Documentation-ZipFile-isDirectory) - проверяет, является ли запись в архиве директорией.
+- [ZipFile::matcher](#Documentation-ZipFile-matcher) - выборка записей в архиве для проведения операций над выбранными записями.
+- [ZipFile::openFile](#Documentation-ZipFile-openFile) - открывает ZIP-архив из файла.
+- [ZipFile::openFromString](#Documentation-ZipFile-openFromString) - открывает ZIP-архив из строки.
+- [ZipFile::openFromStream](#Documentation-ZipFile-openFromStream) - открывает ZIP-архив из потока.
+- [ZipFile::outputAsAttachment](#Documentation-ZipFile-outputAsAttachment) - выводит ZIP-архив в браузер.
+- [ZipFile::outputAsResponse](#Documentation-ZipFile-outputAsResponse) - выводит ZIP-архив, как Response PSR-7.
+- [ZipFile::outputAsString](#Documentation-ZipFile-outputAsString) - выводит ZIP-архив в виде строки.
+- [ZipFile::rename](#Documentation-ZipFile-rename) - переименовывает запись по имени.
+- [ZipFile::rewrite](#Documentation-ZipFile-rewrite) - сохраняет изменения и заново открывает изменившийся архив.
+- [ZipFile::saveAsFile](#Documentation-ZipFile-saveAsFile) - сохраняет архив в файл.
+- [ZipFile::saveAsStream](#Documentation-ZipFile-saveAsStream) - записывает архив в поток.
+- [ZipFile::setArchiveComment](#Documentation-ZipFile-setArchiveComment) - устанавливает комментарий к ZIP-архиву.
+- [ZipFile::setCompressionLevel](#Documentation-ZipFile-setCompressionLevel) - устанавливает уровень сжатия для всех файлов, находящихся в архиве.
+- [ZipFile::setCompressionLevelEntry](#Documentation-ZipFile-setCompressionLevelEntry) - устанавливает уровень сжатия для определённой записи в архиве.
+- [ZipFile::setCompressionMethodEntry](#Documentation-ZipFile-setCompressionMethodEntry) - устанавливает метод сжатия для определённой записи в архиве.
+- [ZipFile::setEntryComment](#Documentation-ZipFile-setEntryComment) - устанавливает комментарий к записи, используя её имя.
+- [ZipFile::setReadPassword](#Documentation-ZipFile-setReadPassword) - устанавливает пароль на чтение открытого запароленного архива для всех зашифрованных записей.
+- [ZipFile::setReadPasswordEntry](#Documentation-ZipFile-setReadPasswordEntry) - устанавливает пароль на чтение конкретной зашифрованной записи открытого запароленного архива.
+- ~~ZipFile::withNewPassword~~ - устаревший метод (**deprecated**) используйте метод [ZipFile::setPassword](#Documentation-ZipFile-setPassword).
+- [ZipFile::setPassword](#Documentation-ZipFile-setPassword) - устанавливает новый пароль для всех файлов, находящихся в архиве.
+- [ZipFile::setPasswordEntry](#Documentation-ZipFile-setPasswordEntry) - устанавливает новый пароль для конкретного файла.
+- [ZipFile::setZipAlign](#Documentation-ZipFile-setZipAlign) - устанавливает выравнивание архива для оптимизации APK файлов (Android packages).
+- [ZipFile::unchangeAll](#Documentation-ZipFile-unchangeAll) - отменяет все изменения, сделанные в архиве.
+- [ZipFile::unchangeArchiveComment](#Documentation-ZipFile-unchangeArchiveComment) - отменяет изменения в комментарии к архиву.
+- [ZipFile::unchangeEntry](#Documentation-ZipFile-unchangeEntry) - отменяет изменения для конкретной записи архива.
+- ~~ZipFile::withoutPassword~~ - устаревший метод (**deprecated**) используйте метод [ZipFile::disableEncryption](#Documentation-ZipFile-disableEncryption).
+- ~~ZipFile::withReadPassword~~ - устаревший метод (**deprecated**) используйте метод [ZipFile::setReadPassword](#Documentation-ZipFile-setReadPassword).
+
+#### <a name="Documentation-Open-Zip-Archive"></a> Создание/Открытие ZIP-архива
+<a name="Documentation-ZipFile-__construct"></a>**ZipFile::__construct** - Инициализацирует ZIP-архив.
+```php
+$zipFile = new \PhpZip\ZipFile();
+```
+<a name="Documentation-ZipFile-openFile"></a> **ZipFile::openFile** - открывает ZIP-архив из файла.
+```php
+$zipFile = new \PhpZip\ZipFile();
+$zipFile->openFile('file.zip');
+```
+<a name="Documentation-ZipFile-openFromString"></a> **ZipFile::openFromString** - открывает ZIP-архив из строки.
+```php
+$zipFile = new \PhpZip\ZipFile();
+$zipFile->openFromString($stringContents);
+```
+<a name="Documentation-ZipFile-openFromStream"></a> **ZipFile::openFromStream** - открывает ZIP-архив из потока.
+```php
+$stream = fopen('file.zip', 'rb');
+
+$zipFile = new \PhpZip\ZipFile();
+$zipFile->openFromStream($stream);
+```
+#### <a name="Documentation-Open-Zip-Entries"></a> Чтение записей из архива
+<a name="Documentation-ZipFile-count"></a> **ZipFile::count** - возвращает количество записей в архиве.
+```php
+$count = count($zipFile);
+// или
+$count = $zipFile->count();
+```
+<a name="Documentation-ZipFile-getListFiles"></a> **ZipFile::getListFiles** - возвращает список файлов архива.
+```php
+$listFiles = $zipFile->getListFiles();
+
+// Пример содержимого массива:
+// array (
+// 0 => 'info.txt',
+// 1 => 'path/to/file.jpg',
+// 2 => 'another path/',
+// )
+```
+<a name="Documentation-ZipFile-getEntryContent"></a> **ZipFile::getEntryContent** - возвращает содержимое записи.
+```php
+// $entryName = 'path/to/example-entry-name.txt';
+
+$contents = $zipFile[$entryName];
+// или
+$contents = $zipFile->getEntryContents($entryName);
+```
+<a name="Documentation-ZipFile-hasEntry"></a> **ZipFile::hasEntry** - проверяет, присутствует ли запись в архиве.
+```php
+// $entryName = 'path/to/example-entry-name.txt';
+
+$hasEntry = isset($zipFile[$entryName]);
+// или
+$hasEntry = $zipFile->hasEntry($entryName);
+```
+<a name="Documentation-ZipFile-isDirectory"></a> **ZipFile::isDirectory** - проверяет, является ли запись в архиве директорией.
+```php
+// $entryName = 'path/to/';
+
+$isDirectory = $zipFile->isDirectory($entryName);
+```
+<a name="Documentation-ZipFile-extractTo"></a> **ZipFile::extractTo** - извлекает содержимое архива в заданную директорию.
+Директория должна существовать.
+```php
+$zipFile->extractTo($directory);
+```
+Можно извлечь только некоторые записи в заданную директорию.
+Директория должна существовать.
+```php
+$extractOnlyFiles = [
+ "filename1",
+ "filename2",
+ "dir/dir/dir/"
+];
+$zipFile->extractTo($directory, $extractOnlyFiles);
+```
+#### <a name="Documentation-Zip-Iterate"></a> Перебор записей/Итератор
+`ZipFile` является итератором.
+Можно перебрать все записи, через цикл `foreach`.
+```php
+foreach($zipFile as $entryName => $contents){
+ echo "Файл: $entryName" . PHP_EOL;
+ echo "Содержимое: $contents" . PHP_EOL;
+ echo "-----------------------------" . PHP_EOL;
+}
+```
+Можно использовать паттерн `Iterator`.
+```php
+$iterator = new \ArrayIterator($zipFile);
+while ($iterator->valid())
+{
+ $entryName = $iterator->key();
+ $contents = $iterator->current();
+
+ echo "Файл: $entryName" . PHP_EOL;
+ echo "Содержимое: $contents" . PHP_EOL;
+ echo "-----------------------------" . PHP_EOL;
+
+ $iterator->next();
+}
+```
+#### <a name="Documentation-Zip-Info"></a> Получение информации о записях
+<a name="Documentation-ZipFile-getArchiveComment"></a> **ZipFile::getArchiveComment** - возвращает комментарий ZIP-архива.
+```php
+$commentArchive = $zipFile->getArchiveComment();
+```
+<a name="Documentation-ZipFile-getEntryComment"></a> **ZipFile::getEntryComment** - возвращает комментарий к записи, используя её имя.
+```php
+$commentEntry = $zipFile->getEntryComment($entryName);
+```
+<a name="Documentation-ZipFile-getEntryInfo"></a> **ZipFile::getEntryInfo** - возвращает подробную информацию о записи в архиве.
+```php
+$zipInfo = $zipFile->getEntryInfo('file.txt');
+
+$arrayInfo = $zipInfo->toArray();
+// Пример содержимого массива:
+// array (
+// 'name' => 'file.gif',
+// 'folder' => false,
+// 'size' => '43',
+// 'compressed_size' => '43',
+// 'modified' => 1510489440,
+// 'created' => null,
+// 'accessed' => null,
+// 'attributes' => '-rw-r--r--',
+// 'encrypted' => false,
+// 'encryption_method' => 0,
+// 'comment' => '',
+// 'crc' => 782934147,
+// 'method_name' => 'No compression',
+// 'compression_method' => 0,
+// 'platform' => 'UNIX',
+// 'version' => 10,
+// )
+
+print_r($zipInfo);
+// Вывод:
+//PhpZip\Model\ZipInfo Object
+//(
+// [name:PhpZip\Model\ZipInfo:private] => file.gif
+// [folder:PhpZip\Model\ZipInfo:private] =>
+// [size:PhpZip\Model\ZipInfo:private] => 43
+// [compressedSize:PhpZip\Model\ZipInfo:private] => 43
+// [mtime:PhpZip\Model\ZipInfo:private] => 1510489324
+// [ctime:PhpZip\Model\ZipInfo:private] =>
+// [atime:PhpZip\Model\ZipInfo:private] =>
+// [encrypted:PhpZip\Model\ZipInfo:private] =>
+// [comment:PhpZip\Model\ZipInfo:private] =>
+// [crc:PhpZip\Model\ZipInfo:private] => 782934147
+// [methodName:PhpZip\Model\ZipInfo:private] => No compression
+// [compressionMethod:PhpZip\Model\ZipInfo:private] => 0
+// [platform:PhpZip\Model\ZipInfo:private] => UNIX
+// [version:PhpZip\Model\ZipInfo:private] => 10
+// [attributes:PhpZip\Model\ZipInfo:private] => -rw-r--r--
+// [encryptionMethod:PhpZip\Model\ZipInfo:private] => 0
+// [compressionLevel:PhpZip\Model\ZipInfo:private] => -1
+//)
+
+echo $zipInfo;
+// Вывод:
+// PhpZip\Model\ZipInfo {Name="file.gif", Size="43 bytes", Compressed size="43 bytes", Modified time="2017-11-12T15:22:04+03:00", Crc=0x2eaaa083, Method name="No compression", Attributes="-rw-r--r--", Platform="UNIX", Version=10}
+```
+<a name="Documentation-ZipFile-getAllInfo"></a> **ZipFile::getAllInfo** - возвращает подробную информацию обо всех записях в архиве.
+```php
+$zipAllInfo = $zipFile->getAllInfo();
+
+print_r($zipAllInfo);
+//Array
+//(
+// [file.txt] => PhpZip\Model\ZipInfo Object
+// (
+// ...
+// )
+//
+// [file2.txt] => PhpZip\Model\ZipInfo Object
+// (
+// ...
+// )
+//
+// ...
+//)
+```
+#### <a name="Documentation-Add-Zip-Entries"></a> Добавление записей в архив
+
+Все методы добавления записей в ZIP-архив позволяют указать метод сжатия содержимого.
+
+Доступны следующие методы сжатия:
+- `\PhpZip\ZipFile::METHOD_STORED` - без сжатия
+- `\PhpZip\ZipFile::METHOD_DEFLATED` - Deflate сжатие
+- `\PhpZip\ZipFile::METHOD_BZIP2` - Bzip2 сжатие при наличии расширения `ext-bz2`
+
+<a name="Documentation-ZipFile-addFile"></a> **ZipFile::addFile** - добавляет в ZIP-архив файл по указанному пути из файловой системы.
+```php
+// $file = '...../file.ext';
+$zipFile->addFile($file);
+
+// можно указать имя записи в архиве (если null, то используется последний компонент из имени файла)
+$zipFile->addFile($file, $entryName);
+// или
+$zipFile[$entryName] = new \SplFileInfo($file);
+
+// можно указать метод сжатия
+$zipFile->addFile($file, $entryName, ZipFile::METHOD_STORED); // Без сжатия
+$zipFile->addFile($file, $entryName, ZipFile::METHOD_DEFLATED); // Deflate сжатие
+$zipFile->addFile($file, $entryName, ZipFile::METHOD_BZIP2); // BZIP2 сжатие
+```
+<a name="Documentation-ZipFile-addFromString"></a> **ZipFile::addFromString** - добавляет файл в ZIP-архив, используя его содержимое в виде строки.
+```php
+$zipFile[$entryName] = $contents;
+// или
+$zipFile->addFromString($entryName, $contents);
+
+// можно указать метод сжатия
+$zipFile->addFromString($entryName, $contents, ZipFile::METHOD_STORED); // Без сжатия
+$zipFile->addFromString($entryName, $contents, ZipFile::METHOD_DEFLATED); // Deflate сжатие
+$zipFile->addFromString($entryName, $contents, ZipFile::METHOD_BZIP2); // BZIP2 сжатие
+```
+<a name="Documentation-ZipFile-addFromStream"></a> **ZipFile::addFromStream** - добавляет в ZIP-архив запись из потока.
+```php
+// $stream = fopen(..., 'rb');
+
+$zipFile->addFromStream($stream, $entryName);
+
+// можно указать метод сжатия
+$zipFile->addFromStream($stream, $entryName, ZipFile::METHOD_STORED); // Без сжатия
+$zipFile->addFromStream($stream, $entryName, ZipFile::METHOD_DEFLATED); // Deflate сжатие
+$zipFile->addFromStream($stream, $entryName, ZipFile::METHOD_BZIP2); // BZIP2 сжатие
+```
+<a name="Documentation-ZipFile-addEmptyDir"></a> **ZipFile::addEmptyDir** - добавляет в ZIP-архив новую (пустую) директорию.
+```php
+// $path = "path/to/";
+
+$zipFile->addEmptyDir($path);
+// или
+$zipFile[$path] = null;
+```
+<a name="Documentation-ZipFile-addAll"></a> **ZipFile::addAll** - добавляет все записи из массива.
+```php
+$entries = [
+ 'file.txt' => 'file contents', // запись из строки данных
+ 'empty dir/' => null, // пустой каталог
+ 'path/to/file.jpg' => fopen('..../filename', 'r'), // запись из потока
+ 'path/to/file.dat' => new \SplFileInfo('..../filename'), // запись из файла
+];
+
+$zipFile->addAll($entries);
+```
+<a name="Documentation-ZipFile-addDir"></a> **ZipFile::addDir** - добавляет файлы из директории по указанному пути без вложенных директорий.
+```php
+$zipFile->addDir($dirName);
+
+// можно указать путь в архиве в который необходимо поместить записи
+$localPath = "to/path/";
+$zipFile->addDir($dirName, $localPath);
+
+// можно указать метод сжатия
+$zipFile->addDir($dirName, $localPath, ZipFile::METHOD_STORED); // Без сжатия
+$zipFile->addDir($dirName, $localPath, ZipFile::METHOD_DEFLATED); // Deflate сжатие
+$zipFile->addDir($dirName, $localPath, ZipFile::METHOD_BZIP2); // BZIP2 сжатие
+```
+<a name="Documentation-ZipFile-addDirRecursive"></a> **ZipFile::addDirRecursive** - добавляет файлы из директории по указанному пути c вложенными директориями.
+```php
+$zipFile->addDirRecursive($dirName);
+
+// можно указать путь в архиве в который необходимо поместить записи
+$localPath = "to/path/";
+$zipFile->addDirRecursive($dirName, $localPath);
+
+// можно указать метод сжатия
+$zipFile->addDirRecursive($dirName, $localPath, ZipFile::METHOD_STORED); // Без сжатия
+$zipFile->addDirRecursive($dirName, $localPath, ZipFile::METHOD_DEFLATED); // Deflate сжатие
+$zipFile->addDirRecursive($dirName, $localPath, ZipFile::METHOD_BZIP2); // BZIP2 сжатие
+```
+<a name="Documentation-ZipFile-addFilesFromIterator"></a> **ZipFile::addFilesFromIterator** - добавляет файлы из итератора директорий.
+```php
+// $directoryIterator = new \DirectoryIterator($dir); // без вложенных директорий
+// $directoryIterator = new \RecursiveDirectoryIterator($dir); // с вложенными директориями
+
+$zipFile->addFilesFromIterator($directoryIterator);
+
+// можно указать путь в архиве в который необходимо поместить записи
+$localPath = "to/path/";
+$zipFile->addFilesFromIterator($directoryIterator, $localPath);
+// или
+$zipFile[$localPath] = $directoryIterator;
+
+// можно указать метод сжатия
+$zipFile->addFilesFromIterator($directoryIterator, $localPath, ZipFile::METHOD_STORED); // Без сжатия
+$zipFile->addFilesFromIterator($directoryIterator, $localPath, ZipFile::METHOD_DEFLATED); // Deflate сжатие
+$zipFile->addFilesFromIterator($directoryIterator, $localPath, ZipFile::METHOD_BZIP2); // BZIP2 сжатие
+```
+Пример добавления файлов из директории в архив с игнорированием некоторых файлов при помощи итератора директорий.
+```php
+$ignoreFiles = [
+ "file_ignore.txt",
+ "dir_ignore/sub dir ignore/"
+];
+
+// $directoryIterator = new \DirectoryIterator($dir); // без вложенных директорий
+// $directoryIterator = new \RecursiveDirectoryIterator($dir); // с вложенными директориями
+
+// используйте \PhpZip\Util\Iterator\IgnoreFilesFilterIterator для не рекурсивного поиска
+$ignoreIterator = new \PhpZip\Util\Iterator\IgnoreFilesRecursiveFilterIterator(
+ $directoryIterator,
+ $ignoreFiles
+);
+
+$zipFile->addFilesFromIterator($ignoreIterator);
+```
+<a name="Documentation-ZipFile-addFilesFromGlob"></a> **ZipFile::addFilesFromGlob** - добавляет файлы из директории в соответствии с [glob шаблоном](https://en.wikipedia.org/wiki/Glob_(programming)) без вложенных директорий.
+```php
+$globPattern = '**.{jpg,jpeg,png,gif}'; // пример glob шаблона -> добавить все .jpg, .jpeg, .png и .gif файлы
+
+$zipFile->addFilesFromGlob($dir, $globPattern);
+
+// можно указать путь в архиве в который необходимо поместить записи
+$localPath = "to/path/";
+$zipFile->addFilesFromGlob($dir, $globPattern, $localPath);
+
+// можно указать метод сжатия
+$zipFile->addFilesFromGlob($dir, $globPattern, $localPath, ZipFile::METHOD_STORED); // Без сжатия
+$zipFile->addFilesFromGlob($dir, $globPattern, $localPath, ZipFile::METHOD_DEFLATED); // Deflate сжатие
+$zipFile->addFilesFromGlob($dir, $globPattern, $localPath, ZipFile::METHOD_BZIP2); // BZIP2 сжатие
+```
+<a name="Documentation-ZipFile-addFilesFromGlobRecursive"></a> **ZipFile::addFilesFromGlobRecursive** - добавляет файлы из директории в соответствии с [glob шаблоном](https://en.wikipedia.org/wiki/Glob_(programming)) c вложенными директориями.
+```php
+$globPattern = '**.{jpg,jpeg,png,gif}'; // пример glob шаблона -> добавить все .jpg, .jpeg, .png и .gif файлы
+
+$zipFile->addFilesFromGlobRecursive($dir, $globPattern);
+
+// можно указать путь в архиве в который необходимо поместить записи
+$localPath = "to/path/";
+$zipFile->addFilesFromGlobRecursive($dir, $globPattern, $localPath);
+
+// можно указать метод сжатия
+$zipFile->addFilesFromGlobRecursive($dir, $globPattern, $localPath, ZipFile::METHOD_STORED); // Без сжатия
+$zipFile->addFilesFromGlobRecursive($dir, $globPattern, $localPath, ZipFile::METHOD_DEFLATED); // Deflate сжатие
+$zipFile->addFilesFromGlobRecursive($dir, $globPattern, $localPath, ZipFile::METHOD_BZIP2); // BZIP2 сжатие
+```
+<a name="Documentation-ZipFile-addFilesFromRegex"></a> **ZipFile::addFilesFromRegex** - добавляет файлы из директории в соответствии с [регулярным выражением](https://en.wikipedia.org/wiki/Regular_expression) без вложенных директорий.
+```php
+$regexPattern = '/\.(jpe?g|png|gif)$/si'; // пример регулярного выражения -> добавить все .jpg, .jpeg, .png и .gif файлы
+
+$zipFile->addFilesFromRegex($dir, $regexPattern);
+
+// можно указать путь в архиве в который необходимо поместить записи
+$localPath = "to/path/";
+$zipFile->addFilesFromRegex($dir, $regexPattern, $localPath);
+
+// можно указать метод сжатия
+$zipFile->addFilesFromRegex($dir, $regexPattern, $localPath, ZipFile::METHOD_STORED); // Без сжатия
+$zipFile->addFilesFromRegex($dir, $regexPattern, $localPath, ZipFile::METHOD_DEFLATED); // Deflate сжатие
+$zipFile->addFilesFromRegex($dir, $regexPattern, $localPath, ZipFile::METHOD_BZIP2); // BZIP2 сжатие
+```
+<a name="Documentation-ZipFile-addFilesFromRegexRecursive"></a> **ZipFile::addFilesFromRegexRecursive** - добавляет файлы из директории в соответствии с [регулярным выражением](https://en.wikipedia.org/wiki/Regular_expression) с вложенными директориями.
+```php
+$regexPattern = '/\.(jpe?g|png|gif)$/si'; // пример регулярного выражения -> добавить все .jpg, .jpeg, .png и .gif файлы
+
+$zipFile->addFilesFromRegexRecursive($dir, $regexPattern);
+
+// можно указать путь в архиве в который необходимо поместить записи
+$localPath = "to/path/";
+$zipFile->addFilesFromRegexRecursive($dir, $regexPattern, $localPath);
+
+// можно указать метод сжатия
+$zipFile->addFilesFromRegexRecursive($dir, $regexPattern, $localPath, ZipFile::METHOD_STORED); // Без сжатия
+$zipFile->addFilesFromRegexRecursive($dir, $regexPattern, $localPath, ZipFile::METHOD_DEFLATED); // Deflate сжатие
+$zipFile->addFilesFromRegexRecursive($dir, $regexPattern, $localPath, ZipFile::METHOD_BZIP2); // BZIP2 сжатие
+```
+#### <a name="Documentation-Remove-Zip-Entries"></a> Удаление записей из архива
+<a name="Documentation-ZipFile-deleteFromName"></a> **ZipFile::deleteFromName** - удаляет запись по имени.
+```php
+$zipFile->deleteFromName($entryName);
+```
+<a name="Documentation-ZipFile-deleteFromGlob"></a> **ZipFile::deleteFromGlob** - удаляет записи в соответствии с [glob шаблоном](https://en.wikipedia.org/wiki/Glob_(programming)).
+```php
+$globPattern = '**.{jpg,jpeg,png,gif}'; // пример glob шаблона -> удалить все .jpg, .jpeg, .png и .gif файлы
+
+$zipFile->deleteFromGlob($globPattern);
+```
+<a name="Documentation-ZipFile-deleteFromRegex"></a> **ZipFile::deleteFromRegex** - удаляет записи в соответствии с [регулярным выражением](https://en.wikipedia.org/wiki/Regular_expression).
+```php
+$regexPattern = '/\.(jpe?g|png|gif)$/si'; // пример регулярному выражения -> удалить все .jpg, .jpeg, .png и .gif файлы
+
+$zipFile->deleteFromRegex($regexPattern);
+```
+<a name="Documentation-ZipFile-deleteAll"></a> **ZipFile::deleteAll** - удаляет все записи в ZIP-архиве.
+```php
+$zipFile->deleteAll();
+```
+#### <a name="Documentation-Entries"></a> Работа с записями и с архивом
+<a name="Documentation-ZipFile-rename"></a> **ZipFile::rename** - переименовывает запись по имени.
+```php
+$zipFile->rename($oldName, $newName);
+```
+<a name="Documentation-ZipFile-setCompressionLevel"></a> **ZipFile::setCompressionLevel** - устанавливает уровень сжатия для всех файлов, находящихся в архиве.
+
+> _Обратите внимание, что действие данного метода не распространяется на записи, добавленные после выполнения этого метода._
+
+По умолчанию используется уровень сжатия -1 (`\PhpZip\ZipFile::LEVEL_DEFAULT_COMPRESSION`) или уровень сжатия, определённый в архиве для Deflate сжатия.
+
+Поддерживаются значения -1 (`\PhpZip\ZipFile::LEVEL_DEFAULT_COMPRESSION`) и диапазон от 1 (`\PhpZip\ZipFile::LEVEL_BEST_SPEED`) до 9 (`\PhpZip\ZipFile::LEVEL_BEST_COMPRESSION`). Чем выше число, тем лучше и дольше сжатие.
+```php
+$zipFile->setCompressionLevel(\PhpZip\ZipFile::LEVEL_BEST_COMPRESSION);
+```
+<a name="Documentation-ZipFile-setCompressionLevelEntry"></a> **ZipFile::setCompressionLevelEntry** - устанавливает уровень сжатия для определённой записи в архиве.
+
+Поддерживаются значения -1 (`\PhpZip\ZipFile::LEVEL_DEFAULT_COMPRESSION`) и диапазон от 1 (`\PhpZip\ZipFile::LEVEL_BEST_SPEED`) до 9 (`\PhpZip\ZipFile::LEVEL_BEST_COMPRESSION`). Чем выше число, тем лучше и дольше сжатие.
+```php
+$zipFile->setCompressionLevelEntry($entryName, \PhpZip\ZipFile::LEVEL_BEST_COMPRESSION);
+```
+<a name="Documentation-ZipFile-setCompressionMethodEntry"></a> **ZipFile::setCompressionMethodEntry** - устанавливает метод сжатия для определённой записи в архиве.
+
+Доступны следующие методы сжатия:
+- `\PhpZip\ZipFile::METHOD_STORED` - без сжатия
+- `\PhpZip\ZipFile::METHOD_DEFLATED` - Deflate сжатие
+- `\PhpZip\ZipFile::METHOD_BZIP2` - Bzip2 сжатие при наличии расширения `ext-bz2`
+```php
+$zipFile->setCompressionMethodEntry($entryName, ZipFile::METHOD_DEFLATED);
+```
+<a name="Documentation-ZipFile-setArchiveComment"></a> **ZipFile::setArchiveComment** - устанавливает комментарий к ZIP-архиву.
+```php
+$zipFile->setArchiveComment($commentArchive);
+```
+<a name="Documentation-ZipFile-setEntryComment"></a> **ZipFile::setEntryComment** - устанавливает комментарий к записи, используя её имя.
+```php
+$zipFile->setEntryComment($entryName, $comment);
+```
+<a name="Documentation-ZipFile-matcher"></a> **ZipFile::matcher** - выборка записей в архиве для проведения операций над выбранными записями.
+```php
+$matcher = $zipFile->matcher();
+```
+Выбор файлов из архива по одному:
+```php
+$matcher
+ ->add('entry name')
+ ->add('another entry');
+```
+Выбор нескольких файлов в архиве:
+```php
+$matcher->add([
+ 'entry name',
+ 'another entry name',
+ 'path/'
+]);
+```
+Выбор файлов по регулярному выражению:
+```php
+$matcher->match('~\.jpe?g$~i');
+```
+Выбор всех файлов в архиве:
+```php
+$matcher->all();
+```
+count() - получает количество выбранных записей:
+```php
+$count = count($matcher);
+// или
+$count = $matcher->count();
+```
+getMatches() - получает список выбранных записей:
+```php
+$entries = $matcher->getMatches();
+// пример содержимого: ['entry name', 'another entry name'];
+```
+invoke() - выполняет пользовательскую функцию над выбранными записями:
+```php
+// пример
+$matcher->invoke(function($entryName) use($zipFile) {
+ $newName = preg_replace('~\.(jpe?g)$~i', '.no_optimize.$1', $entryName);
+ $zipFile->rename($entryName, $newName);
+});
+```
+Функции для работы над выбранными записями:
+```php
+$matcher->delete(); // удалет выбранные записи из ZIP-архива
+$matcher->setPassword($password); // устанавливает новый пароль на выбранные записи
+$matcher->setPassword($password, $encryptionMethod); // устанавливает новый пароль и метод шифрования на выбранные записи
+$matcher->setEncryptionMethod($encryptionMethod); // устанавливает метод шифрования на выбранные записи
+$matcher->disableEncryption(); // отключает шифрование для выбранных записей
+```
+#### <a name="Documentation-Password"></a> Работа с паролями
+
+Реализована поддержка методов шифрования:
+- `\PhpZip\ZipFile::ENCRYPTION_METHOD_TRADITIONAL` - Traditional PKWARE encryption
+- `\PhpZip\ZipFile::ENCRYPTION_METHOD_WINZIP_AES_256` - WinZip AES encryption 256 bit (рекомендуемое)
+- `\PhpZip\ZipFile::ENCRYPTION_METHOD_WINZIP_AES_192` - WinZip AES encryption 192 bit
+- `\PhpZip\ZipFile::ENCRYPTION_METHOD_WINZIP_AES_128` - WinZip AES encryption 128 bit
+
+<a name="Documentation-ZipFile-setReadPassword"></a> **ZipFile::setReadPassword** - устанавливает пароль на чтение открытого запароленного архива для всех зашифрованных записей.
+
+> _Установка пароля не является обязательной для добавления новых записей или удаления существующих, но если вы захотите извлечь контент или изменить метод/уровень сжатия, метод шифрования или изменить пароль, то в этом случае пароль необходимо указать._
+```php
+$zipFile->setReadPassword($password);
+```
+<a name="Documentation-ZipFile-setReadPasswordEntry"></a> **ZipFile::setReadPasswordEntry** - устанавливает пароль на чтение конкретной зашифрованной записи открытого запароленного архива.
+```php
+$zipFile->setReadPasswordEntry($entryName, $password);
+```
+<a name="Documentation-ZipFile-setPassword"></a> **ZipFile::setPassword** - устанавливает новый пароль для всех файлов, находящихся в архиве.
+
+> _Обратите внимание, что действие данного метода не распространяется на записи, добавленные после выполнения этого метода._
+```php
+$zipFile->setPassword($password);
+```
+Можно установить метод шифрования:
+```php
+$encryptionMethod = ZipFile::ENCRYPTION_METHOD_WINZIP_AES_256;
+$zipFile->setPassword($password, $encryptionMethod);
+```
+<a name="Documentation-ZipFile-setPasswordEntry"></a> **ZipFile::setPasswordEntry** - устанавливает новый пароль для конкретного файла.
+```php
+$zipFile->setPasswordEntry($entryName, $password);
+```
+Можно установить метод шифрования:
+```php
+$encryptionMethod = ZipFile::ENCRYPTION_METHOD_WINZIP_AES_256;
+$zipFile->setPasswordEntry($entryName, $password, $encryptionMethod);
+```
+<a name="Documentation-ZipFile-disableEncryption"></a> **ZipFile::disableEncryption** - отключает шифрования всех записей, находящихся в архиве.
+
+> _Обратите внимание, что действие данного метода не распространяется на записи, добавленные после выполнения этого метода._
+```php
+$zipFile->disableEncryption();
+```
+<a name="Documentation-ZipFile-disableEncryptionEntry"></a> **ZipFile::disableEncryptionEntry** - отключает шифрование записи по её имени.
+```php
+$zipFile->disableEncryptionEntry($entryName);
+```
+#### <a name="Documentation-ZipAlign-Usage"></a> zipalign
+<a name="Documentation-ZipFile-setZipAlign"></a> **ZipFile::setZipAlign** - устанавливает выравнивание архива для оптимизации APK файлов (Android packages).
+
+Метод добавляет паддинги незашифрованным и не сжатым записям, для оптимизации расхода памяти в системе Android. Рекомендуется использовать для `APK` файлов. Файл может незначительно увеличиться.
+
+Этот метод является альтернативой вызова команды `zipalign -f -v 4 filename.zip`.
+
+Подробнее можно ознакомиться по [ссылке](https://developer.android.com/studio/command-line/zipalign.html).
+```php
+// вызовите до сохранения или вывода архива
+$zipFile->setZipAlign(4);
+```
+#### <a name="Documentation-Unchanged"></a> Отмена изменений
+<a name="Documentation-ZipFile-unchangeAll"></a> **ZipFile::unchangeAll** - отменяет все изменения, сделанные в архиве.
+```php
+$zipFile->unchangeAll();
+```
+<a name="Documentation-ZipFile-unchangeArchiveComment"></a> **ZipFile::unchangeArchiveComment** - отменяет изменения в комментарии к архиву.
+```php
+$zipFile->unchangeArchiveComment();
+```
+<a name="Documentation-ZipFile-unchangeEntry"></a> **ZipFile::unchangeEntry** - отменяет изменения для конкретной записи архива.
+```php
+$zipFile->unchangeEntry($entryName);
+```
+#### <a name="Documentation-Save-Or-Output-Entries"></a> Сохранение файла или вывод в браузер
+<a name="Documentation-ZipFile-saveAsFile"></a> **ZipFile::saveAsFile** - сохраняет архив в файл.
+```php
+$zipFile->saveAsFile($filename);
+```
+<a name="Documentation-ZipFile-saveAsStream"></a> **ZipFile::saveAsStream** - записывает архив в поток.
+```php
+// $fp = fopen($filename, 'w+b');
+
+$zipFile->saveAsStream($fp);
+```
+<a name="Documentation-ZipFile-outputAsString"></a> **ZipFile::outputAsString** - выводит ZIP-архив в виде строки.
+```php
+$rawZipArchiveBytes = $zipFile->outputAsString();
+```
+<a name="Documentation-ZipFile-outputAsAttachment"></a> **ZipFile::outputAsAttachment** - выводит ZIP-архив в браузер.
+
+При выводе устанавливаются необходимые заголовки, а после вывода завершается работа скрипта.
+```php
+$zipFile->outputAsAttachment($outputFilename);
+```
+Можно установить MIME-тип:
+```php
+$mimeType = 'application/zip'
+$zipFile->outputAsAttachment($outputFilename, $mimeType);
+```
+<a name="Documentation-ZipFile-outputAsResponse"></a> **ZipFile::outputAsResponse** - выводит ZIP-архив, как Response [PSR-7](http://www.php-fig.org/psr/psr-7/).
+
+Метод вывода может использоваться в любом PSR-7 совместимом фреймворке.
+```php
+// $response = ....; // instance Psr\Http\Message\ResponseInterface
+$zipFile->outputAsResponse($response, $outputFilename);
+```
+Можно установить MIME-тип:
+```php
+$mimeType = 'application/zip'
+$zipFile->outputAsResponse($response, $outputFilename, $mimeType);
+```
+Пример для Slim Framework:
+```php
+$app = new \Slim\App;
+$app->get('/download', function ($req, $res, $args) {
+ $zipFile = new \PhpZip\ZipFile();
+ $zipFile['file.txt'] = 'content';
+ return $zipFile->outputAsResponse($res, 'file.zip');
+});
+$app->run();
+```
+<a name="Documentation-ZipFile-rewrite"></a> **ZipFile::rewrite** - сохраняет изменения и заново открывает изменившийся архив.
+```php
+$zipFile->rewrite();
+```
+#### <a name="Documentation-Close-Zip-Archive"></a> Закрытие архива
+<a name="Documentation-ZipFile-close"></a> **ZipFile::close** - закрывает ZIP-архив.
+```php
+$zipFile->close();
+```
+### <a name="Running-Tests"></a> Запуск тестов
+Установите зависимости для разработки.
+```bash
+composer install --dev
+```
+Запустите тесты:
+```bash
+vendor/bin/phpunit -v -c phpunit.xml
+```
+### <a name="Changelog"></a> История изменений
+[Ссылка на Changelog](CHANGELOG.md)
+### <a name="Upgrade"></a> Обновление версий
+#### <a name="Upgrade-v2-to-v3"></a> Обновление с версии 2 до версии 3.0
+Обновите мажорную версию в файле `composer.json` до `^3.0`.
+```json
+{
+ "require": {
+ "nelexa/zip": "^3.0"
+ }
+}
+```
+Затем установите обновления с помощью `Composer`:
+```bash
+composer update nelexa/zip
+```
+Обновите ваш код для работы с новой версией:
+- Класс `ZipOutputFile` объединён с `ZipFile` и удалён.
+ + Замените `new \PhpZip\ZipOutputFile()` на `new \PhpZip\ZipFile()`
+- Статичиская инициализация методов стала не статической.
+ + Замените `\PhpZip\ZipFile::openFromFile($filename);` на `(new \PhpZip\ZipFile())->openFile($filename);`
+ + Замените `\PhpZip\ZipOutputFile::openFromFile($filename);` на `(new \PhpZip\ZipFile())->openFile($filename);`
+ + Замените `\PhpZip\ZipFile::openFromString($contents);` на `(new \PhpZip\ZipFile())->openFromString($contents);`
+ + Замените `\PhpZip\ZipFile::openFromStream($stream);` на `(new \PhpZip\ZipFile())->openFromStream($stream);`
+ + Замените `\PhpZip\ZipOutputFile::create()` на `new \PhpZip\ZipFile()`
+ + Замените `\PhpZip\ZipOutputFile::openFromZipFile($zipFile)` на `(new \PhpZip\ZipFile())->openFile($filename);`
+- Переименуйте методы:
+ + `addFromFile` в `addFile`
+ + `setLevel` в `setCompressionLevel`
+ + `ZipFile::setPassword` в `ZipFile::withReadPassword`
+ + `ZipOutputFile::setPassword` в `ZipFile::withNewPassword`
+ + `ZipOutputFile::disableEncryptionAllEntries` в `ZipFile::withoutPassword`
+ + `ZipOutputFile::setComment` в `ZipFile::setArchiveComment`
+ + `ZipFile::getComment` в `ZipFile::getArchiveComment`
+- Изменились сигнатуры для методов `addDir`, `addFilesFromGlob`, `addFilesFromRegex`.
+- Удалены методы:
+ + `getLevel`
+ + `setCompressionMethod`
+ + `setEntryPassword`
diff --git a/vendor/nelexa/zip/README.md b/vendor/nelexa/zip/README.md
new file mode 100644
index 0000000..afacf1c
--- /dev/null
+++ b/vendor/nelexa/zip/README.md
@@ -0,0 +1,823 @@
+`PhpZip`
+========
+`PhpZip` is a php-library for extended work with ZIP-archives.
+
+[![Build Status](https://travis-ci.org/Ne-Lexa/php-zip.svg?branch=master)](https://travis-ci.org/Ne-Lexa/php-zip)
+[![Latest Stable Version](https://poser.pugx.org/nelexa/zip/v/stable)](https://packagist.org/packages/nelexa/zip)
+[![Total Downloads](https://poser.pugx.org/nelexa/zip/downloads)](https://packagist.org/packages/nelexa/zip)
+[![Minimum PHP Version](http://img.shields.io/badge/php-%3E%3D%205.5-8892BF.svg)](https://php.net/)
+[![License](https://poser.pugx.org/nelexa/zip/license)](https://packagist.org/packages/nelexa/zip)
+
+[Russian Documentation](README.RU.md)
+
+Table of contents
+-----------------
+- [Features](#Features)
+- [Requirements](#Requirements)
+- [Installation](#Installation)
+- [Examples](#Examples)
+- [Glossary](#Glossary)
+- [Documentation](#Documentation)
+ + [Overview of methods of the class `\PhpZip\ZipFile`](#Documentation-Overview)
+ + [Creation/Opening of ZIP-archive](#Documentation-Open-Zip-Archive)
+ + [Reading entries from the archive](#Documentation-Open-Zip-Entries)
+ + [Iterating entries](#Documentation-Zip-Iterate)
+ + [Getting information about entries](#Documentation-Zip-Info)
+ + [Adding entries to the archive](#Documentation-Add-Zip-Entries)
+ + [Deleting entries from the archive](#Documentation-Remove-Zip-Entries)
+ + [Working with entries and archive](#Documentation-Entries)
+ + [Working with passwords](#Documentation-Password)
+ + [zipalign - alignment tool for Android (APK) files](#Documentation-ZipAlign-Usage)
+ + [Undo changes](#Documentation-Unchanged)
+ + [Saving a file or output to a browser](#Documentation-Save-Or-Output-Entries)
+ + [Closing the archive](#Documentation-Close-Zip-Archive)
+- [Running the tests](#Running-Tests)
+- [Changelog](#Changelog)
+- [Upgrade](#Upgrade)
+ + [Upgrade version 2 to version 3.0](#Upgrade-v2-to-v3)
+
+### <a name="Features"></a> Features
+- Opening and unzipping zip files.
+- Creating ZIP-archives.
+- Modifying ZIP archives.
+- Pure php (not require extension `php-zip` and class `\ZipArchive`).
+- It supports saving the archive to a file, outputting the archive to the browser, or outputting it as a string without saving it to a file.
+- Archival comments and comments of individual entry are supported.
+- Get information about each entry in the archive.
+- Only the following compression methods are supported:
+ + No compressed (Stored).
+ + Deflate compression.
+ + BZIP2 compression with the extension `php-bz2`.
+- Support for `ZIP64` (file size is more than 4 GB or the number of entries in the archive is more than 65535).
+- Built-in support for aligning the archive to optimize Android packages (APK) [`zipalign`](https://developer.android.com/studio/command-line/zipalign.html).
+- Working with passwords for PHP 5.5
+ > **Attention!**
+ >
+ > For 32-bit systems, the `Traditional PKWARE Encryption (ZipCrypto)` encryption method is not currently supported.
+ > Use the encryption method `WinZIP AES Encryption`, whenever possible.
+ + Set the password to read the archive for all entries or only for some.
+ + Change the password for the archive, including for individual entries.
+ + Delete the archive password for all or individual entries.
+ + Set the password and/or the encryption method, both for all, and for individual entries in the archive.
+ + Set different passwords and encryption methods for different entries.
+ + Delete the password for all or some entries.
+ + Support `Traditional PKWARE Encryption (ZipCrypto)` and `WinZIP AES Encryption` encryption methods.
+ + Set the encryption method for all or individual entries in the archive.
+
+### <a name="Requirements"></a> Requirements
+- `PHP` >= 5.5 (preferably 64-bit).
+- Optional php-extension `bzip2` for BZIP2 compression.
+- Optional php-extension `openssl` or `mcrypt` for `WinZip Aes Encryption` support.
+
+### <a name="Installation"></a> Installation
+`composer require nelexa/zip`
+
+Latest stable version: [![Latest Stable Version](https://poser.pugx.org/nelexa/zip/v/stable)](https://packagist.org/packages/nelexa/zip)
+
+### <a name="Examples"></a> Examples
+```php
+// create new archive
+$zipFile = new \PhpZip\ZipFile();
+$zipFile
+ ->addFromString("zip/entry/filename", "Is file content") // add an entry from the string
+ ->addFile("/path/to/file", "data/tofile") // add an entry from the file
+ ->addDir(__DIR__, "to/path/") // add files from the directory
+ ->saveAsFile($outputFilename) // save the archive to a file
+ ->close(); // close archive
+
+// open archive, extract, add files, set password and output to browser.
+$zipFile
+ ->openFile($outputFilename) // open archive from file
+ ->extractTo($outputDirExtract) // extract files to the specified directory
+ ->deleteFromRegex('~^\.~') // delete all hidden (Unix) files
+ ->addFromString('dir/file.txt', 'Test file') // add a new entry from the string
+ ->setPassword('password') // set password for all entries
+ ->outputAsAttachment('library.jar'); // output to the browser without saving to a file
+```
+Other examples can be found in the `tests/` folder
+
+### <a name="Glossary"></a> Glossary
+**Zip Entry** - file or folder in a ZIP-archive. Each entry in the archive has certain properties, for example: file name, compression method, encryption method, file size before compression, file size after compression, CRC32 and others.
+
+### <a name="Documentation"></a> Documentation:
+#### <a name="Documentation-Overview"></a> Overview of methods of the class `\PhpZip\ZipFile`
+- [ZipFile::__construct](#Documentation-ZipFile-__construct) - initializes the ZIP archive.
+- [ZipFile::addAll](#Documentation-ZipFile-addAll) - adds all entries from an array.
+- [ZipFile::addDir](#Documentation-ZipFile-addDir) - adds files to the archive from the directory on the specified path without subdirectories.
+- [ZipFile::addDirRecursive](#Documentation-ZipFile-addDirRecursive) - adds files to the archive from the directory on the specified path with subdirectories.
+- [ZipFile::addEmptyDir](#Documentation-ZipFile-addEmptyDir) - add a new directory.
+- [ZipFile::addFile](#Documentation-ZipFile-addFile) - adds a file to a ZIP archive from the given path.
+- [ZipFile::addFilesFromIterator](#Documentation-ZipFile-addFilesFromIterator) - adds files from the iterator of directories.
+- [ZipFile::addFilesFromGlob](#Documentation-ZipFile-addFilesFromGlob) - adds files from a directory by glob pattern without subdirectories.
+- [ZipFile::addFilesFromGlobRecursive](#Documentation-ZipFile-addFilesFromGlobRecursive) - adds files from a directory by glob pattern with subdirectories.
+- [ZipFile::addFilesFromRegex](#Documentation-ZipFile-addFilesFromRegex) - adds files from a directory by PCRE pattern without subdirectories.
+- [ZipFile::addFilesFromRegexRecursive](#Documentation-ZipFile-addFilesFromRegexRecursive) - adds files from a directory by PCRE pattern with subdirectories.
+- [ZipFile::addFromStream](#Documentation-ZipFile-addFromStream) - adds a entry from the stream to the ZIP archive.
+- [ZipFile::addFromString](#Documentation-ZipFile-addFromString) - adds a file to a ZIP archive using its contents.
+- [ZipFile::close](#Documentation-ZipFile-close) - close the archive.
+- [ZipFile::count](#Documentation-ZipFile-count) - returns the number of entries in the archive.
+- [ZipFile::deleteFromName](#Documentation-ZipFile-deleteFromName) - deletes an entry in the archive using its name.
+- [ZipFile::deleteFromGlob](#Documentation-ZipFile-deleteFromGlob) - deletes a entries in the archive using glob pattern.
+- [ZipFile::deleteFromRegex](#Documentation-ZipFile-deleteFromRegex) - deletes a entries in the archive using PCRE pattern.
+- [ZipFile::deleteAll](#Documentation-ZipFile-deleteAll) - deletes all entries in the ZIP archive.
+- [ZipFile::disableEncryption](#Documentation-ZipFile-disableEncryption) - disable encryption for all entries that are already in the archive.
+- [ZipFile::disableEncryptionEntry](#Documentation-ZipFile-disableEncryptionEntry) - disable encryption of an entry defined by its name.
+- [ZipFile::extractTo](#Documentation-ZipFile-extractTo) - extract the archive contents.
+- [ZipFile::getAllInfo](#Documentation-ZipFile-getAllInfo) - returns detailed information about all entries in the archive.
+- [ZipFile::getArchiveComment](#Documentation-ZipFile-getArchiveComment) - returns the Zip archive comment.
+- [ZipFile::getEntryComment](#Documentation-ZipFile-getEntryComment) - returns the comment of an entry using the entry name.
+- [ZipFile::getEntryContent](#Documentation-ZipFile-getEntryContent) - returns the entry contents using its name.
+- [ZipFile::getEntryInfo](#Documentation-ZipFile-getEntryInfo) - returns detailed information about the entry in the archive.
+- [ZipFile::getListFiles](#Documentation-ZipFile-getListFiles) - returns list of archive files.
+- [ZipFile::hasEntry](#Documentation-ZipFile-hasEntry) - checks if there is an entry in the archive.
+- [ZipFile::isDirectory](#Documentation-ZipFile-isDirectory) - checks that the entry in the archive is a directory.
+- [ZipFile::matcher](#Documentation-ZipFile-matcher) - selecting entries in the archive to perform operations on them.
+- [ZipFile::openFile](#Documentation-ZipFile-openFile) - opens a zip-archive from a file.
+- [ZipFile::openFromString](#Documentation-ZipFile-openFromString) - opens a zip-archive from a string.
+- [ZipFile::openFromStream](#Documentation-ZipFile-openFromStream) - opens a zip-archive from the stream.
+- [ZipFile::outputAsAttachment](#Documentation-ZipFile-outputAsAttachment) - outputs a ZIP-archive to the browser.
+- [ZipFile::outputAsResponse](#Documentation-ZipFile-outputAsResponse) - outputs a ZIP-archive as PSR-7 Response.
+- [ZipFile::outputAsString](#Documentation-ZipFile-outputAsString) - outputs a ZIP-archive as string.
+- [ZipFile::rename](#Documentation-ZipFile-rename) - renames an entry defined by its name.
+- [ZipFile::rewrite](#Documentation-ZipFile-rewrite) - save changes and re-open the changed archive.
+- [ZipFile::saveAsFile](#Documentation-ZipFile-saveAsFile) - saves the archive to a file.
+- [ZipFile::saveAsStream](#Documentation-ZipFile-saveAsStream) - writes the archive to the stream.
+- [ZipFile::setArchiveComment](#Documentation-ZipFile-setArchiveComment) - set the comment of a ZIP archive.
+- [ZipFile::setCompressionLevel](#Documentation-ZipFile-setCompressionLevel) - set the compression level for all files in the archive.
+- [ZipFile::setCompressionLevelEntry](#Documentation-ZipFile-setCompressionLevelEntry) - sets the compression level for the entry by its name.
+- [ZipFile::setCompressionMethodEntry](#Documentation-ZipFile-setCompressionMethodEntry) - sets the compression method for the entry by its name.
+- [ZipFile::setEntryComment](#Documentation-ZipFile-setEntryComment) - set the comment of an entry defined by its name.
+- [ZipFile::setReadPassword](#Documentation-ZipFile-setReadPassword) - set the password for the open archive.
+- [ZipFile::setReadPasswordEntry](#Documentation-ZipFile-setReadPasswordEntry) - sets a password for reading of an entry defined by its name.
+- ~~ZipFile::withNewPassword~~ - is an deprecated method, use the [ZipFile::setPassword](#Documentation-ZipFile-setPassword) method.
+- [ZipFile::setPassword](#Documentation-ZipFile-setPassword) - sets a new password for all files in the archive.
+- [ZipFile::setPasswordEntry](#Documentation-ZipFile-setPasswordEntry) - sets a new password of an entry defined by its name.
+- [ZipFile::setZipAlign](#Documentation-ZipFile-setZipAlign) - sets the alignment of the archive to optimize APK files (Android packages).
+- [ZipFile::unchangeAll](#Documentation-ZipFile-unchangeAll) - undo all changes done in the archive.
+- [ZipFile::unchangeArchiveComment](#Documentation-ZipFile-unchangeArchiveComment) - undo changes to the archive comment.
+- [ZipFile::unchangeEntry](#Documentation-ZipFile-unchangeEntry) - undo changes of an entry defined by its name.
+- ~~ZipFile::withoutPassword~~ - is an deprecated method, use the [ZipFile::disableEncryption](#Documentation-ZipFile-disableEncryption) method.
+- ~~ZipFile::withReadPassword~~ - is an deprecated method, use the [ZipFile::setReadPassword](#Documentation-ZipFile-setReadPassword) method.
+
+#### <a name="Documentation-Open-Zip-Archive"></a> Creation/Opening of ZIP-archive
+<a name="Documentation-ZipFile-__construct"></a>**ZipFile::__construct** - initializes the ZIP archive.
+```php
+$zipFile = new \PhpZip\ZipFile();
+```
+<a name="Documentation-ZipFile-openFile"></a> **ZipFile::openFile** - opens a zip-archive from a file.
+```php
+$zipFile = new \PhpZip\ZipFile();
+$zipFile->openFile('file.zip');
+```
+<a name="Documentation-ZipFile-openFromString"></a> **ZipFile::openFromString** - opens a zip-archive from a string.
+```php
+$zipFile = new \PhpZip\ZipFile();
+$zipFile->openFromString($stringContents);
+```
+<a name="Documentation-ZipFile-openFromStream"></a> **ZipFile::openFromStream** - opens a zip-archive from the stream.
+```php
+$stream = fopen('file.zip', 'rb');
+
+$zipFile = new \PhpZip\ZipFile();
+$zipFile->openFromStream($stream);
+```
+#### <a name="Documentation-Open-Zip-Entries"></a> Reading entries from the archive
+<a name="Documentation-ZipFile-count"></a> **ZipFile::count** - returns the number of entries in the archive.
+```php
+$count = count($zipFile);
+// or
+$count = $zipFile->count();
+```
+<a name="Documentation-ZipFile-getListFiles"></a> **ZipFile::getListFiles** - returns list of archive files.
+```php
+$listFiles = $zipFile->getListFiles();
+
+// example array contents:
+// array (
+// 0 => 'info.txt',
+// 1 => 'path/to/file.jpg',
+// 2 => 'another path/',
+// )
+```
+<a name="Documentation-ZipFile-getEntryContent"></a> **ZipFile::getEntryContent** - returns the entry contents using its name.
+```php
+// $entryName = 'path/to/example-entry-name.txt';
+
+$contents = $zipFile[$entryName];
+// or
+$contents = $zipFile->getEntryContents($entryName);
+```
+<a name="Documentation-ZipFile-hasEntry"></a> **ZipFile::hasEntry** - checks if there is an entry in the archive.
+```php
+// $entryName = 'path/to/example-entry-name.txt';
+
+$hasEntry = isset($zipFile[$entryName]);
+// or
+$hasEntry = $zipFile->hasEntry($entryName);
+```
+<a name="Documentation-ZipFile-isDirectory"></a> **ZipFile::isDirectory** - checks that the entry in the archive is a directory.
+```php
+// $entryName = 'path/to/';
+
+$isDirectory = $zipFile->isDirectory($entryName);
+```
+<a name="Documentation-ZipFile-extractTo"></a> **ZipFile::extractTo** - extract the archive contents.
+The directory must exist.
+```php
+$zipFile->extractTo($directory);
+```
+Extract some files to the directory.
+The directory must exist.
+```php
+$extractOnlyFiles = [
+ "filename1",
+ "filename2",
+ "dir/dir/dir/"
+];
+$zipFile->extractTo($directory, $extractOnlyFiles);
+```
+#### <a name="Documentation-Zip-Iterate"></a> Iterating entries
+`ZipFile` is an iterator.
+Can iterate all the entries in the `foreach` loop.
+```php
+foreach($zipFile as $entryName => $contents){
+ echo "Filename: $entryName" . PHP_EOL;
+ echo "Contents: $contents" . PHP_EOL;
+ echo "-----------------------------" . PHP_EOL;
+}
+```
+Can iterate through the `Iterator`.
+```php
+$iterator = new \ArrayIterator($zipFile);
+while ($iterator->valid())
+{
+ $entryName = $iterator->key();
+ $contents = $iterator->current();
+
+ echo "Filename: $entryName" . PHP_EOL;
+ echo "Contents: $contents" . PHP_EOL;
+ echo "-----------------------------" . PHP_EOL;
+
+ $iterator->next();
+}
+```
+#### <a name="Documentation-Zip-Info"></a> Getting information about entries
+<a name="Documentation-ZipFile-getArchiveComment"></a> **ZipFile::getArchiveComment** - returns the Zip archive comment.
+```php
+$commentArchive = $zipFile->getArchiveComment();
+```
+<a name="Documentation-ZipFile-getEntryComment"></a> **ZipFile::getEntryComment** - returns the comment of an entry using the entry name.
+```php
+$commentEntry = $zipFile->getEntryComment($entryName);
+```
+<a name="Documentation-ZipFile-getEntryInfo"></a> **ZipFile::getEntryInfo** - returns detailed information about the entry in the archive
+```php
+$zipInfo = $zipFile->getEntryInfo('file.txt');
+
+$arrayInfo = $zipInfo->toArray();
+// example array contents:
+// array (
+// 'name' => 'file.gif',
+// 'folder' => false,
+// 'size' => '43',
+// 'compressed_size' => '43',
+// 'modified' => 1510489440,
+// 'created' => null,
+// 'accessed' => null,
+// 'attributes' => '-rw-r--r--',
+// 'encrypted' => false,
+// 'encryption_method' => 0,
+// 'comment' => '',
+// 'crc' => 782934147,
+// 'method_name' => 'No compression',
+// 'compression_method' => 0,
+// 'platform' => 'UNIX',
+// 'version' => 10,
+// )
+
+print_r($zipInfo);
+// output:
+//PhpZip\Model\ZipInfo Object
+//(
+// [name:PhpZip\Model\ZipInfo:private] => file.gif
+// [folder:PhpZip\Model\ZipInfo:private] =>
+// [size:PhpZip\Model\ZipInfo:private] => 43
+// [compressedSize:PhpZip\Model\ZipInfo:private] => 43
+// [mtime:PhpZip\Model\ZipInfo:private] => 1510489324
+// [ctime:PhpZip\Model\ZipInfo:private] =>
+// [atime:PhpZip\Model\ZipInfo:private] =>
+// [encrypted:PhpZip\Model\ZipInfo:private] =>
+// [comment:PhpZip\Model\ZipInfo:private] =>
+// [crc:PhpZip\Model\ZipInfo:private] => 782934147
+// [methodName:PhpZip\Model\ZipInfo:private] => No compression
+// [compressionMethod:PhpZip\Model\ZipInfo:private] => 0
+// [platform:PhpZip\Model\ZipInfo:private] => UNIX
+// [version:PhpZip\Model\ZipInfo:private] => 10
+// [attributes:PhpZip\Model\ZipInfo:private] => -rw-r--r--
+// [encryptionMethod:PhpZip\Model\ZipInfo:private] => 0
+// [compressionLevel:PhpZip\Model\ZipInfo:private] => -1
+//)
+
+echo $zipInfo;
+// Output:
+// PhpZip\Model\ZipInfo {Name="file.gif", Size="43 bytes", Compressed size="43 bytes", Modified time="2017-11-12T15:22:04+03:00", Crc=0x2eaaa083, Method name="No compression", Attributes="-rw-r--r--", Platform="UNIX", Version=10}
+```
+<a name="Documentation-ZipFile-getAllInfo"></a> **ZipFile::getAllInfo** - returns detailed information about all entries in the archive.
+```php
+$zipAllInfo = $zipFile->getAllInfo();
+
+print_r($zipAllInfo);
+//Array
+//(
+// [file.txt] => PhpZip\Model\ZipInfo Object
+// (
+// ...
+// )
+//
+// [file2.txt] => PhpZip\Model\ZipInfo Object
+// (
+// ...
+// )
+//
+// ...
+//)
+```
+#### <a name="Documentation-Add-Zip-Entries"></a> Adding entries to the archive
+
+All methods of adding entries to a ZIP archive allow you to specify a method for compressing content.
+
+The following methods of compression are available:
+- `\PhpZip\ZipFile::METHOD_STORED` - no compression
+- `\PhpZip\ZipFile::METHOD_DEFLATED` - Deflate compression
+- `\PhpZip\ZipFile::METHOD_BZIP2` - Bzip2 compression with the extension `ext-bz2`
+
+<a name="Documentation-ZipFile-addFile"></a> **ZipFile::addFile** - adds a file to a ZIP archive from the given path.
+```php
+// $file = '...../file.ext';
+$zipFile->addFile($file);
+
+// you can specify the name of the entry in the archive (if null, then the last component from the file name is used)
+$zipFile->addFile($file, $entryName);
+// or
+$zipFile[$entryName] = new \SplFileInfo($file);
+
+// you can specify a compression method
+$zipFile->addFile($file, $entryName, ZipFile::METHOD_STORED); // No compression
+$zipFile->addFile($file, $entryName, ZipFile::METHOD_DEFLATED); // Deflate compression
+$zipFile->addFile($file, $entryName, ZipFile::METHOD_BZIP2); // BZIP2 compression
+```
+<a name="Documentation-ZipFile-addFromString"></a> **ZipFile::addFromString** - adds a file to a ZIP archive using its contents.
+```php
+$zipFile[$entryName] = $contents;
+// or
+$zipFile->addFromString($entryName, $contents);
+
+// you can specify a compression method
+$zipFile->addFromString($entryName, $contents, ZipFile::METHOD_STORED); // No compression
+$zipFile->addFromString($entryName, $contents, ZipFile::METHOD_DEFLATED); // Deflate compression
+$zipFile->addFromString($entryName, $contents, ZipFile::METHOD_BZIP2); // BZIP2 compression
+```
+<a name="Documentation-ZipFile-addFromStream"></a> **ZipFile::addFromStream** - adds a entry from the stream to the ZIP archive.
+```php
+// $stream = fopen(..., 'rb');
+
+$zipFile->addFromStream($stream, $entryName);
+// or
+$zipFile[$entryName] = $stream;
+
+// you can specify a compression method
+$zipFile->addFromStream($stream, $entryName, ZipFile::METHOD_STORED); // No compression
+$zipFile->addFromStream($stream, $entryName, ZipFile::METHOD_DEFLATED); // Deflate compression
+$zipFile->addFromStream($stream, $entryName, ZipFile::METHOD_BZIP2); // BZIP2 compression
+```
+<a name="Documentation-ZipFile-addEmptyDir"></a> **ZipFile::addEmptyDir** - add a new directory.
+```php
+// $path = "path/to/";
+
+$zipFile->addEmptyDir($path);
+// or
+$zipFile[$path] = null;
+```
+<a name="Documentation-ZipFile-addAll"></a> **ZipFile::addAll** - adds all entries from an array.
+```php
+$entries = [
+ 'file.txt' => 'file contents', // add an entry from the string contents
+ 'empty dir/' => null, // add empty directory
+ 'path/to/file.jpg' => fopen('..../filename', 'r'), // add an entry from the stream
+ 'path/to/file.dat' => new \SplFileInfo('..../filename'), // add an entry from the file
+];
+
+$zipFile->addAll($entries);
+```
+<a name="Documentation-ZipFile-addDir"></a> **ZipFile::addDir** - adds files to the archive from the directory on the specified path without subdirectories.
+```php
+$zipFile->addDir($dirName);
+
+// you can specify the path in the archive to which you want to put entries
+$localPath = "to/path/";
+$zipFile->addDir($dirName, $localPath);
+
+// you can specify a compression method
+$zipFile->addDir($dirName, $localPath, ZipFile::METHOD_STORED); // No compression
+$zipFile->addDir($dirName, $localPath, ZipFile::METHOD_DEFLATED); // Deflate compression
+$zipFile->addDir($dirName, $localPath, ZipFile::METHOD_BZIP2); // BZIP2 compression
+```
+<a name="Documentation-ZipFile-addDirRecursive"></a> **ZipFile::addDirRecursive** - adds files to the archive from the directory on the specified path with subdirectories.
+```php
+$zipFile->addDirRecursive($dirName);
+
+// you can specify the path in the archive to which you want to put entries
+$localPath = "to/path/";
+$zipFile->addDirRecursive($dirName, $localPath);
+
+// you can specify a compression method
+$zipFile->addDirRecursive($dirName, $localPath, ZipFile::METHOD_STORED); // No compression
+$zipFile->addDirRecursive($dirName, $localPath, ZipFile::METHOD_DEFLATED); // Deflate compression
+$zipFile->addDirRecursive($dirName, $localPath, ZipFile::METHOD_BZIP2); // BZIP2 compression
+```
+<a name="Documentation-ZipFile-addFilesFromIterator"></a> **ZipFile::addFilesFromIterator** - adds files from the iterator of directories.
+```php
+// $directoryIterator = new \DirectoryIterator($dir); // without subdirectories
+// $directoryIterator = new \RecursiveDirectoryIterator($dir); // with subdirectories
+
+$zipFile->addFilesFromIterator($directoryIterator);
+
+// you can specify the path in the archive to which you want to put entries
+$localPath = "to/path/";
+$zipFile->addFilesFromIterator($directoryIterator, $localPath);
+// or
+$zipFile[$localPath] = $directoryIterator;
+
+// you can specify a compression method
+$zipFile->addFilesFromIterator($directoryIterator, $localPath, ZipFile::METHOD_STORED); // No compression
+$zipFile->addFilesFromIterator($directoryIterator, $localPath, ZipFile::METHOD_DEFLATED); // Deflate compression
+$zipFile->addFilesFromIterator($directoryIterator, $localPath, ZipFile::METHOD_BZIP2); // BZIP2 compression
+```
+Example with some files ignoring:
+```php
+$ignoreFiles = [
+ "file_ignore.txt",
+ "dir_ignore/sub dir ignore/"
+];
+
+// $directoryIterator = new \DirectoryIterator($dir); // without subdirectories
+// $directoryIterator = new \RecursiveDirectoryIterator($dir); // with subdirectories
+
+// use \PhpZip\Util\Iterator\IgnoreFilesFilterIterator for non-recursive search
+$ignoreIterator = new \PhpZip\Util\Iterator\IgnoreFilesRecursiveFilterIterator(
+ $directoryIterator,
+ $ignoreFiles
+);
+
+$zipFile->addFilesFromIterator($ignoreIterator);
+```
+<a name="Documentation-ZipFile-addFilesFromGlob"></a> **ZipFile::addFilesFromGlob** - adds files from a directory by [glob pattern](https://en.wikipedia.org/wiki/Glob_(programming)) without subdirectories.
+```php
+$globPattern = '**.{jpg,jpeg,png,gif}'; // example glob pattern -> add all .jpg, .jpeg, .png and .gif files
+
+$zipFile->addFilesFromGlob($dir, $globPattern);
+
+// you can specify the path in the archive to which you want to put entries
+$localPath = "to/path/";
+$zipFile->addFilesFromGlob($dir, $globPattern, $localPath);
+
+// you can specify a compression method
+$zipFile->addFilesFromGlob($dir, $globPattern, $localPath, ZipFile::METHOD_STORED); // No compression
+$zipFile->addFilesFromGlob($dir, $globPattern, $localPath, ZipFile::METHOD_DEFLATED); // Deflate compression
+$zipFile->addFilesFromGlob($dir, $globPattern, $localPath, ZipFile::METHOD_BZIP2); // BZIP2 compression
+```
+<a name="Documentation-ZipFile-addFilesFromGlobRecursive"></a> **ZipFile::addFilesFromGlobRecursive** - adds files from a directory by [glob pattern](https://en.wikipedia.org/wiki/Glob_(programming)) with subdirectories.
+```php
+$globPattern = '**.{jpg,jpeg,png,gif}'; // example glob pattern -> add all .jpg, .jpeg, .png and .gif files
+
+$zipFile->addFilesFromGlobRecursive($dir, $globPattern);
+
+// you can specify the path in the archive to which you want to put entries
+$localPath = "to/path/";
+$zipFile->addFilesFromGlobRecursive($dir, $globPattern, $localPath);
+
+// you can specify a compression method
+$zipFile->addFilesFromGlobRecursive($dir, $globPattern, $localPath, ZipFile::METHOD_STORED); // No compression
+$zipFile->addFilesFromGlobRecursive($dir, $globPattern, $localPath, ZipFile::METHOD_DEFLATED); // Deflate compression
+$zipFile->addFilesFromGlobRecursive($dir, $globPattern, $localPath, ZipFile::METHOD_BZIP2); // BZIP2 compression
+```
+<a name="Documentation-ZipFile-addFilesFromRegex"></a> **ZipFile::addFilesFromRegex** - adds files from a directory by [PCRE pattern](https://en.wikipedia.org/wiki/Regular_expression) without subdirectories.
+```php
+$regexPattern = '/\.(jpe?g|png|gif)$/si'; // example regex pattern -> add all .jpg, .jpeg, .png and .gif files
+
+$zipFile->addFilesFromRegex($dir, $regexPattern);
+
+// you can specify the path in the archive to which you want to put entries
+$localPath = "to/path/";
+$zipFile->addFilesFromRegex($dir, $regexPattern, $localPath);
+
+// you can specify a compression method
+$zipFile->addFilesFromRegex($dir, $regexPattern, $localPath, ZipFile::METHOD_STORED); // No compression
+$zipFile->addFilesFromRegex($dir, $regexPattern, $localPath, ZipFile::METHOD_DEFLATED); // Deflate compression
+$zipFile->addFilesFromRegex($dir, $regexPattern, $localPath, ZipFile::METHOD_BZIP2); // BZIP2 compression
+```
+<a name="Documentation-ZipFile-addFilesFromRegexRecursive"></a> **ZipFile::addFilesFromRegexRecursive** - adds files from a directory by [PCRE pattern](https://en.wikipedia.org/wiki/Regular_expression) with subdirectories.
+```php
+$regexPattern = '/\.(jpe?g|png|gif)$/si'; // example regex pattern -> add all .jpg, .jpeg, .png and .gif files
+
+$zipFile->addFilesFromRegexRecursive($dir, $regexPattern);
+
+// you can specify the path in the archive to which you want to put entries
+$localPath = "to/path/";
+$zipFile->addFilesFromRegexRecursive($dir, $regexPattern, $localPath);
+
+// you can specify a compression method
+$zipFile->addFilesFromRegexRecursive($dir, $regexPattern, $localPath, ZipFile::METHOD_STORED); // No compression
+$zipFile->addFilesFromRegexRecursive($dir, $regexPattern, $localPath, ZipFile::METHOD_DEFLATED); // Deflate compression
+$zipFile->addFilesFromRegexRecursive($dir, $regexPattern, $localPath, ZipFile::METHOD_BZIP2); // BZIP2 compression
+```
+#### <a name="Documentation-Remove-Zip-Entries"></a> Deleting entries from the archive
+<a name="Documentation-ZipFile-deleteFromName"></a> **ZipFile::deleteFromName** - deletes an entry in the archive using its name.
+```php
+$zipFile->deleteFromName($entryName);
+```
+<a name="Documentation-ZipFile-deleteFromGlob"></a> **ZipFile::deleteFromGlob** - deletes a entries in the archive using [glob pattern](https://en.wikipedia.org/wiki/Glob_(programming)).
+```php
+$globPattern = '**.{jpg,jpeg,png,gif}'; // example glob pattern -> delete all .jpg, .jpeg, .png and .gif files
+
+$zipFile->deleteFromGlob($globPattern);
+```
+<a name="Documentation-ZipFile-deleteFromRegex"></a> **ZipFile::deleteFromRegex** - deletes a entries in the archive using [PCRE pattern](https://en.wikipedia.org/wiki/Regular_expression).
+```php
+$regexPattern = '/\.(jpe?g|png|gif)$/si'; // example regex pattern -> delete all .jpg, .jpeg, .png and .gif files
+
+$zipFile->deleteFromRegex($regexPattern);
+```
+<a name="Documentation-ZipFile-deleteAll"></a> **ZipFile::deleteAll** - deletes all entries in the ZIP archive.
+```php
+$zipFile->deleteAll();
+```
+#### <a name="Documentation-Entries"></a> Working with entries and archive
+<a name="Documentation-ZipFile-rename"></a> **ZipFile::rename** - renames an entry defined by its name.
+```php
+$zipFile->rename($oldName, $newName);
+```
+<a name="Documentation-ZipFile-setCompressionLevel"></a> **ZipFile::setCompressionLevel** - set the compression level for all files in the archive.
+
+> _Note that this method does not apply to entries that were added after this method was run._
+
+By default, the compression level is -1 (`\PhpZip\ZipFile::LEVEL_DEFAULT_COMPRESSION`) or the compression level specified in the archive for Deflate compression.
+
+The values -1 (`\PhpZip\ZipFile::LEVEL_DEFAULT_COMPRESSION`) and the range from 1 (`\PhpZip\ZipFile::LEVEL_BEST_SPEED`) to 9 (`\PhpZip\ZipFile::LEVEL_BEST_COMPRESSION`) are supported. The higher the number, the better and longer the compression.
+```php
+$zipFile->setCompressionLevel(\PhpZip\ZipFile::LEVEL_BEST_COMPRESSION);
+```
+<a name="Documentation-ZipFile-setCompressionLevelEntry"></a> **ZipFile::setCompressionLevelEntry** - sets the compression level for the entry by its name.
+
+The values -1 (`\PhpZip\ZipFile::LEVEL_DEFAULT_COMPRESSION`) and the range from 1 (`\PhpZip\ZipFile::LEVEL_BEST_SPEED`) to 9 (`\PhpZip\ZipFile::LEVEL_BEST_COMPRESSION`) are supported. The higher the number, the better and longer the compression.
+```php
+$zipFile->setCompressionLevelEntry($entryName, \PhpZip\ZipFile::LEVEL_BEST_COMPRESSION);
+```
+<a name="Documentation-ZipFile-setCompressionMethodEntry"></a> **ZipFile::setCompressionMethodEntry** - sets the compression method for the entry by its name.
+
+The following compression methods are available:
+- `\PhpZip\ZipFile::METHOD_STORED` - No compression
+- `\PhpZip\ZipFile::METHOD_DEFLATED` - Deflate compression
+- `\PhpZip\ZipFile::METHOD_BZIP2` - Bzip2 compression with the extension `ext-bz2`
+```php
+$zipFile->setCompressionMethodEntry($entryName, ZipFile::METHOD_DEFLATED);
+```
+<a name="Documentation-ZipFile-setArchiveComment"></a> **ZipFile::setArchiveComment** - set the comment of a ZIP archive.
+```php
+$zipFile->setArchiveComment($commentArchive);
+```
+<a name="Documentation-ZipFile-setEntryComment"></a> **ZipFile::setEntryComment** - set the comment of an entry defined by its name.
+```php
+$zipFile->setEntryComment($entryName, $comment);
+```
+<a name="Documentation-ZipFile-matcher"></a> **ZipFile::matcher** - selecting entries in the archive to perform operations on them.
+```php
+$matcher = $zipFile->matcher();
+```
+Selecting files from the archive one at a time:
+```php
+$matcher
+ ->add('entry name')
+ ->add('another entry');
+```
+Select multiple files in the archive:
+```php
+$matcher->add([
+ 'entry name',
+ 'another entry name',
+ 'path/'
+]);
+```
+Selecting files by regular expression:
+```php
+$matcher->match('~\.jpe?g$~i');
+```
+Select all files in the archive:
+```php
+$matcher->all();
+```
+count() - gets the number of selected entries:
+```php
+$count = count($matcher);
+// or
+$count = $matcher->count();
+```
+getMatches() - returns a list of selected entries:
+```php
+$entries = $matcher->getMatches();
+// example array contents: ['entry name', 'another entry name'];
+```
+invoke() - invoke a callable function on selected entries:
+```php
+// example
+$matcher->invoke(function($entryName) use($zipFile) {
+ $newName = preg_replace('~\.(jpe?g)$~i', '.no_optimize.$1', $entryName);
+ $zipFile->rename($entryName, $newName);
+});
+```
+Functions for working on the selected entries:
+```php
+$matcher->delete(); // remove selected entries from a ZIP archive
+$matcher->setPassword($password); // sets a new password for the selected entries
+$matcher->setPassword($password, $encryptionMethod); // sets a new password and encryption method to selected entries
+$matcher->setEncryptionMethod($encryptionMethod); // sets the encryption method to the selected entries
+$matcher->disableEncryption(); // disables encryption for selected entries
+```
+#### <a name="Documentation-Password"></a> Working with passwords
+
+Implemented support for encryption methods:
+- `\PhpZip\ZipFile::ENCRYPTION_METHOD_TRADITIONAL` - Traditional PKWARE encryption
+- `\PhpZip\ZipFile::ENCRYPTION_METHOD_WINZIP_AES_256` - WinZip AES encryption 256 bit (recommended)
+- `\PhpZip\ZipFile::ENCRYPTION_METHOD_WINZIP_AES_192` - WinZip AES encryption 192 bit
+- `\PhpZip\ZipFile::ENCRYPTION_METHOD_WINZIP_AES_128` - WinZip AES encryption 128 bit
+
+<a name="Documentation-ZipFile-setReadPassword"></a> **ZipFile::setReadPassword** - set the password for the open archive.
+
+> _Setting a password is not required for adding new entries or deleting existing ones, but if you want to extract the content or change the method / compression level, the encryption method, or change the password, in this case the password must be specified._
+```php
+$zipFile->setReadPassword($password);
+```
+<a name="Documentation-ZipFile-setReadPasswordEntry"></a> **ZipFile::setReadPasswordEntry** - gets a password for reading of an entry defined by its name.
+```php
+$zipFile->setReadPasswordEntry($entryName, $password);
+```
+<a name="Documentation-ZipFile-setPassword"></a> **ZipFile::setPassword** - sets a new password for all files in the archive.
+
+> _Note that this method does not apply to entries that were added after this method was run._
+```php
+$zipFile->setPassword($password);
+```
+You can set the encryption method:
+```php
+$encryptionMethod = ZipFile::ENCRYPTION_METHOD_WINZIP_AES_256;
+$zipFile->setPassword($password, $encryptionMethod);
+```
+<a name="Documentation-ZipFile-setPasswordEntry"></a> **ZipFile::setPasswordEntry** - sets a new password of an entry defined by its name.
+```php
+$zipFile->setPasswordEntry($entryName, $password);
+```
+You can set the encryption method:
+```php
+$encryptionMethod = ZipFile::ENCRYPTION_METHOD_WINZIP_AES_256;
+$zipFile->setPasswordEntry($entryName, $password, $encryptionMethod);
+```
+<a name="Documentation-ZipFile-disableEncryption"></a> **ZipFile::disableEncryption** - disable encryption for all entries that are already in the archive.
+
+> _Note that this method does not apply to entries that were added after this method was run._
+```php
+$zipFile->disableEncryption();
+```
+<a name="Documentation-ZipFile-disableEncryptionEntry"></a> **ZipFile::disableEncryptionEntry** - disable encryption of an entry defined by its name.
+```php
+$zipFile->disableEncryptionEntry($entryName);
+```
+#### <a name="Documentation-ZipAlign-Usage"></a> zipalign
+<a name="Documentation-ZipFile-setZipAlign"></a> **ZipFile::setZipAlign** - sets the alignment of the archive to optimize APK files (Android packages).
+
+This method adds padding to unencrypted and not compressed entries, to optimize memory consumption in the Android system. It is recommended to use for `APK` files. The file may grow slightly.
+
+This method is an alternative to executing the `zipalign -f -v 4 filename.zip`.
+
+More details can be found on the [link](https://developer.android.com/studio/command-line/zipalign.html).
+```php
+$zipFile->setZipAlign(4);
+```
+#### <a name="Documentation-Unchanged"></a> Undo changes
+<a name="Documentation-ZipFile-unchangeAll"></a> **ZipFile::unchangeAll** - undo all changes done in the archive.
+```php
+$zipFile->unchangeAll();
+```
+<a name="Documentation-ZipFile-unchangeArchiveComment"></a> **ZipFile::unchangeArchiveComment** - undo changes to the archive comment.
+```php
+$zipFile->unchangeArchiveComment();
+```
+<a name="Documentation-ZipFile-unchangeEntry"></a> **ZipFile::unchangeEntry** - undo changes of an entry defined by its name.
+```php
+$zipFile->unchangeEntry($entryName);
+```
+#### <a name="Documentation-Save-Or-Output-Entries"></a> Saving a file or output to a browser
+<a name="Documentation-ZipFile-saveAsFile"></a> **ZipFile::saveAsFile** - saves the archive to a file.
+```php
+$zipFile->saveAsFile($filename);
+```
+<a name="Documentation-ZipFile-saveAsStream"></a> **ZipFile::saveAsStream** - writes the archive to the stream.
+```php
+// $fp = fopen($filename, 'w+b');
+
+$zipFile->saveAsStream($fp);
+```
+<a name="Documentation-ZipFile-outputAsString"></a> **ZipFile::outputAsString** - outputs a ZIP-archive as string.
+```php
+$rawZipArchiveBytes = $zipFile->outputAsString();
+```
+<a name="Documentation-ZipFile-outputAsAttachment"></a> **ZipFile::outputAsAttachment** - outputs a ZIP-archive to the browser.
+```php
+$zipFile->outputAsAttachment($outputFilename);
+```
+You can set the Mime-Type:
+```php
+$mimeType = 'application/zip'
+$zipFile->outputAsAttachment($outputFilename, $mimeType);
+```
+<a name="Documentation-ZipFile-outputAsResponse"></a> **ZipFile::outputAsResponse** - outputs a ZIP-archive as [PSR-7 Response](http://www.php-fig.org/psr/psr-7/).
+
+The output method can be used in any PSR-7 compatible framework.
+```php
+// $response = ....; // instance Psr\Http\Message\ResponseInterface
+$zipFile->outputAsResponse($response, $outputFilename);
+```
+You can set the Mime-Type:
+```php
+$mimeType = 'application/zip'
+$zipFile->outputAsResponse($response, $outputFilename, $mimeType);
+```
+An example for the Slim Framework:
+```php
+$app = new \Slim\App;
+$app->get('/download', function ($req, $res, $args) {
+ $zipFile = new \PhpZip\ZipFile();
+ $zipFile['file.txt'] = 'content';
+ return $zipFile->outputAsResponse($res, 'file.zip');
+});
+$app->run();
+```
+<a name="Documentation-ZipFile-rewrite"></a> **ZipFile::rewrite** - save changes and re-open the changed archive.
+```php
+$zipFile->rewrite();
+```
+#### <a name="Documentation-Close-Zip-Archive"></a> Closing the archive
+<a name="Documentation-ZipFile-close"></a> **ZipFile::close** - close the archive.
+```php
+$zipFile->close();
+```
+### <a name="Running-Tests"></a> Running the tests
+Install the dependencies for the development:
+```bash
+composer install --dev
+```
+Run the tests:
+```bash
+vendor/bin/phpunit -v -c phpunit.xml
+```
+### <a name="Changelog"></a> Changelog
+[Link to Changelog](CHANGELOG.md)
+
+### <a name="Upgrade"></a> Upgrade
+#### <a name="Upgrade-v2-to-v3"></a> Upgrade version 2 to version 3.0
+Update the major version in the file `composer.json` to `^3.0`.
+```json
+{
+ "require": {
+ "nelexa/zip": "^3.0"
+ }
+}
+```
+Then install updates using `Composer`:
+```bash
+composer update nelexa/zip
+```
+Update your code to work with the new version:
+- Class `ZipOutputFile` merged to `ZipFile` and removed.
+ + `new \PhpZip\ZipOutputFile()` to `new \PhpZip\ZipFile()`
+- Static initialization methods are now not static.
+ + `\PhpZip\ZipFile::openFromFile($filename);` to `(new \PhpZip\ZipFile())->openFile($filename);`
+ + `\PhpZip\ZipOutputFile::openFromFile($filename);` to `(new \PhpZip\ZipFile())->openFile($filename);`
+ + `\PhpZip\ZipFile::openFromString($contents);` to `(new \PhpZip\ZipFile())->openFromString($contents);`
+ + `\PhpZip\ZipFile::openFromStream($stream);` to `(new \PhpZip\ZipFile())->openFromStream($stream);`
+ + `\PhpZip\ZipOutputFile::create()` to `new \PhpZip\ZipFile()`
+ + `\PhpZip\ZipOutputFile::openFromZipFile(\PhpZip\ZipFile $zipFile)` &gt; `(new \PhpZip\ZipFile())->openFile($filename);`
+- Rename methods:
+ + `addFromFile` to `addFile`
+ + `setLevel` to `setCompressionLevel`
+ + `ZipFile::setPassword` to `ZipFile::withReadPassword`
+ + `ZipOutputFile::setPassword` to `ZipFile::withNewPassword`
+ + `ZipOutputFile::disableEncryptionAllEntries` to `ZipFile::withoutPassword`
+ + `ZipOutputFile::setComment` to `ZipFile::setArchiveComment`
+ + `ZipFile::getComment` to `ZipFile::getArchiveComment`
+- Changed signature for methods `addDir`, `addFilesFromGlob`, `addFilesFromRegex`.
+- Remove methods:
+ + `getLevel`
+ + `setCompressionMethod`
+ + `setEntryPassword`
+
+
diff --git a/vendor/nelexa/zip/composer.json b/vendor/nelexa/zip/composer.json
new file mode 100644
index 0000000..16b02fd
--- /dev/null
+++ b/vendor/nelexa/zip/composer.json
@@ -0,0 +1,47 @@
+{
+ "name": "nelexa/zip",
+ "type": "library",
+ "description": "PhpZip is a php-library for extended work with ZIP-archives. Open, create, update, delete, extract and get info tool. Supports appending to existing ZIP files, WinZip AES encryption, Traditional PKWARE Encryption, ZipAlign tool, BZIP2 compression, external file attributes and ZIP64 extensions. Alternative ZipArchive. It does not require php-zip extension.",
+ "keywords": [
+ "zip",
+ "unzip",
+ "archive",
+ "extract",
+ "winzip",
+ "zipalign",
+ "ziparchive"
+ ],
+ "homepage": "https://github.com/Ne-Lexa/php-zip",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Ne-Lexa",
+ "email": "alexey@nelexa.ru",
+ "role": "Developer"
+ }
+ ],
+ "require": {
+ "php": "^5.5 || ^7.0",
+ "psr/http-message": "^1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.8|~5.7",
+ "zendframework/zend-diactoros": "^1.4"
+ },
+ "autoload": {
+ "psr-4": {
+ "PhpZip\\": "src/PhpZip"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "PhpZip\\": "tests/PhpZip"
+ }
+ },
+ "suggest": {
+ "ext-openssl": "Needed to support encrypt zip entries or use ext-mcrypt",
+ "ext-mcrypt": "Needed to support encrypt zip entries or use ext-openssl",
+ "ext-bz2": "Needed to support BZIP2 compression"
+ },
+ "minimum-stability": "stable"
+}
diff --git a/vendor/nelexa/zip/phpunit.xml b/vendor/nelexa/zip/phpunit.xml
new file mode 100644
index 0000000..c69aee3
--- /dev/null
+++ b/vendor/nelexa/zip/phpunit.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8" ?>
+
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.8/phpunit.xsd"
+ backupGlobals="false"
+ colors="true"
+ bootstrap="vendor/autoload.php">
+ <php>
+ <ini name="error_reporting" value="-1"/>
+ </php>
+
+ <testsuites>
+ <testsuite name="PhpZip test suite">
+ <directory>tests</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>src</directory>
+ </whitelist>
+ </filter>
+</phpunit> \ No newline at end of file
diff --git a/vendor/nelexa/zip/src/PhpZip/Crypto/TraditionalPkwareEncryptionEngine.php b/vendor/nelexa/zip/src/PhpZip/Crypto/TraditionalPkwareEncryptionEngine.php
new file mode 100644
index 0000000..961ac1f
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Crypto/TraditionalPkwareEncryptionEngine.php
@@ -0,0 +1,225 @@
+<?php
+
+namespace PhpZip\Crypto;
+
+use PhpZip\Exception\ZipAuthenticationException;
+use PhpZip\Exception\ZipCryptoException;
+use PhpZip\Model\ZipEntry;
+use PhpZip\Util\CryptoUtil;
+use PhpZip\Util\PackUtil;
+
+/**
+ * Traditional PKWARE Encryption Engine.
+ *
+ * @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class TraditionalPkwareEncryptionEngine implements ZipEncryptionEngine
+{
+ /**
+ * Encryption header size
+ */
+ const STD_DEC_HDR_SIZE = 12;
+
+ /**
+ * Crc table
+ *
+ * @var array
+ */
+ private static $CRC_TABLE = [
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
+ ];
+
+ /**
+ * Encryption keys
+ *
+ * @var array
+ */
+ private $keys = [];
+ /**
+ * @var ZipEntry
+ */
+ private $entry;
+
+ /**
+ * ZipCryptoEngine constructor.
+ *
+ * @param ZipEntry $entry
+ */
+ public function __construct(ZipEntry $entry)
+ {
+ $this->entry = $entry;
+ }
+
+ /**
+ * Initial keys
+ *
+ * @param string $password
+ */
+ private function initKeys($password)
+ {
+ $this->keys[0] = 305419896;
+ $this->keys[1] = 591751049;
+ $this->keys[2] = 878082192;
+ foreach (unpack('C*', $password) as $b) {
+ $this->updateKeys($b);
+ }
+ }
+
+ /**
+ * Update keys.
+ *
+ * @param string $charAt
+ */
+ private function updateKeys($charAt)
+ {
+ $this->keys[0] = self::crc32($this->keys[0], $charAt);
+ $this->keys[1] = $this->keys[1] + ($this->keys[0] & 0xff);
+ $this->keys[1] = PackUtil::toSignedInt32($this->keys[1] * 134775813 + 1);
+ $this->keys[2] = PackUtil::toSignedInt32(self::crc32($this->keys[2], ($this->keys[1] >> 24) & 0xff));
+ }
+
+ /**
+ * Update crc.
+ *
+ * @param int $oldCrc
+ * @param string $charAt
+ * @return int
+ */
+ private function crc32($oldCrc, $charAt)
+ {
+ return (($oldCrc >> 8) & 0xffffff) ^ self::$CRC_TABLE[($oldCrc ^ $charAt) & 0xff];
+ }
+
+ /**
+ * @param string $content
+ * @return string
+ * @throws ZipAuthenticationException
+ */
+ public function decrypt($content)
+ {
+ $password = $this->entry->getPassword();
+ $this->initKeys($password);
+
+ $headerBytes = array_values(unpack('C*', substr($content, 0, self::STD_DEC_HDR_SIZE)));
+ $byte = 0;
+ foreach ($headerBytes as &$byte) {
+ $byte = ($byte ^ $this->decryptByte()) & 0xff;
+ $this->updateKeys($byte);
+ }
+
+ if ($this->entry->getGeneralPurposeBitFlag(ZipEntry::GPBF_DATA_DESCRIPTOR)) {
+ // compare against the file type from extended local headers
+ $checkByte = ($this->entry->getDosTime() >> 8) & 0xff;
+ } else {
+ // compare against the CRC otherwise
+ $checkByte = ($this->entry->getCrc() >> 24) & 0xff;
+ }
+ if ($byte !== $checkByte) {
+ throw new ZipAuthenticationException("Bad password for entry " . $this->entry->getName());
+ }
+
+ $outputContent = "";
+ foreach (unpack('C*', substr($content, self::STD_DEC_HDR_SIZE)) as $val) {
+ $val = ($val ^ $this->decryptByte()) & 0xff;
+ $this->updateKeys($val);
+ $outputContent .= pack('c', $val);
+ }
+ return $outputContent;
+ }
+
+ /**
+ * Decrypt byte.
+ *
+ * @return int
+ */
+ private function decryptByte()
+ {
+ $temp = $this->keys[2] | 2;
+ return (($temp * ($temp ^ 1)) >> 8) & 0xffffff;
+ }
+
+ /**
+ * Encryption data
+ *
+ * @param string $data
+ * @return string
+ */
+ public function encrypt($data)
+ {
+ $crc = $this->entry->isDataDescriptorRequired() ?
+ ($this->entry->getDosTime() & 0x0000ffff) << 16 :
+ $this->entry->getCrc();
+ $headerBytes = CryptoUtil::randomBytes(self::STD_DEC_HDR_SIZE);
+
+ // Initialize again since the generated bytes were encrypted.
+ $password = $this->entry->getPassword();
+ $this->initKeys($password);
+
+ $headerBytes[self::STD_DEC_HDR_SIZE - 1] = pack('c', ($crc >> 24) & 0xff);
+ $headerBytes[self::STD_DEC_HDR_SIZE - 2] = pack('c', ($crc >> 16) & 0xff);
+
+ $headerBytes = $this->encryptData($headerBytes);
+ return $headerBytes . $this->encryptData($data);
+ }
+
+ /**
+ * @param string $content
+ * @return string
+ * @throws ZipCryptoException
+ */
+ private function encryptData($content)
+ {
+ if (null === $content) {
+ throw new ZipCryptoException('content is null');
+ }
+ $buff = '';
+ foreach (unpack('C*', $content) as $val) {
+ $buff .= pack('c', $this->encryptByte($val));
+ }
+ return $buff;
+ }
+
+ /**
+ * @param int $byte
+ * @return int
+ */
+ private function encryptByte($byte)
+ {
+ $tempVal = $byte ^ $this->decryptByte() & 0xff;
+ $this->updateKeys($byte);
+ return $tempVal;
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Crypto/WinZipAesEngine.php b/vendor/nelexa/zip/src/PhpZip/Crypto/WinZipAesEngine.php
new file mode 100644
index 0000000..04fd808
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Crypto/WinZipAesEngine.php
@@ -0,0 +1,252 @@
+<?php
+
+namespace PhpZip\Crypto;
+
+use PhpZip\Exception\RuntimeException;
+use PhpZip\Exception\ZipAuthenticationException;
+use PhpZip\Exception\ZipCryptoException;
+use PhpZip\Extra\Fields\WinZipAesEntryExtraField;
+use PhpZip\Model\ZipEntry;
+use PhpZip\Util\CryptoUtil;
+
+/**
+ * WinZip Aes Encryption Engine.
+ *
+ * @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class WinZipAesEngine implements ZipEncryptionEngine
+{
+ /**
+ * The block size of the Advanced Encryption Specification (AES) Algorithm
+ * in bits (AES_BLOCK_SIZE_BITS).
+ */
+ const AES_BLOCK_SIZE_BITS = 128;
+ const PWD_VERIFIER_BITS = 16;
+ /**
+ * The iteration count for the derived keys of the cipher, KLAC and MAC.
+ */
+ const ITERATION_COUNT = 1000;
+ /**
+ * @var ZipEntry
+ */
+ private $entry;
+
+ /**
+ * WinZipAesEngine constructor.
+ * @param ZipEntry $entry
+ */
+ public function __construct(ZipEntry $entry)
+ {
+ $this->entry = $entry;
+ }
+
+ /**
+ * Decrypt from stream resource.
+ *
+ * @param string $content Input stream buffer
+ * @return string
+ * @throws ZipAuthenticationException
+ * @throws ZipCryptoException
+ */
+ public function decrypt($content)
+ {
+ $extraFieldsCollection = $this->entry->getExtraFieldsCollection();
+
+ if (!isset($extraFieldsCollection[WinZipAesEntryExtraField::getHeaderId()])) {
+ throw new ZipCryptoException($this->entry->getName() . " (missing extra field for WinZip AES entry)");
+ }
+
+ /**
+ * @var WinZipAesEntryExtraField $field
+ */
+ $field = $extraFieldsCollection[WinZipAesEntryExtraField::getHeaderId()];
+
+ // Get key strength.
+ $keyStrengthBits = $field->getKeyStrength();
+ $keyStrengthBytes = $keyStrengthBits / 8;
+
+ $pos = $keyStrengthBytes / 2;
+ $salt = substr($content, 0, $pos);
+ $passwordVerifier = substr($content, $pos, self::PWD_VERIFIER_BITS / 8);
+ $pos += self::PWD_VERIFIER_BITS / 8;
+
+ $sha1Size = 20;
+
+ // Init start, end and size of encrypted data.
+ $start = $pos;
+ $endPos = strlen($content);
+ $footerSize = $sha1Size / 2;
+ $end = $endPos - $footerSize;
+ $size = $end - $start;
+
+ if (0 > $size) {
+ throw new ZipCryptoException($this->entry->getName() . " (false positive WinZip AES entry is too short)");
+ }
+
+ // Load authentication code.
+ $authenticationCode = substr($content, $end, $footerSize);
+ if ($end + $footerSize !== $endPos) {
+ // This should never happen unless someone is writing to the
+ // end of the file concurrently!
+ throw new ZipCryptoException("Expected end of file after WinZip AES authentication code!");
+ }
+
+ $password = $this->entry->getPassword();
+ assert($password !== null);
+ assert(self::AES_BLOCK_SIZE_BITS <= $keyStrengthBits);
+
+ // WinZip 99-character limit
+ // @see https://sourceforge.net/p/p7zip/discussion/383044/thread/c859a2f0/
+ $password = substr($password, 0, 99);
+ $ctrIvSize = self::AES_BLOCK_SIZE_BITS / 8;
+ $iv = str_repeat(chr(0), $ctrIvSize);
+ do {
+ // Here comes the strange part about WinZip AES encryption:
+ // Its unorthodox use of the Password-Based Key Derivation
+ // Function 2 (PBKDF2) of PKCS #5 V2.0 alias RFC 2898.
+ // Yes, the password verifier is only a 16 bit value.
+ // So we must use the MAC for password verification, too.
+ $keyParam = hash_pbkdf2(
+ "sha1",
+ $password,
+ $salt,
+ self::ITERATION_COUNT,
+ (2 * $keyStrengthBits + self::PWD_VERIFIER_BITS) / 8,
+ true
+ );
+ $key = substr($keyParam, 0, $keyStrengthBytes);
+ $sha1MacParam = substr($keyParam, $keyStrengthBytes, $keyStrengthBytes);
+ // Verify password.
+ } while (!$passwordVerifier === substr($keyParam, 2 * $keyStrengthBytes));
+
+ $content = substr($content, $start, $size);
+ $mac = hash_hmac('sha1', $content, $sha1MacParam, true);
+
+ if (substr($mac, 0, 10) !== $authenticationCode) {
+ throw new ZipAuthenticationException($this->entry->getName() .
+ " (authenticated WinZip AES entry content has been tampered with)");
+ }
+
+ return self::aesCtrSegmentIntegerCounter(false, $content, $key, $iv);
+ }
+
+ /**
+ * Decryption or encryption AES-CTR with Segment Integer Count (SIC).
+ *
+ * @param bool $encrypted If true encryption else decryption
+ * @param string $str Data
+ * @param string $key Key
+ * @param string $iv IV
+ * @return string
+ */
+ private static function aesCtrSegmentIntegerCounter($encrypted = true, $str, $key, $iv)
+ {
+ $numOfBlocks = ceil(strlen($str) / 16);
+ $ctrStr = '';
+ for ($i = 0; $i < $numOfBlocks; ++$i) {
+ for ($j = 0; $j < 16; ++$j) {
+ $n = ord($iv[$j]);
+ if (0x100 === ++$n) {
+ // overflow, set this one to 0, increment next
+ $iv[$j] = chr(0);
+ } else {
+ // no overflow, just write incremented number back and abort
+ $iv[$j] = chr($n);
+ break;
+ }
+ }
+ $data = substr($str, $i * 16, 16);
+ $ctrStr .= $encrypted ?
+ self::encryptCtr($data, $key, $iv) :
+ self::decryptCtr($data, $key, $iv);
+ }
+ return $ctrStr;
+ }
+
+ /**
+ * Encrypt AES-CTR.
+ *
+ * @param string $data Raw data
+ * @param string $key Aes key
+ * @param string $iv Aes IV
+ * @return string Encrypted data
+ * @throws RuntimeException
+ */
+ private static function encryptCtr($data, $key, $iv)
+ {
+ if (extension_loaded("openssl")) {
+ $numBits = strlen($key) * 8;
+ return openssl_encrypt($data, 'AES-' . $numBits . '-CTR', $key, OPENSSL_RAW_DATA, $iv);
+ } elseif (extension_loaded("mcrypt")) {
+ return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, "ctr", $iv);
+ } else {
+ throw new RuntimeException('Extension openssl or mcrypt not loaded');
+ }
+ }
+
+ /**
+ * Decrypt AES-CTR.
+ *
+ * @param string $data Encrypted data
+ * @param string $key Aes key
+ * @param string $iv Aes IV
+ * @return string Raw data
+ * @throws RuntimeException
+ */
+ private static function decryptCtr($data, $key, $iv)
+ {
+ if (extension_loaded("openssl")) {
+ $numBits = strlen($key) * 8;
+ return openssl_decrypt($data, 'AES-' . $numBits . '-CTR', $key, OPENSSL_RAW_DATA, $iv);
+ } elseif (extension_loaded("mcrypt")) {
+ return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, "ctr", $iv);
+ } else {
+ throw new RuntimeException('Extension openssl or mcrypt not loaded');
+ }
+ }
+
+ /**
+ * Encryption string.
+ *
+ * @param string $content
+ * @return string
+ */
+ public function encrypt($content)
+ {
+ // Init key strength.
+ $password = $this->entry->getPassword();
+ assert($password !== null);
+
+ // WinZip 99-character limit
+ // @see https://sourceforge.net/p/p7zip/discussion/383044/thread/c859a2f0/
+ $password = substr($password, 0, 99);
+
+ $keyStrengthBits = WinZipAesEntryExtraField::getKeyStrangeFromEncryptionMethod($this->entry->getEncryptionMethod());
+ $keyStrengthBytes = $keyStrengthBits / 8;
+
+ assert(self::AES_BLOCK_SIZE_BITS <= $keyStrengthBits);
+
+ $salt = CryptoUtil::randomBytes($keyStrengthBytes / 2);
+
+ $keyParam = hash_pbkdf2("sha1", $password, $salt, self::ITERATION_COUNT, (2 * $keyStrengthBits + self::PWD_VERIFIER_BITS) / 8, true);
+ $sha1HMacParam = substr($keyParam, $keyStrengthBytes, $keyStrengthBytes);
+
+ // Can you believe they "forgot" the nonce in the CTR mode IV?! :-(
+ $ctrIvSize = self::AES_BLOCK_SIZE_BITS / 8;
+ $iv = str_repeat(chr(0), $ctrIvSize);
+
+ $key = substr($keyParam, 0, $keyStrengthBytes);
+
+ $content = self::aesCtrSegmentIntegerCounter(true, $content, $key, $iv);
+
+ $mac = hash_hmac('sha1', $content, $sha1HMacParam, true);
+
+ return ($salt .
+ substr($keyParam, 2 * $keyStrengthBytes, self::PWD_VERIFIER_BITS / 8) .
+ $content .
+ substr($mac, 0, 10)
+ );
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Crypto/ZipEncryptionEngine.php b/vendor/nelexa/zip/src/PhpZip/Crypto/ZipEncryptionEngine.php
new file mode 100644
index 0000000..3187969
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Crypto/ZipEncryptionEngine.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace PhpZip\Crypto;
+
+use PhpZip\Exception\ZipAuthenticationException;
+
+/**
+ * Encryption Engine
+ *
+ * @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+interface ZipEncryptionEngine
+{
+ /**
+ * Decryption string.
+ *
+ * @param string $encryptionContent
+ * @return string
+ * @throws ZipAuthenticationException
+ */
+ public function decrypt($encryptionContent);
+
+ /**
+ * Encryption string.
+ *
+ * @param string $content
+ * @return string
+ */
+ public function encrypt($content);
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Exception/Crc32Exception.php b/vendor/nelexa/zip/src/PhpZip/Exception/Crc32Exception.php
new file mode 100644
index 0000000..f82b233
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Exception/Crc32Exception.php
@@ -0,0 +1,66 @@
+<?php
+
+namespace PhpZip\Exception;
+
+/**
+ * Thrown to indicate a CRC32 mismatch between the declared value in the
+ * Central File Header and the Data Descriptor or between the declared value
+ * and the computed value from the decompressed data.
+ *
+ * The exception detail message is the name of the ZIP entry.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class Crc32Exception extends ZipException
+{
+ /**
+ * Expected crc.
+ *
+ * @var int
+ */
+ private $expectedCrc;
+
+ /**
+ * Actual crc.
+ *
+ * @var int
+ */
+ private $actualCrc;
+
+ /**
+ * Crc32Exception constructor.
+ *
+ * @param string $name
+ * @param int $expected
+ * @param int $actual
+ */
+ public function __construct($name, $expected, $actual)
+ {
+ parent::__construct($name . " (expected CRC32 value 0x" .
+ dechex($expected) . ", but is actually 0x" . dechex($actual) . ")");
+ assert($expected != $actual);
+ $this->expectedCrc = $expected;
+ $this->actualCrc = $actual;
+ }
+
+ /**
+ * Returns expected crc.
+ *
+ * @return int
+ */
+ public function getExpectedCrc()
+ {
+ return $this->expectedCrc;
+ }
+
+ /**
+ * Returns actual crc.
+ *
+ * @return int
+ */
+ public function getActualCrc()
+ {
+ return $this->actualCrc;
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Exception/InvalidArgumentException.php b/vendor/nelexa/zip/src/PhpZip/Exception/InvalidArgumentException.php
new file mode 100644
index 0000000..24ccc22
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Exception/InvalidArgumentException.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace PhpZip\Exception;
+
+/**
+ * Thrown to indicate that a method has been passed an illegal or
+ * inappropriate argument.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class InvalidArgumentException extends RuntimeException
+{
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Exception/RuntimeException.php b/vendor/nelexa/zip/src/PhpZip/Exception/RuntimeException.php
new file mode 100644
index 0000000..ddc13d7
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Exception/RuntimeException.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace PhpZip\Exception;
+
+/**
+ * Runtime exception.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class RuntimeException extends ZipException
+{
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Exception/ZipAuthenticationException.php b/vendor/nelexa/zip/src/PhpZip/Exception/ZipAuthenticationException.php
new file mode 100644
index 0000000..7f38672
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Exception/ZipAuthenticationException.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace PhpZip\Exception;
+
+/**
+ * Thrown to indicate that an authenticated ZIP entry has been tampered with.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class ZipAuthenticationException extends ZipCryptoException
+{
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Exception/ZipCryptoException.php b/vendor/nelexa/zip/src/PhpZip/Exception/ZipCryptoException.php
new file mode 100644
index 0000000..772209a
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Exception/ZipCryptoException.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace PhpZip\Exception;
+
+/**
+ * Thrown if there is an issue when reading or writing an encrypted ZIP file
+ * or entry.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class ZipCryptoException extends ZipException
+{
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Exception/ZipException.php b/vendor/nelexa/zip/src/PhpZip/Exception/ZipException.php
new file mode 100644
index 0000000..bd123f8
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Exception/ZipException.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace PhpZip\Exception;
+
+/**
+ * Signals that a Zip exception of some sort has occurred.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ * @see \Exception
+ */
+class ZipException extends \Exception
+{
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Exception/ZipNotFoundEntry.php b/vendor/nelexa/zip/src/PhpZip/Exception/ZipNotFoundEntry.php
new file mode 100644
index 0000000..dfa07a7
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Exception/ZipNotFoundEntry.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace PhpZip\Exception;
+
+/**
+ * Thrown if entry not found.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ * @see \Exception
+ */
+class ZipNotFoundEntry extends ZipException
+{
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Exception/ZipUnsupportMethod.php b/vendor/nelexa/zip/src/PhpZip/Exception/ZipUnsupportMethod.php
new file mode 100644
index 0000000..05198cd
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Exception/ZipUnsupportMethod.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace PhpZip\Exception;
+
+/**
+ * Thrown if entry unsupport compression method.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ * @see \Exception
+ */
+class ZipUnsupportMethod extends ZipException
+{
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Extra/ExtraField.php b/vendor/nelexa/zip/src/PhpZip/Extra/ExtraField.php
new file mode 100644
index 0000000..cbf18bd
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Extra/ExtraField.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace PhpZip\Extra;
+
+/**
+ * Extra Field in a Local or Central Header of a ZIP archive.
+ * It defines the common properties of all Extra Fields and how to
+ * serialize/deserialize them to/from byte arrays.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+interface ExtraField
+{
+ /**
+ * Returns the Header ID (type) of this Extra Field.
+ * The Header ID is an unsigned short integer (two bytes)
+ * which must be constant during the life cycle of this object.
+ *
+ * @return int
+ */
+ public static function getHeaderId();
+
+ /**
+ * Serializes a Data Block.
+ * @return string
+ */
+ public function serialize();
+
+ /**
+ * Initializes this Extra Field by deserializing a Data Block.
+ * @param string $data
+ */
+ public function deserialize($data);
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Extra/ExtraFieldsCollection.php b/vendor/nelexa/zip/src/PhpZip/Extra/ExtraFieldsCollection.php
new file mode 100644
index 0000000..3b42dd7
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Extra/ExtraFieldsCollection.php
@@ -0,0 +1,240 @@
+<?php
+
+namespace PhpZip\Extra;
+
+use PhpZip\Exception\InvalidArgumentException;
+use PhpZip\Exception\ZipException;
+
+/**
+ * Represents a collection of Extra Fields as they may
+ * be present at several locations in ZIP files.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class ExtraFieldsCollection implements \Countable, \ArrayAccess, \Iterator
+{
+ /**
+ * The map of Extra Fields.
+ * Maps from Header ID to Extra Field.
+ * Must not be null, but may be empty if no Extra Fields are used.
+ * The map is sorted by Header IDs in ascending order.
+ *
+ * @var ExtraField[]
+ */
+ protected $collection = [];
+
+ /**
+ * Returns the number of Extra Fields in this collection.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return sizeof($this->collection);
+ }
+
+ /**
+ * Returns the Extra Field with the given Header ID or null
+ * if no such Extra Field exists.
+ *
+ * @param int $headerId The requested Header ID.
+ * @return ExtraField The Extra Field with the given Header ID or
+ * if no such Extra Field exists.
+ * @throws ZipException If headerId is out of range.
+ */
+ public function get($headerId)
+ {
+ if (0x0000 > $headerId || $headerId > 0xffff) {
+ throw new ZipException('headerId out of range');
+ }
+ if (isset($this->collection[$headerId])) {
+ return $this->collection[$headerId];
+ }
+ return null;
+ }
+
+ /**
+ * Stores the given Extra Field in this collection.
+ *
+ * @param ExtraField $extraField The Extra Field to store in this collection.
+ * @return ExtraField The Extra Field previously associated with the Header ID of
+ * of the given Extra Field or null if no such Extra Field existed.
+ * @throws ZipException If headerId is out of range.
+ */
+ public function add(ExtraField $extraField)
+ {
+ $headerId = $extraField::getHeaderId();
+ if (0x0000 > $headerId || $headerId > 0xffff) {
+ throw new ZipException('headerId out of range');
+ }
+ $this->collection[$headerId] = $extraField;
+ return $extraField;
+ }
+
+ /**
+ * Returns Extra Field exists
+ *
+ * @param int $headerId The requested Header ID.
+ * @return bool
+ */
+ public function has($headerId)
+ {
+ return isset($this->collection[$headerId]);
+ }
+
+ /**
+ * Removes the Extra Field with the given Header ID.
+ *
+ * @param int $headerId The requested Header ID.
+ * @return ExtraField The Extra Field with the given Header ID or null
+ * if no such Extra Field exists.
+ * @throws ZipException If headerId is out of range or extra field not found.
+ */
+ public function remove($headerId)
+ {
+ if (0x0000 > $headerId || $headerId > 0xffff) {
+ throw new ZipException('headerId out of range');
+ }
+ if (isset($this->collection[$headerId])) {
+ $ef = $this->collection[$headerId];
+ unset($this->collection[$headerId]);
+ return $ef;
+ }
+ throw new ZipException('ExtraField not found');
+ }
+
+ /**
+ * Whether a offset exists
+ * @link http://php.net/manual/en/arrayaccess.offsetexists.php
+ * @param mixed $offset <p>
+ * An offset to check for.
+ * </p>
+ * @return boolean true on success or false on failure.
+ * </p>
+ * <p>
+ * The return value will be casted to boolean if non-boolean was returned.
+ * @since 5.0.0
+ */
+ public function offsetExists($offset)
+ {
+ return isset($this->collection[$offset]);
+ }
+
+ /**
+ * Offset to retrieve
+ * @link http://php.net/manual/en/arrayaccess.offsetget.php
+ * @param mixed $offset <p>
+ * The offset to retrieve.
+ * </p>
+ * @return mixed Can return all value types.
+ * @since 5.0.0
+ */
+ public function offsetGet($offset)
+ {
+ return $this->get($offset);
+ }
+
+ /**
+ * Offset to set
+ * @link http://php.net/manual/en/arrayaccess.offsetset.php
+ * @param mixed $offset <p>
+ * The offset to assign the value to.
+ * </p>
+ * @param mixed $value <p>
+ * The value to set.
+ * </p>
+ * @return void
+ * @throws InvalidArgumentException
+ * @since 5.0.0
+ */
+ public function offsetSet($offset, $value)
+ {
+ if ($value instanceof ExtraField) {
+ assert($offset == $value::getHeaderId());
+ $this->add($value);
+ } else {
+ throw new InvalidArgumentException('value is not instanceof ' . ExtraField::class);
+ }
+ }
+
+ /**
+ * Offset to unset
+ * @link http://php.net/manual/en/arrayaccess.offsetunset.php
+ * @param mixed $offset <p>
+ * The offset to unset.
+ * </p>
+ * @return void
+ * @since 5.0.0
+ */
+ public function offsetUnset($offset)
+ {
+ $this->remove($offset);
+ }
+
+ /**
+ * Return the current element
+ * @link http://php.net/manual/en/iterator.current.php
+ * @return mixed Can return any type.
+ * @since 5.0.0
+ */
+ public function current()
+ {
+ return current($this->collection);
+ }
+
+ /**
+ * Move forward to next element
+ * @link http://php.net/manual/en/iterator.next.php
+ * @return void Any returned value is ignored.
+ * @since 5.0.0
+ */
+ public function next()
+ {
+ next($this->collection);
+ }
+
+ /**
+ * Return the key of the current element
+ * @link http://php.net/manual/en/iterator.key.php
+ * @return mixed scalar on success, or null on failure.
+ * @since 5.0.0
+ */
+ public function key()
+ {
+ return key($this->collection);
+ }
+
+ /**
+ * Checks if current position is valid
+ * @link http://php.net/manual/en/iterator.valid.php
+ * @return boolean The return value will be casted to boolean and then evaluated.
+ * Returns true on success or false on failure.
+ * @since 5.0.0
+ */
+ public function valid()
+ {
+ return $this->offsetExists($this->key());
+ }
+
+ /**
+ * Rewind the Iterator to the first element
+ * @link http://php.net/manual/en/iterator.rewind.php
+ * @return void Any returned value is ignored.
+ * @since 5.0.0
+ */
+ public function rewind()
+ {
+ reset($this->collection);
+ }
+
+ /**
+ * If clone extra fields.
+ */
+ public function __clone()
+ {
+ foreach ($this->collection as $k => $v) {
+ $this->collection[$k] = clone $v;
+ }
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Extra/ExtraFieldsFactory.php b/vendor/nelexa/zip/src/PhpZip/Extra/ExtraFieldsFactory.php
new file mode 100644
index 0000000..37faa4f
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Extra/ExtraFieldsFactory.php
@@ -0,0 +1,173 @@
+<?php
+
+namespace PhpZip\Extra;
+
+use PhpZip\Exception\ZipException;
+use PhpZip\Extra\Fields\ApkAlignmentExtraField;
+use PhpZip\Extra\Fields\DefaultExtraField;
+use PhpZip\Extra\Fields\JarMarkerExtraField;
+use PhpZip\Extra\Fields\NtfsExtraField;
+use PhpZip\Extra\Fields\WinZipAesEntryExtraField;
+use PhpZip\Extra\Fields\Zip64ExtraField;
+use PhpZip\Model\ZipEntry;
+use PhpZip\Util\StringUtil;
+
+/**
+ * Extra Fields Factory
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class ExtraFieldsFactory
+{
+ /**
+ * @var array|null
+ */
+ protected static $registry;
+
+ private function __construct()
+ {
+ }
+
+ /**
+ * @param string $extra
+ * @param ZipEntry|null $entry
+ * @return ExtraFieldsCollection
+ * @throws ZipException
+ */
+ public static function createExtraFieldCollections($extra, ZipEntry $entry = null)
+ {
+ $extraFieldsCollection = new ExtraFieldsCollection();
+ if (null !== $extra) {
+ $extraLength = strlen($extra);
+ if ($extraLength > 0xffff) {
+ throw new ZipException("Extra Fields too large: " . $extraLength);
+ }
+ $pos = 0;
+ $endPos = $extraLength;
+
+ while ($endPos - $pos >= 4) {
+ $unpack = unpack('vheaderId/vdataSize', substr($extra, $pos, 4));
+ $pos += 4;
+ $headerId = (int)$unpack['headerId'];
+ $dataSize = (int)$unpack['dataSize'];
+ $extraField = ExtraFieldsFactory::create($headerId);
+ if ($extraField instanceof Zip64ExtraField && $entry !== null) {
+ $extraField->setEntry($entry);
+ }
+ $extraField->deserialize(substr($extra, $pos, $dataSize));
+ $pos += $dataSize;
+ $extraFieldsCollection[$headerId] = $extraField;
+ }
+ }
+ return $extraFieldsCollection;
+ }
+
+ public static function createSerializedData(ExtraFieldsCollection $extraFieldsCollection)
+ {
+ $extraData = '';
+ foreach ($extraFieldsCollection as $extraField) {
+ $data = $extraField->serialize();
+ $extraData .= pack('vv', $extraField::getHeaderId(), strlen($data));
+ $extraData .= $data;
+ }
+
+ $size = strlen($extraData);
+ if (0x0000 > $size || $size > 0xffff) {
+ throw new ZipException('Size extra out of range: ' . $size . '. Extra data: ' . $extraData);
+ }
+ return $extraData;
+ }
+
+ /**
+ * A static factory method which creates a new Extra Field based on the
+ * given Header ID.
+ * The returned Extra Field still requires proper initialization, for
+ * example by calling ExtraField::readFrom.
+ *
+ * @param int $headerId An unsigned short integer (two bytes) which indicates
+ * the type of the returned Extra Field.
+ * @return ExtraField A new Extra Field or null if not support header id.
+ * @throws ZipException If headerId is out of range.
+ */
+ public static function create($headerId)
+ {
+ if (0x0000 > $headerId || $headerId > 0xffff) {
+ throw new ZipException('headerId out of range');
+ }
+
+ /**
+ * @var ExtraField $extraField
+ */
+ if (isset(self::getRegistry()[$headerId])) {
+ $extraClassName = self::getRegistry()[$headerId];
+ $extraField = new $extraClassName;
+ if ($extraField::getHeaderId() !== $headerId) {
+ throw new ZipException('Runtime error support headerId ' . $headerId);
+ }
+ } else {
+ $extraField = new DefaultExtraField($headerId);
+ }
+ return $extraField;
+ }
+
+ /**
+ * Registered extra field classes.
+ *
+ * @return array
+ */
+ protected static function getRegistry()
+ {
+ if (null === self::$registry) {
+ self::$registry[WinZipAesEntryExtraField::getHeaderId()] = WinZipAesEntryExtraField::class;
+ self::$registry[NtfsExtraField::getHeaderId()] = NtfsExtraField::class;
+ self::$registry[Zip64ExtraField::getHeaderId()] = Zip64ExtraField::class;
+ self::$registry[ApkAlignmentExtraField::getHeaderId()] = ApkAlignmentExtraField::class;
+ self::$registry[JarMarkerExtraField::getHeaderId()] = JarMarkerExtraField::class;
+ }
+ return self::$registry;
+ }
+
+ /**
+ * @return WinZipAesEntryExtraField
+ */
+ public static function createWinZipAesEntryExtra()
+ {
+ return new WinZipAesEntryExtraField();
+ }
+
+ /**
+ * @return NtfsExtraField
+ */
+ public static function createNtfsExtra()
+ {
+ return new NtfsExtraField();
+ }
+
+ /**
+ * @param ZipEntry $entry
+ * @return Zip64ExtraField
+ */
+ public static function createZip64Extra(ZipEntry $entry)
+ {
+ return new Zip64ExtraField($entry);
+ }
+
+ /**
+ * @param ZipEntry $entry
+ * @param int $padding
+ * @return ApkAlignmentExtraField
+ */
+ public static function createApkAlignExtra(ZipEntry $entry, $padding)
+ {
+ $padding = (int)$padding;
+ $multiple = 4;
+ if (StringUtil::endsWith($entry->getName(), '.so')) {
+ $multiple = ApkAlignmentExtraField::ANDROID_COMMON_PAGE_ALIGNMENT_BYTES;
+ }
+ $extraField = new ApkAlignmentExtraField();
+ $extraField->setMultiple($multiple);
+ $extraField->setPadding($padding);
+ return $extraField;
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Extra/Fields/ApkAlignmentExtraField.php b/vendor/nelexa/zip/src/PhpZip/Extra/Fields/ApkAlignmentExtraField.php
new file mode 100644
index 0000000..0280c44
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Extra/Fields/ApkAlignmentExtraField.php
@@ -0,0 +1,112 @@
+<?php
+
+namespace PhpZip\Extra\Fields;
+
+use PhpZip\Exception\InvalidArgumentException;
+use PhpZip\Extra\ExtraField;
+
+/**
+ * Apk Alignment Extra Field
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class ApkAlignmentExtraField implements ExtraField
+{
+ /**
+ * Minimum size (in bytes) of the extensible data block/field used
+ * for alignment of uncompressed entries.
+ */
+ const ALIGNMENT_ZIP_EXTRA_MIN_SIZE_BYTES = 6;
+
+ const ANDROID_COMMON_PAGE_ALIGNMENT_BYTES = 4096;
+
+ /**
+ * @var int
+ */
+ private $multiple;
+ /**
+ * @var int
+ */
+ private $padding;
+
+ /**
+ * Returns the Header ID (type) of this Extra Field.
+ * The Header ID is an unsigned short integer (two bytes)
+ * which must be constant during the life cycle of this object.
+ *
+ * @return int
+ */
+ public static function getHeaderId()
+ {
+ return 0xD935;
+ }
+
+ /**
+ * Serializes a Data Block.
+ * @return string
+ */
+ public function serialize()
+ {
+ if ($this->padding > 0) {
+ $args = array_merge(
+ ['vc*', $this->multiple],
+ array_fill(2, $this->padding, 0)
+ );
+ return call_user_func_array('pack', $args);
+ }
+ return pack('v', $this->multiple);
+ }
+
+ /**
+ * Initializes this Extra Field by deserializing a Data Block.
+ * @param string $data
+ * @throws InvalidArgumentException
+ */
+ public function deserialize($data)
+ {
+ $length = strlen($data);
+ if ($length < 2) {
+ // This is APK alignment field.
+ // FORMAT:
+ // * uint16 alignment multiple (in bytes)
+ // * remaining bytes -- padding to achieve alignment of data which starts after
+ // the extra field
+ throw new InvalidArgumentException("Minimum 6 bytes of the extensible data block/field used for alignment of uncompressed entries.");
+ }
+ $this->multiple = unpack('v', $data)[1];
+ $this->padding = $length - 2;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getMultiple()
+ {
+ return $this->multiple;
+ }
+
+ /**
+ * @return int
+ */
+ public function getPadding()
+ {
+ return $this->padding;
+ }
+
+ /**
+ * @param int $multiple
+ */
+ public function setMultiple($multiple)
+ {
+ $this->multiple = $multiple;
+ }
+
+ /**
+ * @param int $padding
+ */
+ public function setPadding($padding)
+ {
+ $this->padding = $padding;
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Extra/Fields/DefaultExtraField.php b/vendor/nelexa/zip/src/PhpZip/Extra/Fields/DefaultExtraField.php
new file mode 100644
index 0000000..77af380
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Extra/Fields/DefaultExtraField.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace PhpZip\Extra\Fields;
+
+use PhpZip\Exception\ZipException;
+use PhpZip\Extra\ExtraField;
+
+/**
+ * Default implementation for an Extra Field in a Local or Central Header of a
+ * ZIP file.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class DefaultExtraField implements ExtraField
+{
+ /**
+ * @var int
+ */
+ private static $headerId;
+
+ /**
+ * @var string
+ */
+ protected $data;
+
+ /**
+ * Constructs a new Extra Field.
+ *
+ * @param int $headerId an unsigned short integer (two bytes) indicating the
+ * type of the Extra Field.
+ * @throws ZipException
+ */
+ public function __construct($headerId)
+ {
+ if (0x0000 > $headerId || $headerId > 0xffff) {
+ throw new ZipException('headerId out of range');
+ }
+ self::$headerId = $headerId;
+ }
+
+ /**
+ * Returns the Header ID (type) of this Extra Field.
+ * The Header ID is an unsigned short integer (two bytes)
+ * which must be constant during the life cycle of this object.
+ *
+ * @return int
+ */
+ public static function getHeaderId()
+ {
+ return self::$headerId & 0xffff;
+ }
+
+ /**
+ * Serializes a Data Block.
+ * @return string
+ */
+ public function serialize()
+ {
+ return $this->data;
+ }
+
+ /**
+ * Initializes this Extra Field by deserializing a Data Block.
+ * @param string $data
+ */
+ public function deserialize($data)
+ {
+ $this->data = $data;
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Extra/Fields/JarMarkerExtraField.php b/vendor/nelexa/zip/src/PhpZip/Extra/Fields/JarMarkerExtraField.php
new file mode 100644
index 0000000..4558408
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Extra/Fields/JarMarkerExtraField.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace PhpZip\Extra\Fields;
+
+use PhpZip\Exception\ZipException;
+use PhpZip\Extra\ExtraField;
+
+/**
+ * Jar Marker Extra Field
+ * An executable Java program can be packaged in a JAR file with all the libraries it uses.
+ * Executable JAR files can easily be distinguished from the files packed in the JAR file
+ * by the extra field in the first file, which is hexadecimal in the 0xCAFE bytes series.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class JarMarkerExtraField implements ExtraField
+{
+ /**
+ * Returns the Header ID (type) of this Extra Field.
+ * The Header ID is an unsigned short integer (two bytes)
+ * which must be constant during the life cycle of this object.
+ *
+ * @return int
+ */
+ public static function getHeaderId()
+ {
+ return 0xCAFE;
+ }
+
+ /**
+ * Serializes a Data Block.
+ * @return string
+ */
+ public function serialize()
+ {
+ return '';
+ }
+
+ /**
+ * Initializes this Extra Field by deserializing a Data Block.
+ * @param string $data
+ * @throws ZipException
+ */
+ public function deserialize($data)
+ {
+ if (0 !== strlen($data)) {
+ throw new ZipException("JarMarker doesn't expect any data");
+ }
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Extra/Fields/NtfsExtraField.php b/vendor/nelexa/zip/src/PhpZip/Extra/Fields/NtfsExtraField.php
new file mode 100644
index 0000000..45efb36
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Extra/Fields/NtfsExtraField.php
@@ -0,0 +1,133 @@
+<?php
+
+namespace PhpZip\Extra\Fields;
+
+use PhpZip\Extra\ExtraField;
+use PhpZip\Util\PackUtil;
+
+/**
+ * NTFS Extra Field
+ *
+ * @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class NtfsExtraField implements ExtraField
+{
+
+ /**
+ * Modify time
+ *
+ * @var int Unix Timestamp
+ */
+ private $mtime;
+
+ /**
+ * Access Time
+ *
+ * @var int Unix Timestamp
+ */
+ private $atime;
+
+ /**
+ * Create Time
+ *
+ * @var int Unix Time
+ */
+ private $ctime;
+
+ /**
+ * Returns the Header ID (type) of this Extra Field.
+ * The Header ID is an unsigned short integer (two bytes)
+ * which must be constant during the life cycle of this object.
+ *
+ * @return int
+ */
+ public static function getHeaderId()
+ {
+ return 0x000a;
+ }
+
+ /**
+ * Initializes this Extra Field by deserializing a Data Block.
+ * @param string $data
+ */
+ public function deserialize($data)
+ {
+ $unpack = unpack('vtag/vsizeAttr', substr($data, 0, 4));
+ if (24 === $unpack['sizeAttr']) {
+ $tagData = substr($data, 4, $unpack['sizeAttr']);
+ $this->mtime = PackUtil::unpackLongLE(substr($tagData, 0, 8)) / 10000000 - 11644473600;
+ $this->atime = PackUtil::unpackLongLE(substr($tagData, 8, 8)) / 10000000 - 11644473600;
+ $this->ctime = PackUtil::unpackLongLE(substr($tagData, 16, 8)) / 10000000 - 11644473600;
+ }
+ }
+
+ /**
+ * Serializes a Data Block.
+ * @return string
+ */
+ public function serialize()
+ {
+ $serialize = '';
+ if (null !== $this->mtime && null !== $this->atime && null !== $this->ctime) {
+ $mtimeLong = ($this->mtime + 11644473600) * 10000000;
+ $atimeLong = ($this->atime + 11644473600) * 10000000;
+ $ctimeLong = ($this->ctime + 11644473600) * 10000000;
+
+ $serialize .= pack('Vvv', 0, 1, 8 * 3)
+ . PackUtil::packLongLE($mtimeLong)
+ . PackUtil::packLongLE($atimeLong)
+ . PackUtil::packLongLE($ctimeLong);
+ }
+ return $serialize;
+ }
+
+ /**
+ * @return int
+ */
+ public function getMtime()
+ {
+ return $this->mtime;
+ }
+
+ /**
+ * @param int $mtime
+ */
+ public function setMtime($mtime)
+ {
+ $this->mtime = (int)$mtime;
+ }
+
+ /**
+ * @return int
+ */
+ public function getAtime()
+ {
+ return $this->atime;
+ }
+
+ /**
+ * @param int $atime
+ */
+ public function setAtime($atime)
+ {
+ $this->atime = (int)$atime;
+ }
+
+ /**
+ * @return int
+ */
+ public function getCtime()
+ {
+ return $this->ctime;
+ }
+
+ /**
+ * @param int $ctime
+ */
+ public function setCtime($ctime)
+ {
+ $this->ctime = (int)$ctime;
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Extra/Fields/WinZipAesEntryExtraField.php b/vendor/nelexa/zip/src/PhpZip/Extra/Fields/WinZipAesEntryExtraField.php
new file mode 100644
index 0000000..83b5e97
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Extra/Fields/WinZipAesEntryExtraField.php
@@ -0,0 +1,256 @@
+<?php
+
+namespace PhpZip\Extra\Fields;
+
+use PhpZip\Exception\ZipException;
+use PhpZip\Extra\ExtraField;
+use PhpZip\ZipFileInterface;
+
+/**
+ * WinZip AES Extra Field.
+ *
+ * @see http://www.winzip.com/win/en/aes_info.htm AES Encryption Information: Encryption Specification AE-1 and AE-2 (WinZip Computing, S.L.)
+ * @see http://www.winzip.com/win/en/aes_tips.htm AES Coding Tips for Developers (WinZip Computing, S.L.)
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class WinZipAesEntryExtraField implements ExtraField
+{
+ const DATA_SIZE = 7;
+ const VENDOR_ID = 17729; // 'A' | ('E' << 8);
+
+ /**
+ * Entries of this type <em>do</em> include the standard ZIP CRC-32 value.
+ * For use with @see WinZipAesEntryExtraField::setVendorVersion()}/@see WinZipAesEntryExtraField::getVendorVersion().
+ */
+ const VV_AE_1 = 1;
+
+ /**
+ * Entries of this type do <em>not</em> include the standard ZIP CRC-32 value.
+ * For use with @see WinZipAesEntryExtraField::setVendorVersion()}/@see WinZipAesEntryExtraField::getVendorVersion().
+ */
+ const VV_AE_2 = 2;
+
+ const KEY_STRENGTH_128BIT = 128;
+ const KEY_STRENGTH_192BIT = 192;
+ const KEY_STRENGTH_256BIT = 256;
+
+ protected static $keyStrengths = [
+ self::KEY_STRENGTH_128BIT => 0x01,
+ self::KEY_STRENGTH_192BIT => 0x02,
+ self::KEY_STRENGTH_256BIT => 0x03
+ ];
+
+ protected static $encryptionMethods = [
+ self::KEY_STRENGTH_128BIT => ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_128,
+ self::KEY_STRENGTH_192BIT => ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_192,
+ self::KEY_STRENGTH_256BIT => ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_256
+ ];
+
+ /**
+ * Vendor version.
+ *
+ * @var int
+ */
+ protected $vendorVersion = self::VV_AE_1;
+
+ /**
+ * Encryption strength.
+ *
+ * @var int
+ */
+ protected $encryptionStrength = self::KEY_STRENGTH_256BIT;
+
+ /**
+ * Zip compression method.
+ *
+ * @var int
+ */
+ protected $method;
+
+ /**
+ * Returns the Header ID (type) of this Extra Field.
+ * The Header ID is an unsigned short integer (two bytes)
+ * which must be constant during the life cycle of this object.
+ *
+ * @return int
+ */
+ public static function getHeaderId()
+ {
+ return 0x9901;
+ }
+
+ /**
+ * Returns the vendor version.
+ *
+ * @see WinZipAesEntryExtraField::VV_AE_1
+ * @see WinZipAesEntryExtraField::VV_AE_2
+ */
+ public function getVendorVersion()
+ {
+ return $this->vendorVersion & 0xffff;
+ }
+
+ /**
+ * Sets the vendor version.
+ *
+ * @see WinZipAesEntryExtraField::VV_AE_1
+ * @see WinZipAesEntryExtraField::VV_AE_2
+ * @param int $vendorVersion the vendor version.
+ * @throws ZipException Unsupport vendor version.
+ */
+ public function setVendorVersion($vendorVersion)
+ {
+ if ($vendorVersion < self::VV_AE_1 || self::VV_AE_2 < $vendorVersion) {
+ throw new ZipException($vendorVersion);
+ }
+ $this->vendorVersion = $vendorVersion;
+ }
+
+ /**
+ * Returns vendor id.
+ *
+ * @return int
+ */
+ public function getVendorId()
+ {
+ return self::VENDOR_ID;
+ }
+
+ /**
+ * @return bool|int
+ */
+ public function getKeyStrength()
+ {
+ return self::keyStrength($this->encryptionStrength);
+ }
+
+ /**
+ * @param int $encryptionStrength Encryption strength as bits.
+ * @return int
+ * @throws ZipException If unsupport encryption strength.
+ */
+ public static function keyStrength($encryptionStrength)
+ {
+ $flipKeyStrength = array_flip(self::$keyStrengths);
+ if (!isset($flipKeyStrength[$encryptionStrength])) {
+ throw new ZipException("Unsupport encryption strength " . $encryptionStrength);
+ }
+ return $flipKeyStrength[$encryptionStrength];
+ }
+
+ /**
+ * Returns compression method.
+ *
+ * @return int
+ */
+ public function getMethod()
+ {
+ return $this->method & 0xffff;
+ }
+
+ /**
+ * Internal encryption method.
+ *
+ * @return int
+ */
+ public function getEncryptionMethod()
+ {
+ return isset(self::$encryptionMethods[$this->getKeyStrength()]) ?
+ self::$encryptionMethods[$this->getKeyStrength()] :
+ self::$encryptionMethods[self::KEY_STRENGTH_256BIT];
+ }
+
+ /**
+ * @param int $encryptionMethod
+ * @return int
+ * @throws ZipException
+ */
+ public static function getKeyStrangeFromEncryptionMethod($encryptionMethod)
+ {
+ $flipKey = array_flip(self::$encryptionMethods);
+ if (!isset($flipKey[$encryptionMethod])) {
+ throw new ZipException("Unsupport encryption method " . $encryptionMethod);
+ }
+ return $flipKey[$encryptionMethod];
+ }
+
+ /**
+ * Sets compression method.
+ *
+ * @param int $compressionMethod Compression method
+ * @throws ZipException Compression method out of range.
+ */
+ public function setMethod($compressionMethod)
+ {
+ if (0x0000 > $compressionMethod || $compressionMethod > 0xffff) {
+ throw new ZipException('Compression method out of range');
+ }
+ $this->method = $compressionMethod;
+ }
+
+ /**
+ * Set key strength.
+ *
+ * @param int $keyStrength
+ */
+ public function setKeyStrength($keyStrength)
+ {
+ $this->encryptionStrength = self::encryptionStrength($keyStrength);
+ }
+
+ /**
+ * Returns encryption strength.
+ *
+ * @param int $keyStrength Key strength in bits.
+ * @return int
+ */
+ public static function encryptionStrength($keyStrength)
+ {
+ return isset(self::$keyStrengths[$keyStrength]) ?
+ self::$keyStrengths[$keyStrength] :
+ self::$keyStrengths[self::KEY_STRENGTH_128BIT];
+ }
+
+ /**
+ * Serializes a Data Block.
+ * @return string
+ */
+ public function serialize()
+ {
+ return pack(
+ 'vvcv',
+ $this->vendorVersion,
+ self::VENDOR_ID,
+ $this->encryptionStrength,
+ $this->method
+ );
+ }
+
+ /**
+ * Initializes this Extra Field by deserializing a Data Block.
+ * @param string $data
+ * @throws ZipException
+ */
+ public function deserialize($data)
+ {
+ $size = strlen($data);
+ if (self::DATA_SIZE !== $size) {
+ throw new ZipException('WinZip AES Extra data invalid size: ' . $size . '. Must be ' . self::DATA_SIZE);
+ }
+
+ /**
+ * @var int $vendorVersion
+ * @var int $vendorId
+ * @var int $keyStrength
+ * @var int $method
+ */
+ $unpack = unpack('vvendorVersion/vvendorId/ckeyStrength/vmethod', $data);
+ $this->setVendorVersion($unpack['vendorVersion']);
+ if (self::VENDOR_ID !== $unpack['vendorId']) {
+ throw new ZipException('Vendor id invalid: ' . $unpack['vendorId'] . '. Must be ' . self::VENDOR_ID);
+ }
+ $this->setKeyStrength(self::keyStrength($unpack['keyStrength'])); // checked
+ $this->setMethod($unpack['method']);
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Extra/Fields/Zip64ExtraField.php b/vendor/nelexa/zip/src/PhpZip/Extra/Fields/Zip64ExtraField.php
new file mode 100644
index 0000000..52c3e38
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Extra/Fields/Zip64ExtraField.php
@@ -0,0 +1,118 @@
+<?php
+
+namespace PhpZip\Extra\Fields;
+
+use PhpZip\Exception\RuntimeException;
+use PhpZip\Extra\ExtraField;
+use PhpZip\Model\ZipEntry;
+use PhpZip\Util\PackUtil;
+
+/**
+ * ZIP64 Extra Field
+ *
+ * @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class Zip64ExtraField implements ExtraField
+{
+ /** The Header ID for a ZIP64 Extended Information Extra Field. */
+ const ZIP64_HEADER_ID = 0x0001;
+ /**
+ * @var ZipEntry
+ */
+ protected $entry;
+
+ /**
+ * Zip64ExtraField constructor.
+ * @param ZipEntry $entry
+ */
+ public function __construct(ZipEntry $entry = null)
+ {
+ if (null !== $entry) {
+ $this->setEntry($entry);
+ }
+ }
+
+ /**
+ * @param ZipEntry $entry
+ */
+ public function setEntry(ZipEntry $entry)
+ {
+ $this->entry = $entry;
+ }
+
+ /**
+ * Returns the Header ID (type) of this Extra Field.
+ * The Header ID is an unsigned short integer (two bytes)
+ * which must be constant during the life cycle of this object.
+ *
+ * @return int
+ */
+ public static function getHeaderId()
+ {
+ return 0x0001;
+ }
+
+ /**
+ * Serializes a Data Block.
+ * @return string
+ * @throws RuntimeException
+ */
+ public function serialize()
+ {
+ if (null === $this->entry) {
+ throw new RuntimeException("entry is null");
+ }
+ $data = '';
+ // Write out Uncompressed Size.
+ $size = $this->entry->getSize();
+ if (0xffffffff <= $size) {
+ $data .= PackUtil::packLongLE($size);
+ }
+ // Write out Compressed Size.
+ $compressedSize = $this->entry->getCompressedSize();
+ if (0xffffffff <= $compressedSize) {
+ $data .= PackUtil::packLongLE($compressedSize);
+ }
+ // Write out Relative Header Offset.
+ $offset = $this->entry->getOffset();
+ if (0xffffffff <= $offset) {
+ $data .= PackUtil::packLongLE($offset);
+ }
+ return $data;
+ }
+
+ /**
+ * Initializes this Extra Field by deserializing a Data Block.
+ * @param string $data
+ * @throws RuntimeException
+ */
+ public function deserialize($data)
+ {
+ if (null === $this->entry) {
+ throw new RuntimeException("entry is null");
+ }
+ $off = 0;
+ // Read in Uncompressed Size.
+ $size = $this->entry->getSize();
+ if (0xffffffff <= $size) {
+ assert(0xffffffff === $size);
+ $this->entry->setSize(PackUtil::unpackLongLE(substr($data, $off, 8)));
+ $off += 8;
+ }
+ // Read in Compressed Size.
+ $compressedSize = $this->entry->getCompressedSize();
+ if (0xffffffff <= $compressedSize) {
+ assert(0xffffffff === $compressedSize);
+ $this->entry->setCompressedSize(PackUtil::unpackLongLE(substr($data, $off, 8)));
+ $off += 8;
+ }
+ // Read in Relative Header Offset.
+ $offset = $this->entry->getOffset();
+ if (0xffffffff <= $offset) {
+ assert(0xffffffff, $offset);
+ $this->entry->setOffset(PackUtil::unpackLongLE(substr($data, $off, 8)));
+ }
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Mapper/OffsetPositionMapper.php b/vendor/nelexa/zip/src/PhpZip/Mapper/OffsetPositionMapper.php
new file mode 100644
index 0000000..7ea9116
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Mapper/OffsetPositionMapper.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace PhpZip\Mapper;
+
+/**
+ * Adds a offset value to the given position.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class OffsetPositionMapper extends PositionMapper
+{
+ /**
+ * @var int
+ */
+ private $offset;
+
+ /**
+ * @param int $offset
+ */
+ public function __construct($offset)
+ {
+ $this->offset = (int)$offset;
+ }
+
+ /**
+ * @param int $position
+ * @return int
+ */
+ public function map($position)
+ {
+ return parent::map($position) + $this->offset;
+ }
+
+ /**
+ * @param int $position
+ * @return int
+ */
+ public function unmap($position)
+ {
+ return parent::unmap($position) - $this->offset;
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Mapper/PositionMapper.php b/vendor/nelexa/zip/src/PhpZip/Mapper/PositionMapper.php
new file mode 100644
index 0000000..e5d67c8
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Mapper/PositionMapper.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace PhpZip\Mapper;
+
+/**
+ * Maps a given position.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class PositionMapper
+{
+ /**
+ * @param int $position
+ * @return int
+ */
+ public function map($position)
+ {
+ return $position;
+ }
+
+ /**
+ * @param int $position
+ * @return int
+ */
+ public function unmap($position)
+ {
+ return $position;
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Model/EndOfCentralDirectory.php b/vendor/nelexa/zip/src/PhpZip/Model/EndOfCentralDirectory.php
new file mode 100644
index 0000000..8016e5f
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Model/EndOfCentralDirectory.php
@@ -0,0 +1,120 @@
+<?php
+
+namespace PhpZip\Model;
+
+/**
+ * Read End of Central Directory
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class EndOfCentralDirectory
+{
+ /** Zip64 End Of Central Directory Record. */
+ const ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIG = 0x06064B50;
+ /** Zip64 End Of Central Directory Locator. */
+ const ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIG = 0x07064B50;
+ /** End Of Central Directory Record signature. */
+ const END_OF_CENTRAL_DIRECTORY_RECORD_SIG = 0x06054B50;
+ /**
+ * The minimum length of the End Of Central Directory Record.
+ *
+ * end of central dir signature 4
+ * number of this disk 2
+ * number of the disk with the
+ * start of the central directory 2
+ * total number of entries in the
+ * central directory on this disk 2
+ * total number of entries in
+ * the central directory 2
+ * size of the central directory 4
+ * offset of start of central *
+ * directory with respect to *
+ * the starting disk number 4
+ * zipfile comment length 2
+ */
+ const END_OF_CENTRAL_DIRECTORY_RECORD_MIN_LEN = 22;
+ /**
+ * The length of the Zip64 End Of Central Directory Locator.
+ * zip64 end of central dir locator
+ * signature 4
+ * number of the disk with the
+ * start of the zip64 end of
+ * central directory 4
+ * relative offset of the zip64
+ * end of central directory record 8
+ * total number of disks 4
+ */
+ const ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_LEN = 20;
+ /**
+ * The minimum length of the Zip64 End Of Central Directory Record.
+ *
+ * zip64 end of central dir
+ * signature 4
+ * size of zip64 end of central
+ * directory record 8
+ * version made by 2
+ * version needed to extract 2
+ * number of this disk 4
+ * number of the disk with the
+ * start of the central directory 4
+ * total number of entries in the
+ * central directory on this disk 8
+ * total number of entries in
+ * the central directory 8
+ * size of the central directory 8
+ * offset of start of central
+ * directory with respect to
+ * the starting disk number 8
+ */
+ const ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_MIN_LEN = 56;
+ /**
+ * @var string|null The archive comment.
+ */
+ private $comment;
+ /**
+ * @var int
+ */
+ private $entryCount;
+ /**
+ * @var bool
+ */
+ private $zip64 = false;
+
+ /**
+ * EndOfCentralDirectory constructor.
+ * @param int $entryCount
+ * @param null|string $comment
+ * @param bool $zip64
+ */
+ public function __construct($entryCount, $comment, $zip64 = false)
+ {
+ $this->entryCount = $entryCount;
+ $this->comment = $comment;
+ $this->zip64 = $zip64;
+ }
+
+ /**
+ * @return null|string
+ */
+ public function getComment()
+ {
+ return $this->comment;
+ }
+
+ /**
+ * @return int
+ */
+ public function getEntryCount()
+ {
+ return $this->entryCount;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isZip64()
+ {
+ return $this->zip64;
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Model/Entry/OutputOffsetEntry.php b/vendor/nelexa/zip/src/PhpZip/Model/Entry/OutputOffsetEntry.php
new file mode 100644
index 0000000..94bd15b
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Model/Entry/OutputOffsetEntry.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace PhpZip\Model\Entry;
+
+use PhpZip\Model\ZipEntry;
+
+/**
+ * Entry to write to the central directory.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class OutputOffsetEntry
+{
+ /**
+ * @var int
+ */
+ private $offset;
+ /**
+ * @var ZipEntry
+ */
+ private $entry;
+
+ /**
+ * @param int $pos
+ * @param ZipEntry $entry
+ */
+ public function __construct($pos, ZipEntry $entry)
+ {
+ $this->offset = $pos;
+ $this->entry = $entry;
+ }
+
+ /**
+ * @return int
+ */
+ public function getOffset()
+ {
+ return $this->offset;
+ }
+
+ /**
+ * @return ZipEntry
+ */
+ public function getEntry()
+ {
+ return $this->entry;
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Model/Entry/ZipAbstractEntry.php b/vendor/nelexa/zip/src/PhpZip/Model/Entry/ZipAbstractEntry.php
new file mode 100644
index 0000000..72d1722
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Model/Entry/ZipAbstractEntry.php
@@ -0,0 +1,762 @@
+<?php
+
+namespace PhpZip\Model\Entry;
+
+use PhpZip\Exception\InvalidArgumentException;
+use PhpZip\Exception\ZipException;
+use PhpZip\Extra\ExtraFieldsCollection;
+use PhpZip\Extra\ExtraFieldsFactory;
+use PhpZip\Extra\Fields\WinZipAesEntryExtraField;
+use PhpZip\Model\ZipEntry;
+use PhpZip\Util\DateTimeConverter;
+use PhpZip\Util\StringUtil;
+use PhpZip\ZipFileInterface;
+
+/**
+ * Abstract ZIP entry.
+ *
+ * @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+abstract class ZipAbstractEntry implements ZipEntry
+{
+ /**
+ * @var int Bit flags for init state.
+ */
+ private $init;
+ /**
+ * @var string Entry name (filename in archive)
+ */
+ private $name;
+ /**
+ * @var int Made by platform
+ */
+ private $platform;
+ /**
+ * @var int
+ */
+ private $versionNeededToExtract = 20;
+ /**
+ * @var int Compression method
+ */
+ private $method;
+ /**
+ * @var int
+ */
+ private $general;
+ /**
+ * @var int Dos time
+ */
+ private $dosTime;
+ /**
+ * @var int Crc32
+ */
+ private $crc;
+ /**
+ * @var int Compressed size
+ */
+ private $compressedSize = self::UNKNOWN;
+ /**
+ * @var int Uncompressed size
+ */
+ private $size = self::UNKNOWN;
+ /**
+ * @var int External attributes
+ */
+ private $externalAttributes;
+ /**
+ * @var int Relative Offset Of Local File Header.
+ */
+ private $offset = self::UNKNOWN;
+ /**
+ * Collections of Extra Fields.
+ * Keys from Header ID [int] and value Extra Field [ExtraField].
+ * Should be null or may be empty if no Extra Fields are used.
+ *
+ * @var ExtraFieldsCollection
+ */
+ private $extraFieldsCollection;
+ /**
+ * @var string Comment field.
+ */
+ private $comment;
+ /**
+ * @var string Entry password for read or write encryption data.
+ */
+ private $password;
+ /**
+ * Encryption method.
+ * @see ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL
+ * @see ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_128
+ * @see ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_192
+ * @see ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_256
+ * @var int
+ */
+ private $encryptionMethod = ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL;
+ /**
+ * @var int
+ */
+ private $compressionLevel = ZipFileInterface::LEVEL_DEFAULT_COMPRESSION;
+
+ /**
+ * ZipAbstractEntry constructor.
+ */
+ public function __construct()
+ {
+ $this->extraFieldsCollection = new ExtraFieldsCollection();
+ }
+
+ /**
+ * @param ZipEntry $entry
+ */
+ public function setEntry(ZipEntry $entry)
+ {
+ $this->setName($entry->getName());
+ $this->setPlatform($entry->getPlatform());
+ $this->setVersionNeededToExtract($entry->getVersionNeededToExtract());
+ $this->setMethod($entry->getMethod());
+ $this->setGeneralPurposeBitFlags($entry->getGeneralPurposeBitFlags());
+ $this->setDosTime($entry->getDosTime());
+ $this->setCrc($entry->getCrc());
+ $this->setCompressedSize($entry->getCompressedSize());
+ $this->setSize($entry->getSize());
+ $this->setExternalAttributes($entry->getExternalAttributes());
+ $this->setOffset($entry->getOffset());
+ $this->setExtra($entry->getExtra());
+ $this->setComment($entry->getComment());
+ $this->setPassword($entry->getPassword());
+ $this->setEncryptionMethod($entry->getEncryptionMethod());
+ $this->setCompressionLevel($entry->getCompressionLevel());
+ $this->setEncrypted($entry->isEncrypted());
+ }
+
+ /**
+ * Returns the ZIP entry name.
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Set entry name.
+ *
+ * @param string $name New entry name
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setName($name)
+ {
+ $length = strlen($name);
+ if (0x0000 > $length || $length > 0xffff) {
+ throw new ZipException('Illegal zip entry name parameter');
+ }
+ $this->setGeneralPurposeBitFlag(self::GPBF_UTF8, true);
+ $this->name = $name;
+ return $this;
+ }
+
+ /**
+ * Sets the indexed General Purpose Bit Flag.
+ *
+ * @param int $mask
+ * @param bool $bit
+ * @return ZipEntry
+ */
+ public function setGeneralPurposeBitFlag($mask, $bit)
+ {
+ if ($bit) {
+ $this->general |= $mask;
+ } else {
+ $this->general &= ~$mask;
+ }
+ return $this;
+ }
+
+ /**
+ * @return int Get platform
+ */
+ public function getPlatform()
+ {
+ return $this->isInit(self::BIT_PLATFORM) ? $this->platform & 0xffff : self::UNKNOWN;
+ }
+
+ /**
+ * Set platform
+ *
+ * @param int $platform
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setPlatform($platform)
+ {
+ $known = self::UNKNOWN !== $platform;
+ if ($known) {
+ if (0x00 > $platform || $platform > 0xff) {
+ throw new ZipException("Platform out of range");
+ }
+ $this->platform = $platform;
+ } else {
+ $this->platform = 0;
+ }
+ $this->setInit(self::BIT_PLATFORM, $known);
+ return $this;
+ }
+
+ /**
+ * @param int $mask
+ * @return bool
+ */
+ protected function isInit($mask)
+ {
+ return 0 !== ($this->init & $mask);
+ }
+
+ /**
+ * @param int $mask
+ * @param bool $init
+ */
+ protected function setInit($mask, $init)
+ {
+ if ($init) {
+ $this->init |= $mask;
+ } else {
+ $this->init &= ~$mask;
+ }
+ }
+
+ /**
+ * Version needed to extract.
+ *
+ * @return int
+ */
+ public function getVersionNeededToExtract()
+ {
+ return $this->versionNeededToExtract;
+ }
+
+ /**
+ * Set version needed to extract.
+ *
+ * @param int $version
+ * @return ZipEntry
+ */
+ public function setVersionNeededToExtract($version)
+ {
+ $this->versionNeededToExtract = $version;
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isZip64ExtensionsRequired()
+ {
+ return 0xffffffff <= $this->getCompressedSize()
+ || 0xffffffff <= $this->getSize();
+ }
+
+ /**
+ * Returns the compressed size of this entry.
+ *
+ * @see int
+ */
+ public function getCompressedSize()
+ {
+ return $this->compressedSize;
+ }
+
+ /**
+ * Sets the compressed size of this entry.
+ *
+ * @param int $compressedSize The Compressed Size.
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setCompressedSize($compressedSize)
+ {
+ $this->compressedSize = $compressedSize;
+ return $this;
+ }
+
+ /**
+ * Returns the uncompressed size of this entry.
+ *
+ * @see ZipEntry::setCompressedSize
+ */
+ public function getSize()
+ {
+ return $this->size;
+ }
+
+ /**
+ * Sets the uncompressed size of this entry.
+ *
+ * @param int $size The (Uncompressed) Size.
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setSize($size)
+ {
+ $this->size = $size;
+ return $this;
+ }
+
+ /**
+ * Return relative Offset Of Local File Header.
+ *
+ * @return int
+ */
+ public function getOffset()
+ {
+ return $this->offset;
+ }
+
+ /**
+ * @param int $offset
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setOffset($offset)
+ {
+ $this->offset = $offset;
+ return $this;
+ }
+
+ /**
+ * Returns the General Purpose Bit Flags.
+ * @return int
+ */
+ public function getGeneralPurposeBitFlags()
+ {
+ return $this->general & 0xffff;
+ }
+
+ /**
+ * Sets the General Purpose Bit Flags.
+ *
+ * @var int general
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setGeneralPurposeBitFlags($general)
+ {
+ if (0x0000 > $general || $general > 0xffff) {
+ throw new ZipException('general out of range');
+ }
+ $this->general = $general;
+ if ($this->method === ZipFileInterface::METHOD_DEFLATED) {
+ $bit1 = $this->getGeneralPurposeBitFlag(self::GPBF_COMPRESSION_FLAG1);
+ $bit2 = $this->getGeneralPurposeBitFlag(self::GPBF_COMPRESSION_FLAG2);
+ if ($bit1 && !$bit2) {
+ $this->compressionLevel = ZipFileInterface::LEVEL_BEST_COMPRESSION;
+ } elseif (!$bit1 && $bit2) {
+ $this->compressionLevel = ZipFileInterface::LEVEL_FAST;
+ } elseif ($bit1 && $bit2) {
+ $this->compressionLevel = ZipFileInterface::LEVEL_SUPER_FAST;
+ } else {
+ $this->compressionLevel = ZipFileInterface::LEVEL_DEFAULT_COMPRESSION;
+ }
+ }
+ return $this;
+ }
+
+ /**
+ * Returns true if and only if this ZIP entry is encrypted.
+ *
+ * @return bool
+ */
+ public function isEncrypted()
+ {
+ return $this->getGeneralPurposeBitFlag(self::GPBF_ENCRYPTED);
+ }
+
+ /**
+ * Returns the indexed General Purpose Bit Flag.
+ *
+ * @param int $mask
+ * @return bool
+ */
+ public function getGeneralPurposeBitFlag($mask)
+ {
+ return 0 !== ($this->general & $mask);
+ }
+
+ /**
+ * Sets the encryption property to false and removes any other
+ * encryption artifacts.
+ *
+ * @return ZipEntry
+ */
+ public function disableEncryption()
+ {
+ $this->setEncrypted(false);
+ $headerId = WinZipAesEntryExtraField::getHeaderId();
+ if (isset($this->extraFieldsCollection[$headerId])) {
+ /**
+ * @var WinZipAesEntryExtraField $field
+ */
+ $field = $this->extraFieldsCollection[$headerId];
+ if (self::METHOD_WINZIP_AES === $this->getMethod()) {
+ $this->setMethod(null === $field ? self::UNKNOWN : $field->getMethod());
+ }
+ unset($this->extraFieldsCollection[$headerId]);
+ }
+ $this->password = null;
+ return $this;
+ }
+
+ /**
+ * Sets the encryption flag for this ZIP entry.
+ *
+ * @param bool $encrypted
+ * @return ZipEntry
+ */
+ public function setEncrypted($encrypted)
+ {
+ $encrypted = (bool)$encrypted;
+ $this->setGeneralPurposeBitFlag(self::GPBF_ENCRYPTED, $encrypted);
+ return $this;
+ }
+
+ /**
+ * Returns the compression method for this entry.
+ *
+ * @return int
+ */
+ public function getMethod()
+ {
+ $isInit = $this->isInit(self::BIT_METHOD);
+ return $isInit ?
+ $this->method & 0xffff :
+ self::UNKNOWN;
+ }
+
+ /**
+ * Sets the compression method for this entry.
+ *
+ * @param int $method
+ * @return ZipEntry
+ * @throws ZipException If method is not STORED, DEFLATED, BZIP2 or UNKNOWN.
+ */
+ public function setMethod($method)
+ {
+ if (self::UNKNOWN === $method) {
+ $this->method = $method;
+ $this->setInit(self::BIT_METHOD, false);
+ return $this;
+ }
+ if (0x0000 > $method || $method > 0xffff) {
+ throw new ZipException('method out of range: ' . $method);
+ }
+ switch ($method) {
+ case self::METHOD_WINZIP_AES:
+ case ZipFileInterface::METHOD_STORED:
+ case ZipFileInterface::METHOD_DEFLATED:
+ case ZipFileInterface::METHOD_BZIP2:
+ $this->method = $method;
+ $this->setInit(self::BIT_METHOD, true);
+ break;
+
+ default:
+ throw new ZipException($this->name . " (unsupported compression method $method)");
+ }
+ return $this;
+ }
+
+ /**
+ * Get Unix Timestamp
+ *
+ * @return int
+ */
+ public function getTime()
+ {
+ if (!$this->isInit(self::BIT_DATE_TIME)) {
+ return self::UNKNOWN;
+ }
+ return DateTimeConverter::toUnixTimestamp($this->getDosTime());
+ }
+
+ /**
+ * Get Dos Time
+ *
+ * @return int
+ */
+ public function getDosTime()
+ {
+ return $this->dosTime;
+ }
+
+ /**
+ * Set Dos Time
+ * @param int $dosTime
+ * @throws ZipException
+ */
+ public function setDosTime($dosTime)
+ {
+ $dosTime = sprintf('%u', $dosTime);
+ if (0x00000000 > $dosTime || $dosTime > 0xffffffff) {
+ throw new ZipException('DosTime out of range');
+ }
+ $this->dosTime = $dosTime;
+ $this->setInit(self::BIT_DATE_TIME, true);
+ }
+
+ /**
+ * Set time from unix timestamp.
+ *
+ * @param int $unixTimestamp
+ * @return ZipEntry
+ */
+ public function setTime($unixTimestamp)
+ {
+ $known = self::UNKNOWN != $unixTimestamp;
+ if ($known) {
+ $this->dosTime = DateTimeConverter::toDosTime($unixTimestamp);
+ } else {
+ $this->dosTime = 0;
+ }
+ $this->setInit(self::BIT_DATE_TIME, $known);
+ return $this;
+ }
+
+ /**
+ * Returns the external file attributes.
+ *
+ * @return int The external file attributes.
+ */
+ public function getExternalAttributes()
+ {
+ if (!$this->isInit(self::BIT_EXTERNAL_ATTR)) {
+ return $this->isDirectory() ? 0x10 : 0;
+ }
+ return $this->externalAttributes;
+ }
+
+ /**
+ * Sets the external file attributes.
+ *
+ * @param int $externalAttributes the external file attributes.
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setExternalAttributes($externalAttributes)
+ {
+ $known = self::UNKNOWN != $externalAttributes;
+ if ($known) {
+ $this->externalAttributes = $externalAttributes;
+ } else {
+ $this->externalAttributes = 0;
+ }
+ $this->setInit(self::BIT_EXTERNAL_ATTR, $known);
+ return $this;
+ }
+
+ /**
+ * Returns true if and only if this ZIP entry represents a directory entry
+ * (i.e. end with '/').
+ *
+ * @return bool
+ */
+ public function isDirectory()
+ {
+ return StringUtil::endsWith($this->name, '/');
+ }
+
+ /**
+ * @return ExtraFieldsCollection
+ */
+ public function &getExtraFieldsCollection()
+ {
+ return $this->extraFieldsCollection;
+ }
+
+ /**
+ * Returns a protective copy of the serialized Extra Fields.
+ * @return string
+ * @throws ZipException
+ */
+ public function getExtra()
+ {
+ return ExtraFieldsFactory::createSerializedData($this->extraFieldsCollection);
+ }
+
+ /**
+ * Sets the serialized Extra Fields by making a protective copy.
+ * Note that this method parses the serialized Extra Fields according to
+ * the ZIP File Format Specification and limits its size to 64 KB.
+ * Therefore, this property cannot not be used to hold arbitrary
+ * (application) data.
+ * Consider storing such data in a separate entry instead.
+ *
+ * @param string $data The byte array holding the serialized Extra Fields.
+ * @throws ZipException if the serialized Extra Fields exceed 64 KB
+ */
+ public function setExtra($data)
+ {
+ $this->extraFieldsCollection = ExtraFieldsFactory::createExtraFieldCollections($data, $this);
+ }
+
+ /**
+ * Returns comment entry
+ *
+ * @return string
+ */
+ public function getComment()
+ {
+ return null !== $this->comment ? $this->comment : "";
+ }
+
+ /**
+ * Set entry comment.
+ *
+ * @param $comment
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setComment($comment)
+ {
+ if (null !== $comment) {
+ $commentLength = strlen($comment);
+ if (0x0000 > $commentLength || $commentLength > 0xffff) {
+ throw new ZipException("Comment too long");
+ }
+ }
+ $this->setGeneralPurposeBitFlag(self::GPBF_UTF8, true);
+ $this->comment = $comment;
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isDataDescriptorRequired()
+ {
+ return self::UNKNOWN == ($this->getCrc() | $this->getCompressedSize() | $this->getSize());
+ }
+
+ /**
+ * Return crc32 content or 0 for WinZip AES v2
+ *
+ * @return int
+ */
+ public function getCrc()
+ {
+ return $this->crc;
+ }
+
+ /**
+ * Set crc32 content.
+ *
+ * @param int $crc
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setCrc($crc)
+ {
+ $this->crc = $crc;
+ $this->setInit(self::BIT_CRC, true);
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getPassword()
+ {
+ return $this->password;
+ }
+
+ /**
+ * Set password and encryption method from entry
+ *
+ * @param string $password
+ * @param null|int $encryptionMethod
+ * @return ZipEntry
+ */
+ public function setPassword($password, $encryptionMethod = null)
+ {
+ $this->password = $password;
+ if (null !== $encryptionMethod) {
+ $this->setEncryptionMethod($encryptionMethod);
+ }
+ if (!empty($this->password)) {
+ $this->setEncrypted(true);
+ } else {
+ $this->disableEncryption();
+ }
+ return $this;
+ }
+
+ /**
+ * @return int
+ */
+ public function getEncryptionMethod()
+ {
+ return $this->encryptionMethod;
+ }
+
+ /**
+ * Set encryption method
+ *
+ * @see ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL
+ * @see ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_128
+ * @see ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_192
+ * @see ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_256
+ *
+ * @param int $encryptionMethod
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setEncryptionMethod($encryptionMethod)
+ {
+ if (null !== $encryptionMethod) {
+ if (
+ ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL !== $encryptionMethod
+ && ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_128 !== $encryptionMethod
+ && ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_192 !== $encryptionMethod
+ && ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_256 !== $encryptionMethod
+ ) {
+ throw new ZipException('Invalid encryption method');
+ }
+ $this->encryptionMethod = $encryptionMethod;
+ }
+ return $this;
+ }
+
+ /**
+ * @return int
+ */
+ public function getCompressionLevel()
+ {
+ return $this->compressionLevel;
+ }
+
+ /**
+ * @param int $compressionLevel
+ * @return ZipEntry
+ * @throws InvalidArgumentException
+ */
+ public function setCompressionLevel($compressionLevel = ZipFileInterface::LEVEL_DEFAULT_COMPRESSION)
+ {
+ if ($compressionLevel < ZipFileInterface::LEVEL_DEFAULT_COMPRESSION ||
+ $compressionLevel > ZipFileInterface::LEVEL_BEST_COMPRESSION
+ ) {
+ throw new InvalidArgumentException('Invalid compression level. Minimum level ' .
+ ZipFileInterface::LEVEL_DEFAULT_COMPRESSION . '. Maximum level ' . ZipFileInterface::LEVEL_BEST_COMPRESSION);
+ }
+ $this->compressionLevel = $compressionLevel;
+ return $this;
+ }
+
+ /**
+ * Clone extra fields
+ */
+ public function __clone()
+ {
+ $this->extraFieldsCollection = clone $this->extraFieldsCollection;
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Model/Entry/ZipChangesEntry.php b/vendor/nelexa/zip/src/PhpZip/Model/Entry/ZipChangesEntry.php
new file mode 100644
index 0000000..205a793
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Model/Entry/ZipChangesEntry.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace PhpZip\Model\Entry;
+
+use PhpZip\Exception\ZipException;
+
+/**
+ * Source Entry Changes
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class ZipChangesEntry extends ZipAbstractEntry
+{
+ /**
+ * @var ZipSourceEntry
+ */
+ protected $entry;
+
+ /**
+ * ZipChangesEntry constructor.
+ * @param ZipSourceEntry $entry
+ */
+ public function __construct(ZipSourceEntry $entry)
+ {
+ parent::__construct();
+ $this->entry = $entry;
+ $this->setEntry($entry);
+ }
+
+ /**
+ * @return bool
+ */
+ public function isChangedContent()
+ {
+ return !(
+ $this->getCompressionLevel() === $this->entry->getCompressionLevel() &&
+ $this->getMethod() === $this->entry->getMethod() &&
+ $this->isEncrypted() === $this->entry->isEncrypted() &&
+ $this->getEncryptionMethod() === $this->entry->getEncryptionMethod() &&
+ $this->getPassword() === $this->entry->getPassword()
+ );
+ }
+
+ /**
+ * Returns an string content of the given entry.
+ *
+ * @return null|string
+ * @throws ZipException
+ */
+ public function getEntryContent()
+ {
+ return $this->entry->getEntryContent();
+ }
+
+ /**
+ * @return ZipSourceEntry
+ */
+ public function getSourceEntry()
+ {
+ return $this->entry;
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Model/Entry/ZipNewEntry.php b/vendor/nelexa/zip/src/PhpZip/Model/Entry/ZipNewEntry.php
new file mode 100644
index 0000000..d10a32c
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Model/Entry/ZipNewEntry.php
@@ -0,0 +1,89 @@
+<?php
+
+namespace PhpZip\Model\Entry;
+
+use PhpZip\Exception\InvalidArgumentException;
+use PhpZip\Exception\ZipException;
+use PhpZip\ZipFileInterface;
+
+/**
+ * Abstract class for new zip entry.
+ *
+ * @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class ZipNewEntry extends ZipAbstractEntry
+{
+ /**
+ * @var resource|string|null
+ */
+ protected $content;
+ /**
+ * @var bool
+ */
+ private $clone = false;
+
+ /**
+ * ZipNewEntry constructor.
+ * @param string|resource|null $content
+ * @throws InvalidArgumentException
+ */
+ public function __construct($content = null)
+ {
+ parent::__construct();
+ if ($content !== null && !is_string($content) && !is_resource($content)) {
+ throw new InvalidArgumentException('invalid content');
+ }
+ $this->content = $content;
+ }
+
+ /**
+ * Returns an string content of the given entry.
+ *
+ * @return null|string
+ * @throws ZipException
+ */
+ public function getEntryContent()
+ {
+ if (is_resource($this->content)) {
+ return stream_get_contents($this->content, -1, 0);
+ }
+ return $this->content;
+ }
+
+ /**
+ * Version needed to extract.
+ *
+ * @return int
+ */
+ public function getVersionNeededToExtract()
+ {
+ $method = $this->getMethod();
+ return self::METHOD_WINZIP_AES === $method ? 51 :
+ (
+ ZipFileInterface::METHOD_BZIP2 === $method ? 46 :
+ (
+ $this->isZip64ExtensionsRequired() ? 45 :
+ (ZipFileInterface::METHOD_DEFLATED === $method || $this->isDirectory() ? 20 : 10)
+ )
+ );
+ }
+
+ /**
+ * Clone extra fields
+ */
+ public function __clone()
+ {
+ $this->clone = true;
+ parent::__clone();
+ }
+
+ public function __destruct()
+ {
+ if (!$this->clone && null !== $this->content && is_resource($this->content)) {
+ fclose($this->content);
+ $this->content = null;
+ }
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Model/Entry/ZipSourceEntry.php b/vendor/nelexa/zip/src/PhpZip/Model/Entry/ZipSourceEntry.php
new file mode 100644
index 0000000..7c43f10
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Model/Entry/ZipSourceEntry.php
@@ -0,0 +1,95 @@
+<?php
+
+namespace PhpZip\Model\Entry;
+
+use PhpZip\Exception\ZipException;
+use PhpZip\Stream\ZipInputStreamInterface;
+
+/**
+ * This class is used to represent a ZIP file entry.
+ *
+ * @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class ZipSourceEntry extends ZipAbstractEntry
+{
+ /**
+ * Max size cached content in memory.
+ */
+ const MAX_SIZE_CACHED_CONTENT_IN_MEMORY = 524288; // 512 kb
+ /**
+ * @var ZipInputStreamInterface
+ */
+ protected $inputStream;
+ /**
+ * @var string|resource Cached entry content.
+ */
+ protected $entryContent;
+ /**
+ * @var string
+ */
+ protected $readPassword;
+ /**
+ * @var bool
+ */
+ private $clone = false;
+
+ /**
+ * ZipSourceEntry constructor.
+ * @param ZipInputStreamInterface $inputStream
+ */
+ public function __construct(ZipInputStreamInterface $inputStream)
+ {
+ parent::__construct();
+ $this->inputStream = $inputStream;
+ }
+
+ /**
+ * @return ZipInputStreamInterface
+ */
+ public function getInputStream()
+ {
+ return $this->inputStream;
+ }
+
+ /**
+ * Returns an string content of the given entry.
+ *
+ * @return string
+ * @throws ZipException
+ */
+ public function getEntryContent()
+ {
+ if (null === $this->entryContent) {
+ $content = $this->inputStream->readEntryContent($this);
+ if ($this->getSize() < self::MAX_SIZE_CACHED_CONTENT_IN_MEMORY) {
+ $this->entryContent = $content;
+ } else {
+ $this->entryContent = fopen('php://temp', 'rb');
+ fwrite($this->entryContent, $content);
+ }
+ return $content;
+ }
+ if (is_resource($this->entryContent)) {
+ return stream_get_contents($this->entryContent, -1, 0);
+ }
+ return $this->entryContent;
+ }
+
+ /**
+ * Clone extra fields
+ */
+ public function __clone()
+ {
+ $this->clone = true;
+ parent::__clone();
+ }
+
+ public function __destruct()
+ {
+ if (!$this->clone && null !== $this->entryContent && is_resource($this->entryContent)) {
+ fclose($this->entryContent);
+ }
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Model/ZipEntry.php b/vendor/nelexa/zip/src/PhpZip/Model/ZipEntry.php
new file mode 100644
index 0000000..015b4ac
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Model/ZipEntry.php
@@ -0,0 +1,430 @@
+<?php
+
+namespace PhpZip\Model;
+
+use PhpZip\Exception\ZipException;
+use PhpZip\Extra\ExtraFieldsCollection;
+use PhpZip\ZipFileInterface;
+
+/**
+ * ZIP file entry.
+ *
+ * @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+interface ZipEntry
+{
+ // Bit masks for initialized fields.
+ const BIT_PLATFORM = 1,
+ BIT_METHOD = 2 /* 1 << 1 */,
+ BIT_CRC = 4 /* 1 << 2 */,
+ BIT_DATE_TIME = 64 /* 1 << 6 */,
+ BIT_EXTERNAL_ATTR = 128 /* 1 << 7*/
+ ;
+
+ /** The unknown value for numeric properties. */
+ const UNKNOWN = -1;
+
+ /** Windows platform. */
+ const PLATFORM_FAT = 0;
+ /** Unix platform. */
+ const PLATFORM_UNIX = 3;
+ /** MacOS platform */
+ const PLATFORM_OS_X = 19;
+
+ /**
+ * Pseudo compression method for WinZip AES encrypted entries.
+ * Require php extension openssl or mcrypt.
+ */
+ const METHOD_WINZIP_AES = 99;
+
+ /** General Purpose Bit Flag mask for encrypted data. */
+ const GPBF_ENCRYPTED = 1; // 1 << 0
+// (For Methods 8 and 9 - Deflating)
+// Bit 2 Bit 1
+// 0 0 Normal compression
+// 0 1 Maximum compression
+// 1 0 Fast compression
+// 1 1 Super Fast compression
+ const GPBF_COMPRESSION_FLAG1 = 2; // 1 << 1
+ const GPBF_COMPRESSION_FLAG2 = 4; // 1 << 2
+ /** General Purpose Bit Flag mask for data descriptor. */
+ const GPBF_DATA_DESCRIPTOR = 8; // 1 << 3
+ /** General Purpose Bit Flag mask for strong encryption. */
+ const GPBF_STRONG_ENCRYPTION = 64; // 1 << 6
+ /** General Purpose Bit Flag mask for UTF-8. */
+ const GPBF_UTF8 = 2048; // 1 << 11
+
+ /** Local File Header signature. */
+ const LOCAL_FILE_HEADER_SIG = 0x04034B50;
+ /** Data Descriptor signature. */
+ const DATA_DESCRIPTOR_SIG = 0x08074B50;
+ /**
+ * The minimum length of the Local File Header record.
+ *
+ * local file header signature 4
+ * version needed to extract 2
+ * general purpose bit flag 2
+ * compression method 2
+ * last mod file time 2
+ * last mod file date 2
+ * crc-32 4
+ * compressed size 4
+ * uncompressed size 4
+ * file name length 2
+ * extra field length 2
+ */
+ const LOCAL_FILE_HEADER_MIN_LEN = 30;
+ /**
+ * Local File Header signature 4
+ * Version Needed To Extract 2
+ * General Purpose Bit Flags 2
+ * Compression Method 2
+ * Last Mod File Time 2
+ * Last Mod File Date 2
+ * CRC-32 4
+ * Compressed Size 4
+ * Uncompressed Size 4
+ */
+ const LOCAL_FILE_HEADER_FILE_NAME_LENGTH_POS = 26;
+ /**
+ * Default compression level for bzip2
+ */
+ const LEVEL_DEFAULT_BZIP2_COMPRESSION = 4;
+
+ /**
+ * Returns the ZIP entry name.
+ *
+ * @return string
+ */
+ public function getName();
+
+ /**
+ * Set entry name.
+ *
+ * @param string $name New entry name
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setName($name);
+
+ /**
+ * @return int Get platform
+ */
+ public function getPlatform();
+
+ /**
+ * Set platform
+ *
+ * @param int $platform
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setPlatform($platform);
+
+ /**
+ * Version needed to extract.
+ *
+ * @return int
+ */
+ public function getVersionNeededToExtract();
+
+ /**
+ * Set version needed to extract.
+ *
+ * @param int $version
+ * @return ZipEntry
+ */
+ public function setVersionNeededToExtract($version);
+
+ /**
+ * @return bool
+ */
+ public function isZip64ExtensionsRequired();
+
+ /**
+ * Returns the compressed size of this entry.
+ *
+ * @see int
+ */
+ public function getCompressedSize();
+
+ /**
+ * Sets the compressed size of this entry.
+ *
+ * @param int $compressedSize The Compressed Size.
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setCompressedSize($compressedSize);
+
+ /**
+ * Returns the uncompressed size of this entry.
+ *
+ * @see ZipEntry::setCompressedSize
+ */
+ public function getSize();
+
+ /**
+ * Sets the uncompressed size of this entry.
+ *
+ * @param int $size The (Uncompressed) Size.
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setSize($size);
+
+ /**
+ * Return relative Offset Of Local File Header.
+ *
+ * @return int
+ */
+ public function getOffset();
+
+ /**
+ * @param int $offset
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setOffset($offset);
+
+ /**
+ * Returns true if and only if this ZIP entry represents a directory entry
+ * (i.e. end with '/').
+ *
+ * @return bool
+ */
+ public function isDirectory();
+
+ /**
+ * Returns the General Purpose Bit Flags.
+ *
+ * @return int
+ */
+ public function getGeneralPurposeBitFlags();
+
+ /**
+ * Sets the General Purpose Bit Flags.
+ *
+ * @var int general
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setGeneralPurposeBitFlags($general);
+
+ /**
+ * Returns the indexed General Purpose Bit Flag.
+ *
+ * @param int $mask
+ * @return bool
+ */
+ public function getGeneralPurposeBitFlag($mask);
+
+ /**
+ * Sets the indexed General Purpose Bit Flag.
+ *
+ * @param int $mask
+ * @param bool $bit
+ * @return ZipEntry
+ */
+ public function setGeneralPurposeBitFlag($mask, $bit);
+
+ /**
+ * Returns true if and only if this ZIP entry is encrypted.
+ *
+ * @return bool
+ */
+ public function isEncrypted();
+
+ /**
+ * Sets the encryption flag for this ZIP entry.
+ *
+ * @param bool $encrypted
+ * @return ZipEntry
+ */
+ public function setEncrypted($encrypted);
+
+ /**
+ * Sets the encryption property to false and removes any other
+ * encryption artifacts.
+ *
+ * @return ZipEntry
+ */
+ public function disableEncryption();
+
+ /**
+ * Returns the compression method for this entry.
+ *
+ * @return int
+ */
+ public function getMethod();
+
+ /**
+ * Sets the compression method for this entry.
+ *
+ * @param int $method
+ * @return ZipEntry
+ * @throws ZipException If method is not STORED, DEFLATED, BZIP2 or UNKNOWN.
+ */
+ public function setMethod($method);
+
+ /**
+ * Get Unix Timestamp
+ *
+ * @return int
+ */
+ public function getTime();
+
+ /**
+ * Set time from unix timestamp.
+ *
+ * @param int $unixTimestamp
+ * @return ZipEntry
+ */
+ public function setTime($unixTimestamp);
+
+ /**
+ * Get Dos Time
+ *
+ * @return int
+ */
+ public function getDosTime();
+
+ /**
+ * Set Dos Time
+ * @param int $dosTime
+ * @throws ZipException
+ */
+ public function setDosTime($dosTime);
+
+ /**
+ * Returns the external file attributes.
+ *
+ * @return int The external file attributes.
+ */
+ public function getExternalAttributes();
+
+ /**
+ * Sets the external file attributes.
+ *
+ * @param int $externalAttributes the external file attributes.
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setExternalAttributes($externalAttributes);
+
+ /**
+ * @return ExtraFieldsCollection
+ */
+ public function getExtraFieldsCollection();
+
+ /**
+ * Returns a protective copy of the serialized Extra Fields.
+ *
+ * @return string A new byte array holding the serialized Extra Fields.
+ * null is never returned.
+ */
+ public function getExtra();
+
+ /**
+ * Sets the serialized Extra Fields by making a protective copy.
+ * Note that this method parses the serialized Extra Fields according to
+ * the ZIP File Format Specification and limits its size to 64 KB.
+ * Therefore, this property cannot not be used to hold arbitrary
+ * (application) data.
+ * Consider storing such data in a separate entry instead.
+ *
+ * @param string $data The byte array holding the serialized Extra Fields.
+ * @throws ZipException if the serialized Extra Fields exceed 64 KB
+ */
+ public function setExtra($data);
+
+ /**
+ * Returns comment entry
+ *
+ * @return string
+ */
+ public function getComment();
+
+ /**
+ * Set entry comment.
+ *
+ * @param $comment
+ * @return ZipEntry
+ */
+ public function setComment($comment);
+
+ /**
+ * @return bool
+ */
+ public function isDataDescriptorRequired();
+
+ /**
+ * Return crc32 content or 0 for WinZip AES v2
+ *
+ * @return int
+ */
+ public function getCrc();
+
+ /**
+ * Set crc32 content.
+ *
+ * @param int $crc
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setCrc($crc);
+
+ /**
+ * @return string
+ */
+ public function getPassword();
+
+ /**
+ * Set password and encryption method from entry
+ *
+ * @param string $password
+ * @param null|int $encryptionMethod
+ * @return ZipEntry
+ */
+ public function setPassword($password, $encryptionMethod = null);
+
+ /**
+ * @return int
+ */
+ public function getEncryptionMethod();
+
+ /**
+ * Set encryption method
+ *
+ * @see ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL
+ * @see ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_128
+ * @see ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_192
+ * @see ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_256
+ *
+ * @param int $encryptionMethod
+ * @return ZipEntry
+ * @throws ZipException
+ */
+ public function setEncryptionMethod($encryptionMethod);
+
+ /**
+ * Returns an string content of the given entry.
+ *
+ * @return null|string
+ * @throws ZipException
+ */
+ public function getEntryContent();
+
+ /**
+ * @param int $compressionLevel
+ * @return ZipEntry
+ */
+ public function setCompressionLevel($compressionLevel = ZipFileInterface::LEVEL_DEFAULT_COMPRESSION);
+
+ /**
+ * @return int
+ */
+ public function getCompressionLevel();
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Model/ZipEntryMatcher.php b/vendor/nelexa/zip/src/PhpZip/Model/ZipEntryMatcher.php
new file mode 100644
index 0000000..7ce6406
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Model/ZipEntryMatcher.php
@@ -0,0 +1,166 @@
+<?php
+
+namespace PhpZip\Model;
+
+/**
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class ZipEntryMatcher implements \Countable
+{
+ /**
+ * @var ZipModel
+ */
+ protected $zipModel;
+
+ /**
+ * @var array
+ */
+ protected $matches = [];
+
+ /**
+ * ZipEntryMatcher constructor.
+ * @param ZipModel $zipModel
+ */
+ public function __construct(ZipModel $zipModel)
+ {
+ $this->zipModel = $zipModel;
+ }
+
+ /**
+ * @param string|array $entries
+ * @return ZipEntryMatcher
+ */
+ public function add($entries)
+ {
+ $entries = (array)$entries;
+ $entries = array_map(function ($entry) {
+ return $entry instanceof ZipEntry ? $entry->getName() : $entry;
+ }, $entries);
+ $this->matches = array_unique(
+ array_merge(
+ $this->matches,
+ array_keys(
+ array_intersect_key(
+ $this->zipModel->getEntries(),
+ array_flip($entries)
+ )
+ )
+ )
+ );
+ return $this;
+ }
+
+ /**
+ * @param string $regexp
+ * @return ZipEntryMatcher
+ */
+ public function match($regexp)
+ {
+ array_walk($this->zipModel->getEntries(), function (
+ /** @noinspection PhpUnusedParameterInspection */
+ $entry,
+ $entryName
+ ) use ($regexp) {
+ if (preg_match($regexp, $entryName)) {
+ $this->matches[] = $entryName;
+ }
+ });
+ $this->matches = array_unique($this->matches);
+ return $this;
+ }
+
+ /**
+ * @return ZipEntryMatcher
+ */
+ public function all()
+ {
+ $this->matches = array_keys($this->zipModel->getEntries());
+ return $this;
+ }
+
+ /**
+ * Callable function for all select entries.
+ *
+ * Callable function signature:
+ * function(string $entryName){}
+ *
+ * @param callable $callable
+ */
+ public function invoke(callable $callable)
+ {
+ if (!empty($this->matches)) {
+ array_walk($this->matches, function ($entryName) use ($callable) {
+ call_user_func($callable, $entryName);
+ });
+ }
+ }
+
+ /**
+ * @return array
+ */
+ public function getMatches()
+ {
+ return $this->matches;
+ }
+
+ public function delete()
+ {
+ array_walk($this->matches, function ($entry) {
+ $this->zipModel->deleteEntry($entry);
+ });
+ $this->matches = [];
+ }
+
+ /**
+ * @param string|null $password
+ * @param int|null $encryptionMethod
+ */
+ public function setPassword($password, $encryptionMethod = null)
+ {
+ array_walk($this->matches, function ($entry) use ($password, $encryptionMethod) {
+ $entry = $this->zipModel->getEntry($entry);
+ if (!$entry->isDirectory()) {
+ $this->zipModel->getEntryForChanges($entry)->setPassword($password, $encryptionMethod);
+ }
+ });
+ }
+
+ /**
+ * @param int $encryptionMethod
+ */
+ public function setEncryptionMethod($encryptionMethod)
+ {
+ array_walk($this->matches, function ($entry) use ($encryptionMethod) {
+ $entry = $this->zipModel->getEntry($entry);
+ if (!$entry->isDirectory()) {
+ $this->zipModel->getEntryForChanges($entry)->setEncryptionMethod($encryptionMethod);
+ }
+ });
+ }
+
+ public function disableEncryption()
+ {
+ array_walk($this->matches, function ($entry) {
+ $entry = $this->zipModel->getEntry($entry);
+ if (!$entry->isDirectory()) {
+ $entry = $this->zipModel->getEntryForChanges($entry);
+ $entry->clearEncryption();
+ }
+ });
+ }
+
+ /**
+ * Count elements of an object
+ * @link http://php.net/manual/en/countable.count.php
+ * @return int The custom count as an integer.
+ * </p>
+ * <p>
+ * The return value is cast to an integer.
+ * @since 5.1.0
+ */
+ public function count()
+ {
+ return count($this->matches);
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Model/ZipInfo.php b/vendor/nelexa/zip/src/PhpZip/Model/ZipInfo.php
new file mode 100644
index 0000000..6434703
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Model/ZipInfo.php
@@ -0,0 +1,594 @@
+<?php
+
+namespace PhpZip\Model;
+
+use PhpZip\Extra\Fields\NtfsExtraField;
+use PhpZip\Extra\Fields\WinZipAesEntryExtraField;
+use PhpZip\Util\FilesUtil;
+use PhpZip\ZipFileInterface;
+
+/**
+ * Zip info
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class ZipInfo
+{
+ // made by constants
+ const MADE_BY_MS_DOS = 0;
+ const MADE_BY_AMIGA = 1;
+ const MADE_BY_OPEN_VMS = 2;
+ const MADE_BY_UNIX = 3;
+ const MADE_BY_VM_CMS = 4;
+ const MADE_BY_ATARI = 5;
+ const MADE_BY_OS_2 = 6;
+ const MADE_BY_MACINTOSH = 7;
+ const MADE_BY_Z_SYSTEM = 8;
+ const MADE_BY_CP_M = 9;
+ const MADE_BY_WINDOWS_NTFS = 10;
+ const MADE_BY_MVS = 11;
+ const MADE_BY_VSE = 12;
+ const MADE_BY_ACORN_RISC = 13;
+ const MADE_BY_VFAT = 14;
+ const MADE_BY_ALTERNATE_MVS = 15;
+ const MADE_BY_BEOS = 16;
+ const MADE_BY_TANDEM = 17;
+ const MADE_BY_OS_400 = 18;
+ const MADE_BY_OS_X = 19;
+ const MADE_BY_UNKNOWN = 20;
+
+ const UNX_IFMT = 0170000; /* Unix file type mask */
+ const UNX_IFREG = 0100000; /* Unix regular file */
+ const UNX_IFSOCK = 0140000; /* Unix socket (BSD, not SysV or Amiga) */
+ const UNX_IFLNK = 0120000; /* Unix symbolic link (not SysV, Amiga) */
+ const UNX_IFBLK = 0060000; /* Unix block special (not Amiga) */
+ const UNX_IFDIR = 0040000; /* Unix directory */
+ const UNX_IFCHR = 0020000; /* Unix character special (not Amiga) */
+ const UNX_IFIFO = 0010000; /* Unix fifo (BCC, not MSC or Amiga) */
+ const UNX_ISUID = 04000; /* Unix set user id on execution */
+ const UNX_ISGID = 02000; /* Unix set group id on execution */
+ const UNX_ISVTX = 01000; /* Unix directory permissions control */
+ const UNX_ENFMT = self::UNX_ISGID; /* Unix record locking enforcement flag */
+ const UNX_IRWXU = 00700; /* Unix read, write, execute: owner */
+ const UNX_IRUSR = 00400; /* Unix read permission: owner */
+ const UNX_IWUSR = 00200; /* Unix write permission: owner */
+ const UNX_IXUSR = 00100; /* Unix execute permission: owner */
+ const UNX_IRWXG = 00070; /* Unix read, write, execute: group */
+ const UNX_IRGRP = 00040; /* Unix read permission: group */
+ const UNX_IWGRP = 00020; /* Unix write permission: group */
+ const UNX_IXGRP = 00010; /* Unix execute permission: group */
+ const UNX_IRWXO = 00007; /* Unix read, write, execute: other */
+ const UNX_IROTH = 00004; /* Unix read permission: other */
+ const UNX_IWOTH = 00002; /* Unix write permission: other */
+ const UNX_IXOTH = 00001; /* Unix execute permission: other */
+
+ private static $valuesMadeBy = [
+ self::MADE_BY_MS_DOS => 'FAT',
+ self::MADE_BY_AMIGA => 'Amiga',
+ self::MADE_BY_OPEN_VMS => 'OpenVMS',
+ self::MADE_BY_UNIX => 'UNIX',
+ self::MADE_BY_VM_CMS => 'VM/CMS',
+ self::MADE_BY_ATARI => 'Atari ST',
+ self::MADE_BY_OS_2 => 'OS/2 H.P.F.S.',
+ self::MADE_BY_MACINTOSH => 'Macintosh',
+ self::MADE_BY_Z_SYSTEM => 'Z-System',
+ self::MADE_BY_CP_M => 'CP/M',
+ self::MADE_BY_WINDOWS_NTFS => 'Windows NTFS',
+ self::MADE_BY_MVS => 'MVS (OS/390 - Z/OS)',
+ self::MADE_BY_VSE => 'VSE',
+ self::MADE_BY_ACORN_RISC => 'Acorn Risc',
+ self::MADE_BY_VFAT => 'VFAT',
+ self::MADE_BY_ALTERNATE_MVS => 'Alternate MVS',
+ self::MADE_BY_BEOS => 'BeOS',
+ self::MADE_BY_TANDEM => 'Tandem',
+ self::MADE_BY_OS_400 => 'OS/400',
+ self::MADE_BY_OS_X => 'Mac OS X',
+ ];
+
+ private static $valuesCompressionMethod = [
+ ZipEntry::UNKNOWN => 'unknown',
+ ZipFileInterface::METHOD_STORED => 'no compression',
+ 1 => 'shrink',
+ 2 => 'reduce level 1',
+ 3 => 'reduce level 2',
+ 4 => 'reduce level 3',
+ 5 => 'reduce level 4',
+ 6 => 'implode',
+ 7 => 'reserved for Tokenizing compression algorithm',
+ ZipFileInterface::METHOD_DEFLATED => 'deflate',
+ 9 => 'deflate64',
+ 10 => 'PKWARE Data Compression Library Imploding (old IBM TERSE)',
+ 11 => 'reserved by PKWARE',
+ 12 => 'bzip2',
+ 13 => 'reserved by PKWARE',
+ 14 => 'LZMA (EFS)',
+ 15 => 'reserved by PKWARE',
+ 16 => 'reserved by PKWARE',
+ 17 => 'reserved by PKWARE',
+ 18 => 'IBM TERSE',
+ 19 => 'IBM LZ77 z Architecture (PFS)',
+ 97 => 'WavPack',
+ 98 => 'PPMd version I, Rev 1',
+ ZipEntry::METHOD_WINZIP_AES => 'WinZip AES',
+ ];
+
+ /**
+ * @var string
+ */
+ private $name;
+ /**
+ * @var bool
+ */
+ private $folder;
+ /**
+ * @var int
+ */
+ private $size;
+ /**
+ * @var int
+ */
+ private $compressedSize;
+ /**
+ * @var int
+ */
+ private $mtime;
+ /**
+ * @var int|null
+ */
+ private $ctime;
+ /**
+ * @var int|null
+ */
+ private $atime;
+ /**
+ * @var bool
+ */
+ private $encrypted;
+ /**
+ * @var string|null
+ */
+ private $comment;
+ /**
+ * @var int
+ */
+ private $crc;
+ /**
+ * @var string
+ */
+ private $methodName;
+ /**
+ * @var int
+ */
+ private $compressionMethod;
+ /**
+ * @var string
+ */
+ private $platform;
+ /**
+ * @var int
+ */
+ private $version;
+ /**
+ * @var string
+ */
+ private $attributes;
+ /**
+ * @var int|null
+ */
+ private $encryptionMethod;
+ /**
+ * @var int|null
+ */
+ private $compressionLevel;
+
+ /**
+ * ZipInfo constructor.
+ *
+ * @param ZipEntry $entry
+ */
+ public function __construct(ZipEntry $entry)
+ {
+ $mtime = $entry->getTime();
+ $atime = null;
+ $ctime = null;
+
+ $field = $entry->getExtraFieldsCollection()->get(NtfsExtraField::getHeaderId());
+ if (null !== $field && $field instanceof NtfsExtraField) {
+ /**
+ * @var NtfsExtraField $field
+ */
+ $atime = $field->getAtime();
+ $ctime = $field->getCtime();
+ $mtime = $field->getMtime();
+ }
+
+ $this->name = $entry->getName();
+ $this->folder = $entry->isDirectory();
+ $this->size = PHP_INT_SIZE === 4 ?
+ sprintf('%u', $entry->getSize()) :
+ $entry->getSize();
+ $this->compressedSize = PHP_INT_SIZE === 4 ?
+ sprintf('%u', $entry->getCompressedSize()) :
+ $entry->getCompressedSize();
+ $this->mtime = $mtime;
+ $this->ctime = $ctime;
+ $this->atime = $atime;
+ $this->encrypted = $entry->isEncrypted();
+ $this->encryptionMethod = $entry->getEncryptionMethod();
+ $this->comment = $entry->getComment();
+ $this->crc = $entry->getCrc();
+ $this->compressionMethod = self::getMethodId($entry);
+ $this->methodName = self::getEntryMethodName($entry);
+ $this->platform = self::getPlatformName($entry);
+ $this->version = $entry->getVersionNeededToExtract();
+ $this->compressionLevel = $entry->getCompressionLevel();
+
+ $attributes = str_repeat(" ", 12);
+ $externalAttributes = $entry->getExternalAttributes();
+ $externalAttributes = PHP_INT_SIZE === 4 ?
+ sprintf('%u', $externalAttributes) :
+ $externalAttributes;
+ $xattr = (($externalAttributes >> 16) & 0xFFFF);
+ switch ($entry->getPlatform()) {
+ case self::MADE_BY_MS_DOS:
+ // no break
+ /** @noinspection PhpMissingBreakStatementInspection */
+ case self::MADE_BY_WINDOWS_NTFS:
+ if ($entry->getPlatform() != self::MADE_BY_MS_DOS ||
+ ($xattr & 0700) !=
+ (0400 |
+ (!($externalAttributes & 1) << 7) |
+ (($externalAttributes & 0x10) << 2))
+ ) {
+ $xattr = $externalAttributes & 0xFF;
+ $attributes = ".r.-... ";
+ $attributes[2] = ($xattr & 0x01) ? '-' : 'w';
+ $attributes[5] = ($xattr & 0x02) ? 'h' : '-';
+ $attributes[6] = ($xattr & 0x04) ? 's' : '-';
+ $attributes[4] = ($xattr & 0x20) ? 'a' : '-';
+ if ($xattr & 0x10) {
+ $attributes[0] = 'd';
+ $attributes[3] = 'x';
+ } else {
+ $attributes[0] = '-';
+ }
+ if ($xattr & 0x08) {
+ $attributes[0] = 'V';
+ } else {
+ $ext = strtolower(pathinfo($entry->getName(), PATHINFO_EXTENSION));
+ if (in_array($ext, ["com", "exe", "btm", "cmd", "bat"])) {
+ $attributes[3] = 'x';
+ }
+ }
+ break;
+ } /* else: fall through! */
+
+ // no break
+ default: /* assume Unix-like */
+ switch ($xattr & self::UNX_IFMT) {
+ case self::UNX_IFDIR:
+ $attributes[0] = 'd';
+ break;
+ case self::UNX_IFREG:
+ $attributes[0] = '-';
+ break;
+ case self::UNX_IFLNK:
+ $attributes[0] = 'l';
+ break;
+ case self::UNX_IFBLK:
+ $attributes[0] = 'b';
+ break;
+ case self::UNX_IFCHR:
+ $attributes[0] = 'c';
+ break;
+ case self::UNX_IFIFO:
+ $attributes[0] = 'p';
+ break;
+ case self::UNX_IFSOCK:
+ $attributes[0] = 's';
+ break;
+ default:
+ $attributes[0] = '?';
+ break;
+ }
+ $attributes[1] = ($xattr & self::UNX_IRUSR) ? 'r' : '-';
+ $attributes[4] = ($xattr & self::UNX_IRGRP) ? 'r' : '-';
+ $attributes[7] = ($xattr & self::UNX_IROTH) ? 'r' : '-';
+ $attributes[2] = ($xattr & self::UNX_IWUSR) ? 'w' : '-';
+ $attributes[5] = ($xattr & self::UNX_IWGRP) ? 'w' : '-';
+ $attributes[8] = ($xattr & self::UNX_IWOTH) ? 'w' : '-';
+
+ if ($xattr & self::UNX_IXUSR) {
+ $attributes[3] = ($xattr & self::UNX_ISUID) ? 's' : 'x';
+ } else {
+ $attributes[3] = ($xattr & self::UNX_ISUID) ? 'S' : '-';
+ } /* S==undefined */
+ if ($xattr & self::UNX_IXGRP) {
+ $attributes[6] = ($xattr & self::UNX_ISGID) ? 's' : 'x';
+ } /* == UNX_ENFMT */
+ else {
+ $attributes[6] = ($xattr & self::UNX_ISGID) ? 'S' : '-';
+ } /* SunOS 4.1.x */
+ if ($xattr & self::UNX_IXOTH) {
+ $attributes[9] = ($xattr & self::UNX_ISVTX) ? 't' : 'x';
+ } /* "sticky bit" */
+ else {
+ $attributes[9] = ($xattr & self::UNX_ISVTX) ? 'T' : '-';
+ } /* T==undefined */
+ }
+ $this->attributes = trim($attributes);
+ }
+
+ /**
+ * @param ZipEntry $entry
+ * @return int
+ */
+ private static function getMethodId(ZipEntry $entry)
+ {
+ $method = $entry->getMethod();
+ if ($entry->isEncrypted()) {
+ if ($entry->getMethod() === ZipEntry::METHOD_WINZIP_AES) {
+ $field = $entry->getExtraFieldsCollection()->get(WinZipAesEntryExtraField::getHeaderId());
+ if (null !== $field) {
+ /**
+ * @var WinZipAesEntryExtraField $field
+ */
+ $method = $field->getMethod();
+ }
+ }
+ }
+ return $method;
+ }
+
+ /**
+ * @param ZipEntry $entry
+ * @return string
+ */
+ private static function getEntryMethodName(ZipEntry $entry)
+ {
+ $return = '';
+ if ($entry->isEncrypted()) {
+ if ($entry->getMethod() === ZipEntry::METHOD_WINZIP_AES) {
+ $return = ucfirst(self::$valuesCompressionMethod[$entry->getMethod()]);
+ $field = $entry->getExtraFieldsCollection()->get(WinZipAesEntryExtraField::getHeaderId());
+ if (null !== $field) {
+ /**
+ * @var WinZipAesEntryExtraField $field
+ */
+ $return .= '-' . $field->getKeyStrength();
+ if (isset(self::$valuesCompressionMethod[$field->getMethod()])) {
+ $return .= ' ' . ucfirst(self::$valuesCompressionMethod[$field->getMethod()]);
+ }
+ }
+ } else {
+ $return .= 'ZipCrypto';
+ if (isset(self::$valuesCompressionMethod[$entry->getMethod()])) {
+ $return .= ' ' . ucfirst(self::$valuesCompressionMethod[$entry->getMethod()]);
+ }
+ }
+ } elseif (isset(self::$valuesCompressionMethod[$entry->getMethod()])) {
+ $return = ucfirst(self::$valuesCompressionMethod[$entry->getMethod()]);
+ } else {
+ $return = 'unknown';
+ }
+ return $return;
+ }
+
+ /**
+ * @param ZipEntry $entry
+ * @return string
+ */
+ public static function getPlatformName(ZipEntry $entry)
+ {
+ if (isset(self::$valuesMadeBy[$entry->getPlatform()])) {
+ return self::$valuesMadeBy[$entry->getPlatform()];
+ } else {
+ return 'unknown';
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * @return string
+ * @deprecated use \PhpZip\Model\ZipInfo::getName()
+ */
+ public function getPath()
+ {
+ return $this->getName();
+ }
+
+ /**
+ * @return boolean
+ */
+ public function isFolder()
+ {
+ return $this->folder;
+ }
+
+ /**
+ * @return int
+ */
+ public function getSize()
+ {
+ return $this->size;
+ }
+
+ /**
+ * @return int
+ */
+ public function getCompressedSize()
+ {
+ return $this->compressedSize;
+ }
+
+ /**
+ * @return int
+ */
+ public function getMtime()
+ {
+ return $this->mtime;
+ }
+
+ /**
+ * @return int|null
+ */
+ public function getCtime()
+ {
+ return $this->ctime;
+ }
+
+ /**
+ * @return int|null
+ */
+ public function getAtime()
+ {
+ return $this->atime;
+ }
+
+ /**
+ * @return string
+ */
+ public function getAttributes()
+ {
+ return $this->attributes;
+ }
+
+ /**
+ * @return boolean
+ */
+ public function isEncrypted()
+ {
+ return $this->encrypted;
+ }
+
+ /**
+ * @return null|string
+ */
+ public function getComment()
+ {
+ return $this->comment;
+ }
+
+ /**
+ * @return int
+ */
+ public function getCrc()
+ {
+ return $this->crc;
+ }
+
+ /**
+ * @return string
+ * @deprecated use \PhpZip\Model\ZipInfo::getMethodName()
+ */
+ public function getMethod()
+ {
+ return $this->getMethodName();
+ }
+
+ /**
+ * @return string
+ */
+ public function getMethodName()
+ {
+ return $this->methodName;
+ }
+
+ /**
+ * @return string
+ */
+ public function getPlatform()
+ {
+ return $this->platform;
+ }
+
+ /**
+ * @return int
+ */
+ public function getVersion()
+ {
+ return $this->version;
+ }
+
+ /**
+ * @return int|null
+ */
+ public function getEncryptionMethod()
+ {
+ return $this->encryptionMethod;
+ }
+
+ /**
+ * @return int|null
+ */
+ public function getCompressionLevel()
+ {
+ return $this->compressionLevel;
+ }
+
+ /**
+ * @return int
+ */
+ public function getCompressionMethod()
+ {
+ return $this->compressionMethod;
+ }
+
+ /**
+ * @return array
+ */
+ public function toArray()
+ {
+ return [
+ 'name' => $this->getName(),
+ 'path' => $this->getName(), // deprecated
+ 'folder' => $this->isFolder(),
+ 'size' => $this->getSize(),
+ 'compressed_size' => $this->getCompressedSize(),
+ 'modified' => $this->getMtime(),
+ 'created' => $this->getCtime(),
+ 'accessed' => $this->getAtime(),
+ 'attributes' => $this->getAttributes(),
+ 'encrypted' => $this->isEncrypted(),
+ 'encryption_method' => $this->getEncryptionMethod(),
+ 'comment' => $this->getComment(),
+ 'crc' => $this->getCrc(),
+ 'method' => $this->getMethodName(), // deprecated
+ 'method_name' => $this->getMethodName(),
+ 'compression_method' => $this->getCompressionMethod(),
+ 'platform' => $this->getPlatform(),
+ 'version' => $this->getVersion()
+ ];
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return __CLASS__ . ' {'
+ . 'Name="' . $this->getName() . '", '
+ . ($this->isFolder() ? 'Folder, ' : '')
+ . 'Size="' . FilesUtil::humanSize($this->getSize()) . '"'
+ . ', Compressed size="' . FilesUtil::humanSize($this->getCompressedSize()) . '"'
+ . ', Modified time="' . date(DATE_W3C, $this->getMtime()) . '", '
+ . ($this->getCtime() !== null ? 'Created time="' . date(DATE_W3C, $this->getCtime()) . '", ' : '')
+ . ($this->getAtime() !== null ? 'Accessed time="' . date(DATE_W3C, $this->getAtime()) . '", ' : '')
+ . ($this->isEncrypted() ? 'Encrypted, ' : '')
+ . (!empty($this->comment) ? 'Comment="' . $this->getComment() . '", ' : '')
+ . (!empty($this->crc) ? 'Crc=0x' . dechex($this->getCrc()) . ', ' : '')
+ . 'Method name="' . $this->getMethodName() . '", '
+ . 'Attributes="' . $this->getAttributes() . '", '
+ . 'Platform="' . $this->getPlatform() . '", '
+ . 'Version=' . $this->getVersion()
+ . '}';
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Model/ZipModel.php b/vendor/nelexa/zip/src/PhpZip/Model/ZipModel.php
new file mode 100644
index 0000000..ac62b17
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Model/ZipModel.php
@@ -0,0 +1,344 @@
+<?php
+
+namespace PhpZip\Model;
+
+use PhpZip\Exception\InvalidArgumentException;
+use PhpZip\Exception\ZipException;
+use PhpZip\Exception\ZipNotFoundEntry;
+use PhpZip\Model\Entry\ZipChangesEntry;
+use PhpZip\Model\Entry\ZipSourceEntry;
+use PhpZip\ZipFileInterface;
+
+/**
+ * Zip Model
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class ZipModel implements \Countable
+{
+ /**
+ * @var ZipSourceEntry[]
+ */
+ protected $inputEntries = [];
+ /**
+ * @var ZipEntry[]
+ */
+ protected $outEntries = [];
+ /**
+ * @var string|null
+ */
+ protected $archiveComment;
+ /**
+ * @var string|null
+ */
+ protected $archiveCommentChanges;
+ /**
+ * @var bool
+ */
+ protected $archiveCommentChanged = false;
+ /**
+ * @var int|null
+ */
+ protected $zipAlign;
+ /**
+ * @var bool
+ */
+ private $zip64;
+
+ /**
+ * @param ZipSourceEntry[] $entries
+ * @param EndOfCentralDirectory $endOfCentralDirectory
+ * @return ZipModel
+ */
+ public static function newSourceModel(array $entries, EndOfCentralDirectory $endOfCentralDirectory)
+ {
+ $model = new self;
+ $model->inputEntries = $entries;
+ $model->outEntries = $entries;
+ $model->archiveComment = $endOfCentralDirectory->getComment();
+ $model->zip64 = $endOfCentralDirectory->isZip64();
+ return $model;
+ }
+
+ /**
+ * @return null|string
+ */
+ public function getArchiveComment()
+ {
+ if ($this->archiveCommentChanged) {
+ return $this->archiveCommentChanges;
+ }
+ return $this->archiveComment;
+ }
+
+ /**
+ * @param string $comment
+ * @throws InvalidArgumentException
+ */
+ public function setArchiveComment($comment)
+ {
+ if (null !== $comment && strlen($comment) !== 0) {
+ $comment = (string)$comment;
+ $length = strlen($comment);
+ if (0x0000 > $length || $length > 0xffff) {
+ throw new InvalidArgumentException('Length comment out of range');
+ }
+ }
+ if ($comment !== $this->archiveComment) {
+ $this->archiveCommentChanges = $comment;
+ $this->archiveCommentChanged = true;
+ } else {
+ $this->archiveCommentChanged = false;
+ }
+ }
+
+ /**
+ * Specify a password for extracting files.
+ *
+ * @param null|string $password
+ */
+ public function setReadPassword($password)
+ {
+ foreach ($this->inputEntries as $entry) {
+ if ($entry->isEncrypted()) {
+ $entry->setPassword($password);
+ }
+ }
+ }
+
+ /**
+ * @param string $entryName
+ * @param string $password
+ * @throws ZipNotFoundEntry
+ */
+ public function setReadPasswordEntry($entryName, $password)
+ {
+ if (!isset($this->inputEntries[$entryName])) {
+ throw new ZipNotFoundEntry('Not found entry ' . $entryName);
+ }
+ if ($this->inputEntries[$entryName]->isEncrypted()) {
+ $this->inputEntries[$entryName]->setPassword($password);
+ }
+ }
+
+ /**
+ * @return int|null
+ */
+ public function getZipAlign()
+ {
+ return $this->zipAlign;
+ }
+
+ /**
+ * @param int|null $zipAlign
+ */
+ public function setZipAlign($zipAlign)
+ {
+ $this->zipAlign = $zipAlign === null ? null : (int)$zipAlign;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isZipAlign()
+ {
+ return $this->zipAlign != null;
+ }
+
+ /**
+ * @param null|string $writePassword
+ */
+ public function setWritePassword($writePassword)
+ {
+ $this->matcher()->all()->setPassword($writePassword);
+ }
+
+ /**
+ * Remove password
+ */
+ public function removePassword()
+ {
+ $this->matcher()->all()->setPassword(null);
+ }
+
+ /**
+ * @param string|ZipEntry $entryName
+ */
+ public function removePasswordEntry($entryName)
+ {
+ $this->matcher()->add($entryName)->setPassword(null);
+ }
+
+ /**
+ * @return bool
+ */
+ public function isArchiveCommentChanged()
+ {
+ return $this->archiveCommentChanged;
+ }
+
+ /**
+ * @param string|ZipEntry $old
+ * @param string|ZipEntry $new
+ * @throws InvalidArgumentException
+ * @throws ZipNotFoundEntry
+ */
+ public function renameEntry($old, $new)
+ {
+ $old = $old instanceof ZipEntry ? $old->getName() : (string)$old;
+ $new = $new instanceof ZipEntry ? $new->getName() : (string)$new;
+
+ if (isset($this->outEntries[$new])) {
+ throw new InvalidArgumentException("New entry name " . $new . ' is exists.');
+ }
+
+ $entry = $this->getEntryForChanges($old);
+ $entry->setName($new);
+ $this->deleteEntry($old);
+ $this->addEntry($entry);
+ }
+
+ /**
+ * @param string|ZipEntry $entry
+ * @return ZipChangesEntry|ZipEntry
+ */
+ public function getEntryForChanges($entry)
+ {
+ $entry = $this->getEntry($entry);
+ if ($entry instanceof ZipSourceEntry) {
+ $entry = new ZipChangesEntry($entry);
+ $this->addEntry($entry);
+ }
+ return $entry;
+ }
+
+ /**
+ * @param string|ZipEntry $entryName
+ * @return ZipEntry
+ * @throws ZipNotFoundEntry
+ */
+ public function getEntry($entryName)
+ {
+ $entryName = $entryName instanceof ZipEntry ? $entryName->getName() : (string)$entryName;
+ if (isset($this->outEntries[$entryName])) {
+ return $this->outEntries[$entryName];
+ }
+ throw new ZipNotFoundEntry('Zip entry "' . $entryName . '" not found');
+ }
+
+ /**
+ * @param string|ZipEntry $entry
+ * @return bool
+ */
+ public function deleteEntry($entry)
+ {
+ $entry = $entry instanceof ZipEntry ? $entry->getName() : (string)$entry;
+ if (isset($this->outEntries[$entry])) {
+ unset($this->outEntries[$entry]);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @param ZipEntry $entry
+ */
+ public function addEntry(ZipEntry $entry)
+ {
+ $this->outEntries[$entry->getName()] = $entry;
+ }
+
+ /**
+ * Get all entries with changes.
+ *
+ * @return ZipEntry[]
+ */
+ public function &getEntries()
+ {
+ return $this->outEntries;
+ }
+
+ /**
+ * @param string|ZipEntry $entryName
+ * @return bool
+ */
+ public function hasEntry($entryName)
+ {
+ $entryName = $entryName instanceof ZipEntry ? $entryName->getName() : (string)$entryName;
+ return isset($this->outEntries[$entryName]);
+ }
+
+ /**
+ * Delete all entries.
+ */
+ public function deleteAll()
+ {
+ $this->outEntries = [];
+ }
+
+ /**
+ * Count elements of an object
+ * @link http://php.net/manual/en/countable.count.php
+ * @return int The custom count as an integer.
+ * </p>
+ * <p>
+ * The return value is cast to an integer.
+ * @since 5.1.0
+ */
+ public function count()
+ {
+ return sizeof($this->outEntries);
+ }
+
+ /**
+ * Undo all changes done in the archive
+ */
+ public function unchangeAll()
+ {
+ $this->outEntries = $this->inputEntries;
+ $this->unchangeArchiveComment();
+ }
+
+ /**
+ * Undo change archive comment
+ */
+ public function unchangeArchiveComment()
+ {
+ $this->archiveCommentChanges = null;
+ $this->archiveCommentChanged = false;
+ }
+
+ /**
+ * Revert all changes done to an entry with the given name.
+ *
+ * @param string|ZipEntry $entry Entry name or ZipEntry
+ * @return bool
+ */
+ public function unchangeEntry($entry)
+ {
+ $entry = $entry instanceof ZipEntry ? $entry->getName() : (string)$entry;
+ if (isset($this->outEntries[$entry]) && isset($this->inputEntries[$entry])) {
+ $this->outEntries[$entry] = $this->inputEntries[$entry];
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @param int $encryptionMethod
+ * @throws ZipException
+ */
+ public function setEncryptionMethod($encryptionMethod = ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_256)
+ {
+ $this->matcher()->all()->setEncryptionMethod($encryptionMethod);
+ }
+
+ /**
+ * @return ZipEntryMatcher
+ */
+ public function matcher()
+ {
+ return new ZipEntryMatcher($this);
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Stream/ResponseStream.php b/vendor/nelexa/zip/src/PhpZip/Stream/ResponseStream.php
new file mode 100644
index 0000000..172de1e
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Stream/ResponseStream.php
@@ -0,0 +1,298 @@
+<?php
+
+namespace PhpZip\Stream;
+
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Implement PSR Message Stream
+ */
+class ResponseStream implements StreamInterface
+{
+ /**
+ * @var array
+ */
+ private static $readWriteHash = [
+ 'read' => [
+ 'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true,
+ 'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true,
+ 'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true,
+ 'x+t' => true, 'c+t' => true, 'a+' => true,
+ ],
+ 'write' => [
+ 'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true,
+ 'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true,
+ 'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true,
+ 'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true,
+ ],
+ ];
+ /**
+ * @var resource
+ */
+ private $stream;
+ /**
+ * @var int
+ */
+ private $size;
+ /**
+ * @var bool
+ */
+ private $seekable;
+ /**
+ * @var bool
+ */
+ private $readable;
+ /**
+ * @var bool
+ */
+ private $writable;
+ /**
+ * @var array|mixed|null
+ */
+ private $uri;
+
+ /**
+ * @param resource $stream Stream resource to wrap.
+ * @throws \InvalidArgumentException if the stream is not a stream resource
+ */
+ public function __construct($stream)
+ {
+ if (!is_resource($stream)) {
+ throw new \InvalidArgumentException('Stream must be a resource');
+ }
+ $this->stream = $stream;
+ $meta = stream_get_meta_data($this->stream);
+ $this->seekable = $meta['seekable'];
+ $this->readable = isset(self::$readWriteHash['read'][$meta['mode']]);
+ $this->writable = isset(self::$readWriteHash['write'][$meta['mode']]);
+ $this->uri = $this->getMetadata('uri');
+ }
+
+ /**
+ * Get stream metadata as an associative array or retrieve a specific key.
+ *
+ * The keys returned are identical to the keys returned from PHP's
+ * stream_get_meta_data() function.
+ *
+ * @link http://php.net/manual/en/function.stream-get-meta-data.php
+ * @param string $key Specific metadata to retrieve.
+ * @return array|mixed|null Returns an associative array if no key is
+ * provided. Returns a specific key value if a key is provided and the
+ * value is found, or null if the key is not found.
+ */
+ public function getMetadata($key = null)
+ {
+ if (!$this->stream) {
+ return $key ? null : [];
+ }
+ $meta = stream_get_meta_data($this->stream);
+ return isset($meta[$key]) ? $meta[$key] : null;
+ }
+
+ /**
+ * Reads all data from the stream into a string, from the beginning to end.
+ *
+ * This method MUST attempt to seek to the beginning of the stream before
+ * reading data and read the stream until the end is reached.
+ *
+ * Warning: This could attempt to load a large amount of data into memory.
+ *
+ * This method MUST NOT raise an exception in order to conform with PHP's
+ * string casting operations.
+ *
+ * @see http://php.net/manual/en/language.oop5.magic.php#object.tostring
+ * @return string
+ */
+ public function __toString()
+ {
+ if (!$this->stream) {
+ return '';
+ }
+ $this->rewind();
+ return (string)stream_get_contents($this->stream);
+ }
+
+ /**
+ * Seek to the beginning of the stream.
+ *
+ * If the stream is not seekable, this method will raise an exception;
+ * otherwise, it will perform a seek(0).
+ *
+ * @see seek()
+ * @link http://www.php.net/manual/en/function.fseek.php
+ * @throws \RuntimeException on failure.
+ */
+ public function rewind()
+ {
+ $this->seekable && rewind($this->stream);
+ }
+
+ /**
+ * Get the size of the stream if known.
+ *
+ * @return int|null Returns the size in bytes if known, or null if unknown.
+ */
+ public function getSize()
+ {
+ if ($this->size !== null) {
+ return $this->size;
+ }
+ if (!$this->stream) {
+ return null;
+ }
+ // Clear the stat cache if the stream has a URI
+ if ($this->uri) {
+ clearstatcache(true, $this->uri);
+ }
+ $stats = fstat($this->stream);
+ if (isset($stats['size'])) {
+ $this->size = $stats['size'];
+ return $this->size;
+ }
+ return null;
+ }
+
+ /**
+ * Returns the current position of the file read/write pointer
+ *
+ * @return int Position of the file pointer
+ * @throws \RuntimeException on error.
+ */
+ public function tell()
+ {
+ return $this->stream ? ftell($this->stream) : false;
+ }
+
+ /**
+ * Returns true if the stream is at the end of the stream.
+ *
+ * @return bool
+ */
+ public function eof()
+ {
+ return !$this->stream || feof($this->stream);
+ }
+
+ /**
+ * Returns whether or not the stream is seekable.
+ *
+ * @return bool
+ */
+ public function isSeekable()
+ {
+ return $this->seekable;
+ }
+
+ /**
+ * Seek to a position in the stream.
+ *
+ * @link http://www.php.net/manual/en/function.fseek.php
+ * @param int $offset Stream offset
+ * @param int $whence Specifies how the cursor position will be calculated
+ * based on the seek offset. Valid values are identical to the built-in
+ * PHP $whence values for `fseek()`. SEEK_SET: Set position equal to
+ * offset bytes SEEK_CUR: Set position to current location plus offset
+ * SEEK_END: Set position to end-of-stream plus offset.
+ * @throws \RuntimeException on failure.
+ */
+ public function seek($offset, $whence = SEEK_SET)
+ {
+ $this->seekable && fseek($this->stream, $offset, $whence);
+ }
+
+ /**
+ * Returns whether or not the stream is writable.
+ *
+ * @return bool
+ */
+ public function isWritable()
+ {
+ return $this->writable;
+ }
+
+ /**
+ * Write data to the stream.
+ *
+ * @param string $string The string that is to be written.
+ * @return int Returns the number of bytes written to the stream.
+ * @throws \RuntimeException on failure.
+ */
+ public function write($string)
+ {
+ $this->size = null;
+ return $this->writable ? fwrite($this->stream, $string) : false;
+ }
+
+ /**
+ * Returns whether or not the stream is readable.
+ *
+ * @return bool
+ */
+ public function isReadable()
+ {
+ return $this->readable;
+ }
+
+ /**
+ * Read data from the stream.
+ *
+ * @param int $length Read up to $length bytes from the object and return
+ * them. Fewer than $length bytes may be returned if underlying stream
+ * call returns fewer bytes.
+ * @return string Returns the data read from the stream, or an empty string
+ * if no bytes are available.
+ * @throws \RuntimeException if an error occurs.
+ */
+ public function read($length)
+ {
+ return $this->readable ? fread($this->stream, $length) : "";
+ }
+
+ /**
+ * Returns the remaining contents in a string
+ *
+ * @return string
+ * @throws \RuntimeException if unable to read or an error occurs while
+ * reading.
+ */
+ public function getContents()
+ {
+ return $this->stream ? stream_get_contents($this->stream) : '';
+ }
+
+ /**
+ * Closes the stream when the destructed
+ */
+ public function __destruct()
+ {
+ $this->close();
+ }
+
+ /**
+ * Closes the stream and any underlying resources.
+ *
+ * @return void
+ */
+ public function close()
+ {
+ if (is_resource($this->stream)) {
+ fclose($this->stream);
+ }
+ $this->detach();
+ }
+
+ /**
+ * Separates any underlying resources from the stream.
+ *
+ * After the stream has been detached, the stream is in an unusable state.
+ *
+ * @return resource|null Underlying PHP stream, if any
+ */
+ public function detach()
+ {
+ $result = $this->stream;
+ $this->stream = $this->size = $this->uri = null;
+ $this->readable = $this->writable = $this->seekable = false;
+ return $result;
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Stream/ZipInputStream.php b/vendor/nelexa/zip/src/PhpZip/Stream/ZipInputStream.php
new file mode 100644
index 0000000..8c8adf5
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Stream/ZipInputStream.php
@@ -0,0 +1,603 @@
+<?php
+
+namespace PhpZip\Stream;
+
+use PhpZip\Crypto\TraditionalPkwareEncryptionEngine;
+use PhpZip\Crypto\WinZipAesEngine;
+use PhpZip\Exception\Crc32Exception;
+use PhpZip\Exception\InvalidArgumentException;
+use PhpZip\Exception\RuntimeException;
+use PhpZip\Exception\ZipCryptoException;
+use PhpZip\Exception\ZipException;
+use PhpZip\Exception\ZipUnsupportMethod;
+use PhpZip\Extra\ExtraFieldsCollection;
+use PhpZip\Extra\ExtraFieldsFactory;
+use PhpZip\Extra\Fields\ApkAlignmentExtraField;
+use PhpZip\Extra\Fields\WinZipAesEntryExtraField;
+use PhpZip\Mapper\OffsetPositionMapper;
+use PhpZip\Mapper\PositionMapper;
+use PhpZip\Model\EndOfCentralDirectory;
+use PhpZip\Model\Entry\ZipSourceEntry;
+use PhpZip\Model\ZipEntry;
+use PhpZip\Model\ZipModel;
+use PhpZip\Util\PackUtil;
+use PhpZip\Util\StringUtil;
+use PhpZip\ZipFileInterface;
+
+/**
+ * Read zip file
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class ZipInputStream implements ZipInputStreamInterface
+{
+ /**
+ * @var resource
+ */
+ protected $in;
+ /**
+ * @var PositionMapper
+ */
+ protected $mapper;
+ /**
+ * @var int The number of bytes in the preamble of this ZIP file.
+ */
+ protected $preamble = 0;
+ /**
+ * @var int The number of bytes in the postamble of this ZIP file.
+ */
+ protected $postamble = 0;
+ /**
+ * @var ZipModel
+ */
+ protected $zipModel;
+
+ /**
+ * ZipInputStream constructor.
+ * @param resource $in
+ * @throws RuntimeException
+ */
+ public function __construct($in)
+ {
+ if (!is_resource($in)) {
+ throw new RuntimeException('$in must be resource');
+ }
+ $this->in = $in;
+ $this->mapper = new PositionMapper();
+ }
+
+ /**
+ * @return ZipModel
+ */
+ public function readZip()
+ {
+ $this->checkZipFileSignature();
+ $endOfCentralDirectory = $this->readEndOfCentralDirectory();
+ $entries = $this->mountCentralDirectory($endOfCentralDirectory);
+ $this->zipModel = ZipModel::newSourceModel($entries, $endOfCentralDirectory);
+ return $this->zipModel;
+ }
+
+ /**
+ * Check zip file signature
+ *
+ * @throws ZipException if this not .ZIP file.
+ */
+ protected function checkZipFileSignature()
+ {
+ rewind($this->in);
+ // Constraint: A ZIP file must start with a Local File Header
+ // or a (ZIP64) End Of Central Directory Record if it's empty.
+ $signatureBytes = fread($this->in, 4);
+ if (strlen($signatureBytes) < 4) {
+ throw new ZipException("Invalid zip file.");
+ }
+ $signature = unpack('V', $signatureBytes)[1];
+ if (
+ ZipEntry::LOCAL_FILE_HEADER_SIG !== $signature
+ && EndOfCentralDirectory::ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIG !== $signature
+ && EndOfCentralDirectory::END_OF_CENTRAL_DIRECTORY_RECORD_SIG !== $signature
+ ) {
+ throw new ZipException("Expected Local File Header or (ZIP64) End Of Central Directory Record! Signature: " . $signature);
+ }
+ }
+
+ /**
+ * @return EndOfCentralDirectory
+ * @throws ZipException
+ */
+ protected function readEndOfCentralDirectory()
+ {
+ $comment = null;
+ // Search for End of central directory record.
+ $stats = fstat($this->in);
+ $size = $stats['size'];
+ $max = $size - EndOfCentralDirectory::END_OF_CENTRAL_DIRECTORY_RECORD_MIN_LEN;
+ $min = $max >= 0xffff ? $max - 0xffff : 0;
+ for ($endOfCentralDirRecordPos = $max; $endOfCentralDirRecordPos >= $min; $endOfCentralDirRecordPos--) {
+ fseek($this->in, $endOfCentralDirRecordPos, SEEK_SET);
+ // end of central dir signature 4 bytes (0x06054b50)
+ if (EndOfCentralDirectory::END_OF_CENTRAL_DIRECTORY_RECORD_SIG !== unpack('V', fread($this->in, 4))[1]) {
+ continue;
+ }
+
+ // number of this disk - 2 bytes
+ // number of the disk with the start of the
+ // central directory - 2 bytes
+ // total number of entries in the central
+ // directory on this disk - 2 bytes
+ // total number of entries in the central
+ // directory - 2 bytes
+ // size of the central directory - 4 bytes
+ // offset of start of central directory with
+ // respect to the starting disk number - 4 bytes
+ // ZIP file comment length - 2 bytes
+ $data = unpack(
+ 'vdiskNo/vcdDiskNo/vcdEntriesDisk/vcdEntries/VcdSize/VcdPos/vcommentLength',
+ fread($this->in, 18)
+ );
+
+ if (0 !== $data['diskNo'] || 0 !== $data['cdDiskNo'] || $data['cdEntriesDisk'] !== $data['cdEntries']) {
+ throw new ZipException(
+ "ZIP file spanning/splitting is not supported!"
+ );
+ }
+ // .ZIP file comment (variable size)
+ if (0 < $data['commentLength']) {
+ $comment = fread($this->in, $data['commentLength']);
+ }
+ $this->preamble = $endOfCentralDirRecordPos;
+ $this->postamble = $size - ftell($this->in);
+
+ // Check for ZIP64 End Of Central Directory Locator.
+ $endOfCentralDirLocatorPos = $endOfCentralDirRecordPos - EndOfCentralDirectory::ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_LEN;
+
+ fseek($this->in, $endOfCentralDirLocatorPos, SEEK_SET);
+ // zip64 end of central dir locator
+ // signature 4 bytes (0x07064b50)
+ if (
+ 0 > $endOfCentralDirLocatorPos ||
+ ftell($this->in) === $size ||
+ EndOfCentralDirectory::ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIG !== unpack('V', fread($this->in, 4))[1]
+ ) {
+ // Seek and check first CFH, probably requiring an offset mapper.
+ $offset = $endOfCentralDirRecordPos - $data['cdSize'];
+ fseek($this->in, $offset, SEEK_SET);
+ $offset -= $data['cdPos'];
+ if (0 !== $offset) {
+ $this->mapper = new OffsetPositionMapper($offset);
+ }
+ $entryCount = $data['cdEntries'];
+ return new EndOfCentralDirectory($entryCount, $comment);
+ }
+
+ // number of the disk with the
+ // start of the zip64 end of
+ // central directory 4 bytes
+ $zip64EndOfCentralDirectoryRecordDisk = unpack('V', fread($this->in, 4))[1];
+ // relative offset of the zip64
+ // end of central directory record 8 bytes
+ $zip64EndOfCentralDirectoryRecordPos = PackUtil::unpackLongLE(fread($this->in, 8));
+ // total number of disks 4 bytes
+ $totalDisks = unpack('V', fread($this->in, 4))[1];
+ if (0 !== $zip64EndOfCentralDirectoryRecordDisk || 1 !== $totalDisks) {
+ throw new ZipException("ZIP file spanning/splitting is not supported!");
+ }
+ fseek($this->in, $zip64EndOfCentralDirectoryRecordPos, SEEK_SET);
+ // zip64 end of central dir
+ // signature 4 bytes (0x06064b50)
+ $zip64EndOfCentralDirSig = unpack('V', fread($this->in, 4))[1];
+ if (EndOfCentralDirectory::ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIG !== $zip64EndOfCentralDirSig) {
+ throw new ZipException("Expected ZIP64 End Of Central Directory Record!");
+ }
+ // size of zip64 end of central
+ // directory record 8 bytes
+ // version made by 2 bytes
+ // version needed to extract 2 bytes
+ fseek($this->in, 12, SEEK_CUR);
+ // number of this disk 4 bytes
+ $diskNo = unpack('V', fread($this->in, 4))[1];
+ // number of the disk with the
+ // start of the central directory 4 bytes
+ $cdDiskNo = unpack('V', fread($this->in, 4))[1];
+ // total number of entries in the
+ // central directory on this disk 8 bytes
+ $cdEntriesDisk = PackUtil::unpackLongLE(fread($this->in, 8));
+ // total number of entries in the
+ // central directory 8 bytes
+ $cdEntries = PackUtil::unpackLongLE(fread($this->in, 8));
+ if (0 !== $diskNo || 0 !== $cdDiskNo || $cdEntriesDisk !== $cdEntries) {
+ throw new ZipException("ZIP file spanning/splitting is not supported!");
+ }
+ if ($cdEntries < 0 || 0x7fffffff < $cdEntries) {
+ throw new ZipException("Total Number Of Entries In The Central Directory out of range!");
+ }
+ // size of the central directory 8 bytes
+ fseek($this->in, 8, SEEK_CUR);
+ // offset of start of central
+ // directory with respect to
+ // the starting disk number 8 bytes
+ $cdPos = PackUtil::unpackLongLE(fread($this->in, 8));
+ // zip64 extensible data sector (variable size)
+ fseek($this->in, $cdPos, SEEK_SET);
+ $this->preamble = $zip64EndOfCentralDirectoryRecordPos;
+ $entryCount = $cdEntries;
+ $zip64 = true;
+ return new EndOfCentralDirectory($entryCount, $comment, $zip64);
+ }
+ // Start recovering file entries from min.
+ $this->preamble = $min;
+ $this->postamble = $size - $min;
+ return new EndOfCentralDirectory(0, $comment);
+ }
+
+ /**
+ * Reads the central directory from the given seekable byte channel
+ * and populates the internal tables with ZipEntry instances.
+ *
+ * The ZipEntry's will know all data that can be obtained from the
+ * central directory alone, but not the data that requires the local
+ * file header or additional data to be read.
+ *
+ * @param EndOfCentralDirectory $endOfCentralDirectory
+ * @return ZipEntry[]
+ * @throws ZipException
+ */
+ protected function mountCentralDirectory(EndOfCentralDirectory $endOfCentralDirectory)
+ {
+ $numEntries = $endOfCentralDirectory->getEntryCount();
+ $entries = [];
+
+ for (; $numEntries > 0; $numEntries--) {
+ $entry = $this->readEntry();
+ // Re-load virtual offset after ZIP64 Extended Information
+ // Extra Field may have been parsed, map it to the real
+ // offset and conditionally update the preamble size from it.
+ $lfhOff = $this->mapper->map($entry->getOffset());
+ $lfhOff = PHP_INT_SIZE === 4 ? sprintf('%u', $lfhOff) : $lfhOff;
+ if ($lfhOff < $this->preamble) {
+ $this->preamble = $lfhOff;
+ }
+ $entries[$entry->getName()] = $entry;
+ }
+
+ if (0 !== $numEntries % 0x10000) {
+ throw new ZipException("Expected " . abs($numEntries) .
+ ($numEntries > 0 ? " more" : " less") .
+ " entries in the Central Directory!");
+ }
+
+ if ($this->preamble + $this->postamble >= fstat($this->in)['size']) {
+ assert(0 === $numEntries);
+ $this->checkZipFileSignature();
+ }
+
+ return $entries;
+ }
+
+ /**
+ * @return ZipEntry
+ * @throws InvalidArgumentException
+ */
+ public function readEntry()
+ {
+ // central file header signature 4 bytes (0x02014b50)
+ $fileHeaderSig = unpack('V', fread($this->in, 4))[1];
+ if (ZipOutputStreamInterface::CENTRAL_FILE_HEADER_SIG !== $fileHeaderSig) {
+ throw new InvalidArgumentException("Corrupt zip file. Can not read zip entry.");
+ }
+
+ // version made by 2 bytes
+ // version needed to extract 2 bytes
+ // general purpose bit flag 2 bytes
+ // compression method 2 bytes
+ // last mod file time 2 bytes
+ // last mod file date 2 bytes
+ // crc-32 4 bytes
+ // compressed size 4 bytes
+ // uncompressed size 4 bytes
+ // file name length 2 bytes
+ // extra field length 2 bytes
+ // file comment length 2 bytes
+ // disk number start 2 bytes
+ // internal file attributes 2 bytes
+ // external file attributes 4 bytes
+ // relative offset of local header 4 bytes
+ $data = unpack(
+ 'vversionMadeBy/vversionNeededToExtract/vgpbf/' .
+ 'vrawMethod/VrawTime/VrawCrc/VrawCompressedSize/' .
+ 'VrawSize/vfileLength/vextraLength/vcommentLength/' .
+ 'VrawInternalAttributes/VrawExternalAttributes/VlfhOff',
+ fread($this->in, 42)
+ );
+
+// $utf8 = 0 !== ($data['gpbf'] & self::GPBF_UTF8);
+
+ // See appendix D of PKWARE's ZIP File Format Specification.
+ $name = fread($this->in, $data['fileLength']);
+
+ $entry = new ZipSourceEntry($this);
+ $entry->setName($name);
+ $entry->setVersionNeededToExtract($data['versionNeededToExtract']);
+ $entry->setPlatform($data['versionMadeBy'] >> 8);
+ $entry->setMethod($data['rawMethod']);
+ $entry->setGeneralPurposeBitFlags($data['gpbf']);
+ $entry->setDosTime($data['rawTime']);
+ $entry->setCrc($data['rawCrc']);
+ $entry->setCompressedSize($data['rawCompressedSize']);
+ $entry->setSize($data['rawSize']);
+ $entry->setExternalAttributes($data['rawExternalAttributes']);
+ $entry->setOffset($data['lfhOff']); // must be unmapped!
+ if (0 < $data['extraLength']) {
+ $entry->setExtra(fread($this->in, $data['extraLength']));
+ }
+ if (0 < $data['commentLength']) {
+ $entry->setComment(fread($this->in, $data['commentLength']));
+ }
+ return $entry;
+ }
+
+ /**
+ * @param ZipEntry $entry
+ * @return string
+ * @throws ZipException
+ */
+ public function readEntryContent(ZipEntry $entry)
+ {
+ if ($entry->isDirectory()) {
+ return null;
+ }
+ if (!($entry instanceof ZipSourceEntry)) {
+ throw new InvalidArgumentException('entry must be ' . ZipSourceEntry::class);
+ }
+ $isEncrypted = $entry->isEncrypted();
+ if ($isEncrypted && null === $entry->getPassword()) {
+ throw new ZipException("Can not password from entry " . $entry->getName());
+ }
+
+ $pos = $entry->getOffset();
+ assert(ZipEntry::UNKNOWN !== $pos);
+ $pos = PHP_INT_SIZE === 4 ? sprintf('%u', $pos) : $pos;
+
+ $startPos = $pos = $this->mapper->map($pos);
+ fseek($this->in, $startPos);
+
+ // local file header signature 4 bytes (0x04034b50)
+ if (ZipEntry::LOCAL_FILE_HEADER_SIG !== unpack('V', fread($this->in, 4))[1]) {
+ throw new ZipException($entry->getName() . " (expected Local File Header)");
+ }
+ fseek($this->in, $pos + ZipEntry::LOCAL_FILE_HEADER_FILE_NAME_LENGTH_POS);
+ // file name length 2 bytes
+ // extra field length 2 bytes
+ $data = unpack('vfileLength/vextraLength', fread($this->in, 4));
+ $pos += ZipEntry::LOCAL_FILE_HEADER_MIN_LEN + $data['fileLength'] + $data['extraLength'];
+
+ assert(ZipEntry::UNKNOWN !== $entry->getCrc());
+
+ $method = $entry->getMethod();
+
+ fseek($this->in, $pos);
+
+ // Get raw entry content
+ $compressedSize = $entry->getCompressedSize();
+ $compressedSize = PHP_INT_SIZE === 4 ? sprintf('%u', $compressedSize) : $compressedSize;
+ if ($compressedSize > 0) {
+ $content = fread($this->in, $compressedSize);
+ } else {
+ $content = '';
+ }
+
+ $skipCheckCrc = false;
+ if ($isEncrypted) {
+ if (ZipEntry::METHOD_WINZIP_AES === $method) {
+ // Strong Encryption Specification - WinZip AES
+ $winZipAesEngine = new WinZipAesEngine($entry);
+ $content = $winZipAesEngine->decrypt($content);
+ /**
+ * @var WinZipAesEntryExtraField $field
+ */
+ $field = $entry->getExtraFieldsCollection()->get(WinZipAesEntryExtraField::getHeaderId());
+ $method = $field->getMethod();
+ $entry->setEncryptionMethod($field->getEncryptionMethod());
+ $skipCheckCrc = true;
+ } else {
+ // Traditional PKWARE Decryption
+ $zipCryptoEngine = new TraditionalPkwareEncryptionEngine($entry);
+ $content = $zipCryptoEngine->decrypt($content);
+ $entry->setEncryptionMethod(ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL);
+ }
+
+ if (!$skipCheckCrc) {
+ // Check CRC32 in the Local File Header or Data Descriptor.
+ $localCrc = null;
+ if ($entry->getGeneralPurposeBitFlag(ZipEntry::GPBF_DATA_DESCRIPTOR)) {
+ // The CRC32 is in the Data Descriptor after the compressed size.
+ // Note the Data Descriptor's Signature is optional:
+ // All newer apps should write it (and so does TrueVFS),
+ // but older apps might not.
+ fseek($this->in, $pos + $compressedSize);
+ $localCrc = unpack('V', fread($this->in, 4))[1];
+ if (ZipEntry::DATA_DESCRIPTOR_SIG === $localCrc) {
+ $localCrc = unpack('V', fread($this->in, 4))[1];
+ }
+ } else {
+ fseek($this->in, $startPos + 14);
+ // The CRC32 in the Local File Header.
+ $localCrc = sprintf('%u', fread($this->in, 4)[1]);
+ $localCrc = PHP_INT_SIZE === 4 ? sprintf('%u', $localCrc) : $localCrc;
+ }
+
+ $crc = PHP_INT_SIZE === 4 ? sprintf('%u', $entry->getCrc()) : $entry->getCrc();
+
+ if ($crc != $localCrc) {
+ throw new Crc32Exception($entry->getName(), $crc, $localCrc);
+ }
+ }
+ }
+
+ switch ($method) {
+ case ZipFileInterface::METHOD_STORED:
+ break;
+ case ZipFileInterface::METHOD_DEFLATED:
+ $content = gzinflate($content);
+ break;
+ case ZipFileInterface::METHOD_BZIP2:
+ if (!extension_loaded('bz2')) {
+ throw new ZipException('Extension bzip2 not install');
+ }
+ $content = bzdecompress($content);
+ break;
+ default:
+ throw new ZipUnsupportMethod($entry->getName() .
+ " (compression method " . $method . " is not supported)");
+ }
+ if (!$skipCheckCrc AND false) {
+ $localCrc = crc32($content);
+ $localCrc = PHP_INT_SIZE === 4 ? sprintf('%u', $localCrc) : $localCrc;
+ $crc = PHP_INT_SIZE === 4 ? sprintf('%u', $entry->getCrc()) : $entry->getCrc();
+ if ($crc != $localCrc) {
+ if ($isEncrypted) {
+ throw new ZipCryptoException("Wrong password");
+ }
+ throw new Crc32Exception($entry->getName(), $crc, $localCrc);
+ }
+ }
+ return $content;
+ }
+
+ /**
+ * @return resource
+ */
+ public function getStream()
+ {
+ return $this->in;
+ }
+
+ /**
+ * Copy the input stream of the LOC entry zip and the data into
+ * the output stream and zip the alignment if necessary.
+ *
+ * @param ZipEntry $entry
+ * @param ZipOutputStreamInterface $out
+ */
+ public function copyEntry(ZipEntry $entry, ZipOutputStreamInterface $out)
+ {
+ $pos = $entry->getOffset();
+ assert(ZipEntry::UNKNOWN !== $pos);
+ $pos = PHP_INT_SIZE === 4 ? sprintf('%u', $pos) : $pos;
+ $pos = $this->mapper->map($pos);
+
+ $nameLength = strlen($entry->getName());
+
+ fseek($this->in, $pos + ZipEntry::LOCAL_FILE_HEADER_MIN_LEN - 2, SEEK_SET);
+ $sourceExtraLength = $destExtraLength = unpack('v', fread($this->in, 2))[1];
+
+ if ($sourceExtraLength > 0) {
+ // read Local File Header extra fields
+ fseek($this->in, $pos + ZipEntry::LOCAL_FILE_HEADER_MIN_LEN + $nameLength, SEEK_SET);
+ $extra = fread($this->in, $sourceExtraLength);
+ $extraFieldsCollection = ExtraFieldsFactory::createExtraFieldCollections($extra, $entry);
+ if (isset($extraFieldsCollection[ApkAlignmentExtraField::getHeaderId()]) && $this->zipModel->isZipAlign()) {
+ unset($extraFieldsCollection[ApkAlignmentExtraField::getHeaderId()]);
+ $destExtraLength = strlen(ExtraFieldsFactory::createSerializedData($extraFieldsCollection));
+ }
+ } else {
+ $extraFieldsCollection = new ExtraFieldsCollection();
+ }
+
+ $dataAlignmentMultiple = $this->zipModel->getZipAlign();
+ $copyInToOutLength = $entry->getCompressedSize();
+
+ fseek($this->in, $pos, SEEK_SET);
+
+ if (
+ $this->zipModel->isZipAlign() &&
+ !$entry->isEncrypted() &&
+ $entry->getMethod() === ZipFileInterface::METHOD_STORED
+ ) {
+ if (StringUtil::endsWith($entry->getName(), '.so')) {
+ $dataAlignmentMultiple = ApkAlignmentExtraField::ANDROID_COMMON_PAGE_ALIGNMENT_BYTES;
+ }
+
+ $dataMinStartOffset =
+ ftell($out->getStream()) +
+ ZipEntry::LOCAL_FILE_HEADER_MIN_LEN +
+ $destExtraLength +
+ $nameLength +
+ ApkAlignmentExtraField::ALIGNMENT_ZIP_EXTRA_MIN_SIZE_BYTES;
+ $padding =
+ ($dataAlignmentMultiple - ($dataMinStartOffset % $dataAlignmentMultiple))
+ % $dataAlignmentMultiple;
+
+ $alignExtra = new ApkAlignmentExtraField();
+ $alignExtra->setMultiple($dataAlignmentMultiple);
+ $alignExtra->setPadding($padding);
+ $extraFieldsCollection->add($alignExtra);
+
+ $extra = ExtraFieldsFactory::createSerializedData($extraFieldsCollection);
+
+ // copy Local File Header without extra field length
+ // from input stream to output stream
+ stream_copy_to_stream($this->in, $out->getStream(), ZipEntry::LOCAL_FILE_HEADER_MIN_LEN - 2);
+ // write new extra field length (2 bytes) to output stream
+ fwrite($out->getStream(), pack('v', strlen($extra)));
+ // skip 2 bytes to input stream
+ fseek($this->in, 2, SEEK_CUR);
+ // copy name from input stream to output stream
+ stream_copy_to_stream($this->in, $out->getStream(), $nameLength);
+ // write extra field to output stream
+ fwrite($out->getStream(), $extra);
+ // skip source extraLength from input stream
+ fseek($this->in, $sourceExtraLength, SEEK_CUR);
+ } else {
+ $copyInToOutLength += ZipEntry::LOCAL_FILE_HEADER_MIN_LEN + $sourceExtraLength + $nameLength;
+ ;
+ }
+ if ($entry->getGeneralPurposeBitFlag(ZipEntry::GPBF_DATA_DESCRIPTOR)) {
+// crc-32 4 bytes
+// compressed size 4 bytes
+// uncompressed size 4 bytes
+ $copyInToOutLength += 12;
+ if ($entry->isZip64ExtensionsRequired()) {
+// compressed size +4 bytes
+// uncompressed size +4 bytes
+ $copyInToOutLength += 8;
+ }
+ }
+ // copy loc, data, data descriptor from input to output stream
+ stream_copy_to_stream($this->in, $out->getStream(), $copyInToOutLength);
+ }
+
+ /**
+ * @param ZipEntry $entry
+ * @param ZipOutputStreamInterface $out
+ */
+ public function copyEntryData(ZipEntry $entry, ZipOutputStreamInterface $out)
+ {
+ $offset = $entry->getOffset();
+ $offset = PHP_INT_SIZE === 4 ? sprintf('%u', $offset) : $offset;
+ $offset = $this->mapper->map($offset);
+ $nameLength = strlen($entry->getName());
+
+ fseek($this->in, $offset + ZipEntry::LOCAL_FILE_HEADER_MIN_LEN - 2, SEEK_SET);
+ $extraLength = unpack('v', fread($this->in, 2))[1];
+
+ fseek($this->in, $offset + ZipEntry::LOCAL_FILE_HEADER_MIN_LEN + $nameLength + $extraLength, SEEK_SET);
+ // copy raw data from input stream to output stream
+ stream_copy_to_stream($this->in, $out->getStream(), $entry->getCompressedSize());
+ }
+
+ public function __destruct()
+ {
+ $this->close();
+ }
+
+ public function close()
+ {
+ if ($this->in != null) {
+ fclose($this->in);
+ $this->in = null;
+ }
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Stream/ZipInputStreamInterface.php b/vendor/nelexa/zip/src/PhpZip/Stream/ZipInputStreamInterface.php
new file mode 100644
index 0000000..2093c03
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Stream/ZipInputStreamInterface.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace PhpZip\Stream;
+
+use PhpZip\Model\ZipEntry;
+use PhpZip\Model\ZipModel;
+
+/**
+ * Read zip file
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+interface ZipInputStreamInterface
+{
+ /**
+ * @return ZipModel
+ */
+ public function readZip();
+
+ /**
+ * @return ZipEntry
+ */
+ public function readEntry();
+
+ /**
+ * @param ZipEntry $entry
+ * @return string
+ */
+ public function readEntryContent(ZipEntry $entry);
+
+ /**
+ * @return resource
+ */
+ public function getStream();
+
+ /**
+ * Copy the input stream of the LOC entry zip and the data into
+ * the output stream and zip the alignment if necessary.
+ *
+ * @param ZipEntry $entry
+ * @param ZipOutputStreamInterface $out
+ */
+ public function copyEntry(ZipEntry $entry, ZipOutputStreamInterface $out);
+
+ /**
+ * @param ZipEntry $entry
+ * @param ZipOutputStreamInterface $out
+ */
+ public function copyEntryData(ZipEntry $entry, ZipOutputStreamInterface $out);
+
+ public function close();
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Stream/ZipOutputStream.php b/vendor/nelexa/zip/src/PhpZip/Stream/ZipOutputStream.php
new file mode 100644
index 0000000..c1c875d
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Stream/ZipOutputStream.php
@@ -0,0 +1,528 @@
+<?php
+
+namespace PhpZip\Stream;
+
+use PhpZip\Crypto\TraditionalPkwareEncryptionEngine;
+use PhpZip\Crypto\WinZipAesEngine;
+use PhpZip\Exception\InvalidArgumentException;
+use PhpZip\Exception\RuntimeException;
+use PhpZip\Exception\ZipException;
+use PhpZip\Extra\ExtraFieldsFactory;
+use PhpZip\Extra\Fields\ApkAlignmentExtraField;
+use PhpZip\Extra\Fields\WinZipAesEntryExtraField;
+use PhpZip\Extra\Fields\Zip64ExtraField;
+use PhpZip\Model\EndOfCentralDirectory;
+use PhpZip\Model\Entry\OutputOffsetEntry;
+use PhpZip\Model\Entry\ZipChangesEntry;
+use PhpZip\Model\Entry\ZipSourceEntry;
+use PhpZip\Model\ZipEntry;
+use PhpZip\Model\ZipModel;
+use PhpZip\Util\PackUtil;
+use PhpZip\Util\StringUtil;
+use PhpZip\ZipFileInterface;
+
+/**
+ * Write
+ * ip file
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class ZipOutputStream implements ZipOutputStreamInterface
+{
+ /**
+ * @var resource
+ */
+ protected $out;
+ /**
+ * @var ZipModel
+ */
+ protected $zipModel;
+
+ /**
+ * ZipOutputStream constructor.
+ * @param resource $out
+ * @param ZipModel $zipModel
+ * @throws InvalidArgumentException
+ */
+ public function __construct($out, ZipModel $zipModel)
+ {
+ if (!is_resource($out)) {
+ throw new InvalidArgumentException('$out must be resource');
+ }
+ $this->out = $out;
+ $this->zipModel = $zipModel;
+ }
+
+ public function writeZip()
+ {
+ $entries = $this->zipModel->getEntries();
+ $outPosEntries = [];
+ foreach ($entries as $entry) {
+ $outPosEntries[] = new OutputOffsetEntry(ftell($this->out), $entry);
+ $this->writeEntry($entry);
+ }
+ $centralDirectoryOffset = ftell($this->out);
+ foreach ($outPosEntries as $outputEntry) {
+ $this->writeCentralDirectoryHeader($outputEntry);
+ }
+ $this->writeEndOfCentralDirectoryRecord($centralDirectoryOffset);
+ }
+
+ /**
+ * @param ZipEntry $entry
+ * @throws ZipException
+ */
+ public function writeEntry(ZipEntry $entry)
+ {
+ if ($entry instanceof ZipSourceEntry) {
+ $entry->getInputStream()->copyEntry($entry, $this);
+ return;
+ }
+
+ $entryContent = $this->entryCommitChangesAndReturnContent($entry);
+
+ $offset = ftell($this->out);
+ $compressedSize = $entry->getCompressedSize();
+
+ $extra = $entry->getExtra();
+
+ $nameLength = strlen($entry->getName());
+ $extraLength = strlen($extra);
+
+ // zip align
+ if (
+ $this->zipModel->isZipAlign() &&
+ !$entry->isEncrypted() &&
+ $entry->getMethod() === ZipFileInterface::METHOD_STORED
+ ) {
+ $dataAlignmentMultiple = $this->zipModel->getZipAlign();
+ if (StringUtil::endsWith($entry->getName(), '.so')) {
+ $dataAlignmentMultiple = ApkAlignmentExtraField::ANDROID_COMMON_PAGE_ALIGNMENT_BYTES;
+ }
+ $dataMinStartOffset =
+ $offset +
+ ZipEntry::LOCAL_FILE_HEADER_MIN_LEN +
+ $extraLength +
+ $nameLength +
+ ApkAlignmentExtraField::ALIGNMENT_ZIP_EXTRA_MIN_SIZE_BYTES;
+
+ $padding =
+ ($dataAlignmentMultiple - ($dataMinStartOffset % $dataAlignmentMultiple))
+ % $dataAlignmentMultiple;
+
+ $alignExtra = new ApkAlignmentExtraField();
+ $alignExtra->setMultiple($dataAlignmentMultiple);
+ $alignExtra->setPadding($padding);
+
+ $extraFieldsCollection = clone $entry->getExtraFieldsCollection();
+ $extraFieldsCollection->add($alignExtra);
+
+ $extra = ExtraFieldsFactory::createSerializedData($extraFieldsCollection);
+ $extraLength = strlen($extra);
+ }
+
+ $size = $nameLength + $extraLength;
+ if (0xffff < $size) {
+ throw new ZipException(
+ $entry->getName() . " (the total size of " . $size .
+ " bytes for the name, extra fields and comment " .
+ "exceeds the maximum size of " . 0xffff . " bytes)"
+ );
+ }
+
+ $dd = $entry->isDataDescriptorRequired();
+ fwrite(
+ $this->out,
+ pack(
+ 'VvvvVVVVvv',
+ // local file header signature 4 bytes (0x04034b50)
+ ZipEntry::LOCAL_FILE_HEADER_SIG,
+ // version needed to extract 2 bytes
+ $entry->getVersionNeededToExtract(),
+ // general purpose bit flag 2 bytes
+ $entry->getGeneralPurposeBitFlags(),
+ // compression method 2 bytes
+ $entry->getMethod(),
+ // last mod file time 2 bytes
+ // last mod file date 2 bytes
+ $entry->getDosTime(),
+ // crc-32 4 bytes
+ $dd ? 0 : $entry->getCrc(),
+ // compressed size 4 bytes
+ $dd ? 0 : $entry->getCompressedSize(),
+ // uncompressed size 4 bytes
+ $dd ? 0 : $entry->getSize(),
+ // file name length 2 bytes
+ $nameLength,
+ // extra field length 2 bytes
+ $extraLength
+ )
+ );
+ if ($nameLength > 0) {
+ fwrite($this->out, $entry->getName());
+ }
+ if ($extraLength > 0) {
+ fwrite($this->out, $extra);
+ }
+
+ if ($entry instanceof ZipChangesEntry && !$entry->isChangedContent()) {
+ $entry->getSourceEntry()->getInputStream()->copyEntryData($entry->getSourceEntry(), $this);
+ } elseif (null !== $entryContent) {
+ fwrite($this->out, $entryContent);
+ }
+
+ assert(ZipEntry::UNKNOWN !== $entry->getCrc());
+ assert(ZipEntry::UNKNOWN !== $entry->getSize());
+ if ($entry->getGeneralPurposeBitFlag(ZipEntry::GPBF_DATA_DESCRIPTOR)) {
+ // data descriptor signature 4 bytes (0x08074b50)
+ // crc-32 4 bytes
+ fwrite($this->out, pack('VV', ZipEntry::DATA_DESCRIPTOR_SIG, $entry->getCrc()));
+ // compressed size 4 or 8 bytes
+ // uncompressed size 4 or 8 bytes
+ if ($entry->isZip64ExtensionsRequired()) {
+ fwrite($this->out, PackUtil::packLongLE($compressedSize));
+ fwrite($this->out, PackUtil::packLongLE($entry->getSize()));
+ } else {
+ fwrite($this->out, pack('VV', $entry->getCompressedSize(), $entry->getSize()));
+ }
+ } elseif ($entry->getCompressedSize() != $compressedSize) {
+ throw new ZipException(
+ $entry->getName() . " (expected compressed entry size of "
+ . $entry->getCompressedSize() . " bytes, " .
+ "but is actually " . $compressedSize . " bytes)"
+ );
+ }
+ }
+
+ /**
+ * @param ZipEntry $entry
+ * @return null|string
+ * @throws ZipException
+ */
+ protected function entryCommitChangesAndReturnContent(ZipEntry $entry)
+ {
+ if (ZipEntry::UNKNOWN === $entry->getPlatform()) {
+ $entry->setPlatform(ZipEntry::PLATFORM_UNIX);
+ }
+ if (ZipEntry::UNKNOWN === $entry->getTime()) {
+ $entry->setTime(time());
+ }
+ $method = $entry->getMethod();
+
+ $encrypted = $entry->isEncrypted();
+ // See appendix D of PKWARE's ZIP File Format Specification.
+ $utf8 = true;
+
+ if ($encrypted && null === $entry->getPassword()) {
+ throw new ZipException("Can not password from entry " . $entry->getName());
+ }
+
+ // Compose General Purpose Bit Flag.
+ $general = ($encrypted ? ZipEntry::GPBF_ENCRYPTED : 0)
+ | ($entry->isDataDescriptorRequired() ? ZipEntry::GPBF_DATA_DESCRIPTOR : 0)
+ | ($utf8 ? ZipEntry::GPBF_UTF8 : 0);
+
+ $entryContent = null;
+ $extraFieldsCollection = $entry->getExtraFieldsCollection();
+ if (!($entry instanceof ZipChangesEntry && !$entry->isChangedContent())) {
+ $entryContent = $entry->getEntryContent();
+
+ if ($entryContent !== null) {
+ $entry->setSize(strlen($entryContent));
+ $entry->setCrc(crc32($entryContent));
+
+ if ($encrypted && ZipEntry::METHOD_WINZIP_AES === $method) {
+ /**
+ * @var WinZipAesEntryExtraField $field
+ */
+ $field = $extraFieldsCollection->get(WinZipAesEntryExtraField::getHeaderId());
+ if (null !== $field) {
+ $method = $field->getMethod();
+ }
+ }
+
+ switch ($method) {
+ case ZipFileInterface::METHOD_STORED:
+ break;
+
+ case ZipFileInterface::METHOD_DEFLATED:
+ $entryContent = gzdeflate($entryContent, $entry->getCompressionLevel());
+ break;
+
+ case ZipFileInterface::METHOD_BZIP2:
+ $compressionLevel = $entry->getCompressionLevel() === ZipFileInterface::LEVEL_DEFAULT_COMPRESSION ?
+ ZipEntry::LEVEL_DEFAULT_BZIP2_COMPRESSION :
+ $entry->getCompressionLevel();
+ $entryContent = bzcompress($entryContent, $compressionLevel);
+ if (is_int($entryContent)) {
+ throw new ZipException('Error bzip2 compress. Error code: ' . $entryContent);
+ }
+ break;
+
+ case ZipEntry::UNKNOWN:
+ $entryContent = $this->determineBestCompressionMethod($entry, $entryContent);
+ $method = $entry->getMethod();
+ break;
+
+ default:
+ throw new ZipException($entry->getName() . " (unsupported compression method " . $method . ")");
+ }
+
+ if (ZipFileInterface::METHOD_DEFLATED === $method) {
+ $bit1 = false;
+ $bit2 = false;
+ switch ($entry->getCompressionLevel()) {
+ case ZipFileInterface::LEVEL_BEST_COMPRESSION:
+ $bit1 = true;
+ break;
+
+ case ZipFileInterface::LEVEL_FAST:
+ $bit2 = true;
+ break;
+
+ case ZipFileInterface::LEVEL_SUPER_FAST:
+ $bit1 = true;
+ $bit2 = true;
+ break;
+ }
+
+ $general |= ($bit1 ? ZipEntry::GPBF_COMPRESSION_FLAG1 : 0);
+ $general |= ($bit2 ? ZipEntry::GPBF_COMPRESSION_FLAG2 : 0);
+ }
+
+ if ($encrypted) {
+ if (in_array($entry->getEncryptionMethod(), [
+ ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_128,
+ ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_192,
+ ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_256,
+ ], true)) {
+ $keyStrength = WinZipAesEntryExtraField::getKeyStrangeFromEncryptionMethod($entry->getEncryptionMethod()); // size bits
+ $field = ExtraFieldsFactory::createWinZipAesEntryExtra();
+ $field->setKeyStrength($keyStrength);
+ $field->setMethod($method);
+ $size = $entry->getSize();
+ if (20 <= $size && ZipFileInterface::METHOD_BZIP2 !== $method) {
+ $field->setVendorVersion(WinZipAesEntryExtraField::VV_AE_1);
+ } else {
+ $field->setVendorVersion(WinZipAesEntryExtraField::VV_AE_2);
+ $entry->setCrc(0);
+ }
+ $extraFieldsCollection->add($field);
+ $entry->setMethod(ZipEntry::METHOD_WINZIP_AES);
+
+ $winZipAesEngine = new WinZipAesEngine($entry);
+ $entryContent = $winZipAesEngine->encrypt($entryContent);
+ } elseif ($entry->getEncryptionMethod() === ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL) {
+ $zipCryptoEngine = new TraditionalPkwareEncryptionEngine($entry);
+ $entryContent = $zipCryptoEngine->encrypt($entryContent);
+ }
+ }
+
+ $compressedSize = strlen($entryContent);
+ $entry->setCompressedSize($compressedSize);
+ }
+ }
+
+ // Commit changes.
+ $entry->setGeneralPurposeBitFlags($general);
+
+ if ($entry->isZip64ExtensionsRequired()) {
+ $extraFieldsCollection->add(ExtraFieldsFactory::createZip64Extra($entry));
+ } elseif ($extraFieldsCollection->has(Zip64ExtraField::getHeaderId())) {
+ $extraFieldsCollection->remove(Zip64ExtraField::getHeaderId());
+ }
+ return $entryContent;
+ }
+
+ /**
+ * @param ZipEntry $entry
+ * @param string $content
+ * @return string
+ * @throws ZipException
+ */
+ protected function determineBestCompressionMethod(ZipEntry $entry, $content)
+ {
+ if (null !== $content) {
+ $entryContent = gzdeflate($content, $entry->getCompressionLevel());
+ if (strlen($entryContent) < strlen($content)) {
+ $entry->setMethod(ZipFileInterface::METHOD_DEFLATED);
+ return $entryContent;
+ }
+ $entry->setMethod(ZipFileInterface::METHOD_STORED);
+ }
+ return $content;
+ }
+
+ /**
+ * Writes a Central File Header record.
+ *
+ * @param OutputOffsetEntry $outEntry
+ * @throws RuntimeException
+ * @internal param OutPosEntry $entry
+ */
+ protected function writeCentralDirectoryHeader(OutputOffsetEntry $outEntry)
+ {
+ $entry = $outEntry->getEntry();
+ $compressedSize = $entry->getCompressedSize();
+ $size = $entry->getSize();
+ // This test MUST NOT include the CRC-32 because VV_AE_2 sets it to
+ // UNKNOWN!
+ if (ZipEntry::UNKNOWN === ($compressedSize | $size)) {
+ throw new RuntimeException("invalid entry");
+ }
+ $extra = $entry->getExtra();
+ $extraSize = strlen($extra);
+
+ $commentLength = strlen($entry->getComment());
+ fwrite(
+ $this->out,
+ pack(
+ 'VvvvvVVVVvvvvvVV',
+ // central file header signature 4 bytes (0x02014b50)
+ self::CENTRAL_FILE_HEADER_SIG,
+ // version made by 2 bytes
+ ($entry->getPlatform() << 8) | 63,
+ // version needed to extract 2 bytes
+ $entry->getVersionNeededToExtract(),
+ // general purpose bit flag 2 bytes
+ $entry->getGeneralPurposeBitFlags(),
+ // compression method 2 bytes
+ $entry->getMethod(),
+ // last mod file datetime 4 bytes
+ $entry->getDosTime(),
+ // crc-32 4 bytes
+ $entry->getCrc(),
+ // compressed size 4 bytes
+ $entry->getCompressedSize(),
+ // uncompressed size 4 bytes
+ $entry->getSize(),
+ // file name length 2 bytes
+ strlen($entry->getName()),
+ // extra field length 2 bytes
+ $extraSize,
+ // file comment length 2 bytes
+ $commentLength,
+ // disk number start 2 bytes
+ 0,
+ // internal file attributes 2 bytes
+ 0,
+ // external file attributes 4 bytes
+ $entry->getExternalAttributes(),
+ // relative offset of local header 4 bytes
+ $outEntry->getOffset()
+ )
+ );
+ // file name (variable size)
+ fwrite($this->out, $entry->getName());
+ if (0 < $extraSize) {
+ // extra field (variable size)
+ fwrite($this->out, $extra);
+ }
+ if (0 < $commentLength) {
+ // file comment (variable size)
+ fwrite($this->out, $entry->getComment());
+ }
+ }
+
+ protected function writeEndOfCentralDirectoryRecord($centralDirectoryOffset)
+ {
+ $centralDirectoryEntriesCount = count($this->zipModel);
+ $position = ftell($this->out);
+ $centralDirectorySize = $position - $centralDirectoryOffset;
+ $centralDirectoryEntriesZip64 = $centralDirectoryEntriesCount > 0xffff;
+ $centralDirectorySizeZip64 = $centralDirectorySize > 0xffffffff;
+ $centralDirectoryOffsetZip64 = $centralDirectoryOffset > 0xffffffff;
+ $centralDirectoryEntries16 = $centralDirectoryEntriesZip64 ? 0xffff : (int)$centralDirectoryEntriesCount;
+ $centralDirectorySize32 = $centralDirectorySizeZip64 ? 0xffffffff : $centralDirectorySize;
+ $centralDirectoryOffset32 = $centralDirectoryOffsetZip64 ? 0xffffffff : $centralDirectoryOffset;
+ $zip64 // ZIP64 extensions?
+ = $centralDirectoryEntriesZip64
+ || $centralDirectorySizeZip64
+ || $centralDirectoryOffsetZip64;
+ if ($zip64) {
+ // [zip64 end of central directory record]
+ // relative offset of the zip64 end of central directory record
+ $zip64EndOfCentralDirectoryOffset = $position;
+ // zip64 end of central dir
+ // signature 4 bytes (0x06064b50)
+ fwrite($this->out, pack('V', EndOfCentralDirectory::ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIG));
+ // size of zip64 end of central
+ // directory record 8 bytes
+ fwrite($this->out, PackUtil::packLongLE(EndOfCentralDirectory::ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_MIN_LEN - 12));
+ // version made by 2 bytes
+ // version needed to extract 2 bytes
+ // due to potential use of BZIP2 compression
+ // number of this disk 4 bytes
+ // number of the disk with the
+ // start of the central directory 4 bytes
+ fwrite($this->out, pack('vvVV', 63, 46, 0, 0));
+ // total number of entries in the
+ // central directory on this disk 8 bytes
+ fwrite($this->out, PackUtil::packLongLE($centralDirectoryEntriesCount));
+ // total number of entries in the
+ // central directory 8 bytes
+ fwrite($this->out, PackUtil::packLongLE($centralDirectoryEntriesCount));
+ // size of the central directory 8 bytes
+ fwrite($this->out, PackUtil::packLongLE($centralDirectorySize));
+ // offset of start of central
+ // directory with respect to
+ // the starting disk number 8 bytes
+ fwrite($this->out, PackUtil::packLongLE($centralDirectoryOffset));
+ // zip64 extensible data sector (variable size)
+
+ // [zip64 end of central directory locator]
+ // signature 4 bytes (0x07064b50)
+ // number of the disk with the
+ // start of the zip64 end of
+ // central directory 4 bytes
+ fwrite($this->out, pack('VV', EndOfCentralDirectory::ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIG, 0));
+ // relative offset of the zip64
+ // end of central directory record 8 bytes
+ fwrite($this->out, PackUtil::packLongLE($zip64EndOfCentralDirectoryOffset));
+ // total number of disks 4 bytes
+ fwrite($this->out, pack('V', 1));
+ }
+ $comment = $this->zipModel->getArchiveComment();
+ $commentLength = strlen($comment);
+ fwrite(
+ $this->out,
+ pack(
+ 'VvvvvVVv',
+ // end of central dir signature 4 bytes (0x06054b50)
+ EndOfCentralDirectory::END_OF_CENTRAL_DIRECTORY_RECORD_SIG,
+ // number of this disk 2 bytes
+ 0,
+ // number of the disk with the
+ // start of the central directory 2 bytes
+ 0,
+ // total number of entries in the
+ // central directory on this disk 2 bytes
+ $centralDirectoryEntries16,
+ // total number of entries in
+ // the central directory 2 bytes
+ $centralDirectoryEntries16,
+ // size of the central directory 4 bytes
+ $centralDirectorySize32,
+ // offset of start of central
+ // directory with respect to
+ // the starting disk number 4 bytes
+ $centralDirectoryOffset32,
+ // .ZIP file comment length 2 bytes
+ $commentLength
+ )
+ );
+ if ($commentLength > 0) {
+ // .ZIP file comment (variable size)
+ fwrite($this->out, $comment);
+ }
+ }
+
+ /**
+ * @return resource
+ */
+ public function getStream()
+ {
+ return $this->out;
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Stream/ZipOutputStreamInterface.php b/vendor/nelexa/zip/src/PhpZip/Stream/ZipOutputStreamInterface.php
new file mode 100644
index 0000000..57c397e
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Stream/ZipOutputStreamInterface.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace PhpZip\Stream;
+
+use PhpZip\Model\ZipEntry;
+
+/**
+ * Write zip file
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+interface ZipOutputStreamInterface
+{
+ /** Central File Header signature. */
+ const CENTRAL_FILE_HEADER_SIG = 0x02014B50;
+
+ public function writeZip();
+
+ /**
+ * @param ZipEntry $entry
+ */
+ public function writeEntry(ZipEntry $entry);
+
+ /**
+ * @return resource
+ */
+ public function getStream();
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Util/CryptoUtil.php b/vendor/nelexa/zip/src/PhpZip/Util/CryptoUtil.php
new file mode 100644
index 0000000..7403c93
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Util/CryptoUtil.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace PhpZip\Util;
+
+use PhpZip\Exception\RuntimeException;
+
+/**
+ * Crypto Utils
+ */
+class CryptoUtil
+{
+
+ /**
+ * Returns random bytes.
+ *
+ * @param int $length
+ * @return string
+ * @throws RuntimeException
+ */
+ final public static function randomBytes($length)
+ {
+ $length = (int)$length;
+ if (function_exists('random_bytes')) {
+ return random_bytes($length);
+ } elseif (function_exists('openssl_random_pseudo_bytes')) {
+ return openssl_random_pseudo_bytes($length);
+ } elseif (function_exists('mcrypt_create_iv')) {
+ return mcrypt_create_iv($length);
+ } else {
+ throw new RuntimeException('Extension openssl or mcrypt not loaded');
+ }
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Util/DateTimeConverter.php b/vendor/nelexa/zip/src/PhpZip/Util/DateTimeConverter.php
new file mode 100644
index 0000000..e63f56b
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Util/DateTimeConverter.php
@@ -0,0 +1,78 @@
+<?php
+
+namespace PhpZip\Util;
+
+use PhpZip\Exception\ZipException;
+
+/**
+ * Convert unix timestamp values to DOS date/time values and vice versa.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class DateTimeConverter
+{
+ /**
+ * Smallest supported DOS date/time value in a ZIP file,
+ * which is January 1st, 1980 AD 00:00:00 local time.
+ */
+ const MIN_DOS_TIME = 0x210000; // (1 << 21) | (1 << 16)
+
+ /**
+ * Largest supported DOS date/time value in a ZIP file,
+ * which is December 31st, 2107 AD 23:59:58 local time.
+ */
+ const MAX_DOS_TIME = 0xff9fbf7d; // ((2107 - 1980) << 25) | (12 << 21) | (31 << 16) | (23 << 11) | (59 << 5) | (58 >> 1);
+
+ /**
+ * Convert a 32 bit integer DOS date/time value to a UNIX timestamp value.
+ *
+ * @param int $dosTime Dos date/time
+ * @return int Unix timestamp
+ */
+ public static function toUnixTimestamp($dosTime)
+ {
+ if (self::MIN_DOS_TIME > $dosTime) {
+ $dosTime = self::MIN_DOS_TIME;
+ } elseif (self::MAX_DOS_TIME < $dosTime) {
+ $dosTime = self::MAX_DOS_TIME;
+ }
+
+ return mktime(
+ ($dosTime >> 11) & 0x1f, // hour
+ ($dosTime >> 5) & 0x3f, // minute
+ 2 * ($dosTime & 0x1f), // second
+ ($dosTime >> 21) & 0x0f, // month
+ ($dosTime >> 16) & 0x1f, // day
+ 1980 + (($dosTime >> 25) & 0x7f) // year
+ );
+ }
+
+ /**
+ * Converts a UNIX timestamp value to a DOS date/time value.
+ *
+ * @param int $unixTimestamp The number of seconds since midnight, January 1st,
+ * 1970 AD UTC.
+ * @return int A DOS date/time value reflecting the local time zone and
+ * rounded down to even seconds
+ * and is in between DateTimeConverter::MIN_DOS_TIME and DateTimeConverter::MAX_DOS_TIME.
+ * @throws ZipException If unix timestamp is negative.
+ */
+ public static function toDosTime($unixTimestamp)
+ {
+ if (0 > $unixTimestamp) {
+ throw new ZipException("Negative unix timestamp: " . $unixTimestamp);
+ }
+
+ $date = getdate($unixTimestamp);
+
+ if ($date['year'] < 1980) {
+ return self::MIN_DOS_TIME;
+ }
+
+ $date['year'] -= 1980;
+ return ($date['year'] << 25 | $date['mon'] << 21 |
+ $date['mday'] << 16 | $date['hours'] << 11 |
+ $date['minutes'] << 5 | $date['seconds'] >> 1);
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Util/FilesUtil.php b/vendor/nelexa/zip/src/PhpZip/Util/FilesUtil.php
new file mode 100644
index 0000000..29e8688
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Util/FilesUtil.php
@@ -0,0 +1,228 @@
+<?php
+
+namespace PhpZip\Util;
+
+use PhpZip\Util\Iterator\IgnoreFilesFilterIterator;
+use PhpZip\Util\Iterator\IgnoreFilesRecursiveFilterIterator;
+
+/**
+ * Files util.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class FilesUtil
+{
+
+ /**
+ * Is empty directory
+ *
+ * @param string $dir Directory
+ * @return bool
+ */
+ public static function isEmptyDir($dir)
+ {
+ if (!is_readable($dir)) {
+ return false;
+ }
+ return count(scandir($dir)) === 2;
+ }
+
+ /**
+ * Remove recursive directory.
+ *
+ * @param string $dir Directory path.
+ */
+ public static function removeDir($dir)
+ {
+ $files = new \RecursiveIteratorIterator(
+ new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS),
+ \RecursiveIteratorIterator::CHILD_FIRST
+ );
+ foreach ($files as $fileInfo) {
+ $function = ($fileInfo->isDir() ? 'rmdir' : 'unlink');
+ $function($fileInfo->getRealPath());
+ }
+ rmdir($dir);
+ }
+
+
+ /**
+ * Convert glob pattern to regex pattern.
+ *
+ * @param string $globPattern
+ * @return string
+ */
+ public static function convertGlobToRegEx($globPattern)
+ {
+ // Remove beginning and ending * globs because they're useless
+ $globPattern = trim($globPattern, '*');
+ $escaping = false;
+ $inCurrent = 0;
+ $chars = str_split($globPattern);
+ $regexPattern = '';
+ foreach ($chars as $currentChar) {
+ switch ($currentChar) {
+ case '*':
+ $regexPattern .= ($escaping ? "\\*" : '.*');
+ $escaping = false;
+ break;
+ case '?':
+ $regexPattern .= ($escaping ? "\\?" : '.');
+ $escaping = false;
+ break;
+ case '.':
+ case '(':
+ case ')':
+ case '+':
+ case '|':
+ case '^':
+ case '$':
+ case '@':
+ case '%':
+ $regexPattern .= '\\' . $currentChar;
+ $escaping = false;
+ break;
+ case '\\':
+ if ($escaping) {
+ $regexPattern .= "\\\\";
+ $escaping = false;
+ } else {
+ $escaping = true;
+ }
+ break;
+ case '{':
+ if ($escaping) {
+ $regexPattern .= "\\{";
+ } else {
+ $regexPattern = '(';
+ $inCurrent++;
+ }
+ $escaping = false;
+ break;
+ case '}':
+ if ($inCurrent > 0 && !$escaping) {
+ $regexPattern .= ')';
+ $inCurrent--;
+ } elseif ($escaping) {
+ $regexPattern = "\\}";
+ } else {
+ $regexPattern = "}";
+ }
+ $escaping = false;
+ break;
+ case ',':
+ if ($inCurrent > 0 && !$escaping) {
+ $regexPattern .= '|';
+ } elseif ($escaping) {
+ $regexPattern .= "\\,";
+ } else {
+ $regexPattern = ",";
+ }
+ break;
+ default:
+ $escaping = false;
+ $regexPattern .= $currentChar;
+ }
+ }
+ return $regexPattern;
+ }
+
+ /**
+ * Search files.
+ *
+ * @param string $inputDir
+ * @param bool $recursive
+ * @param array $ignoreFiles
+ * @return array Searched file list
+ */
+ public static function fileSearchWithIgnore($inputDir, $recursive = true, array $ignoreFiles = [])
+ {
+ $directoryIterator = $recursive ?
+ new \RecursiveDirectoryIterator($inputDir) :
+ new \DirectoryIterator($inputDir);
+
+ if (!empty($ignoreFiles)) {
+ $directoryIterator = $recursive ?
+ new IgnoreFilesRecursiveFilterIterator($directoryIterator, $ignoreFiles) :
+ new IgnoreFilesFilterIterator($directoryIterator, $ignoreFiles);
+ }
+
+ $iterator = $recursive ?
+ new \RecursiveIteratorIterator($directoryIterator) :
+ new \IteratorIterator($directoryIterator);
+
+ $fileList = [];
+ foreach ($iterator as $file) {
+ if ($file instanceof \SplFileInfo) {
+ $fileList[] = $file->getPathname();
+ }
+ }
+ return $fileList;
+ }
+
+ /**
+ * Search files from glob pattern.
+ *
+ * @param string $globPattern
+ * @param int $flags
+ * @param bool $recursive
+ * @return array Searched file list
+ */
+ public static function globFileSearch($globPattern, $flags = 0, $recursive = true)
+ {
+ $flags = (int)$flags;
+ $recursive = (bool)$recursive;
+ $files = glob($globPattern, $flags);
+ if (!$recursive) {
+ return $files;
+ }
+ foreach (glob(dirname($globPattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
+ $files = array_merge($files, self::globFileSearch($dir . '/' . basename($globPattern), $flags, $recursive));
+ }
+ return $files;
+ }
+
+ /**
+ * Search files from regex pattern.
+ *
+ * @param string $folder
+ * @param string $pattern
+ * @param bool $recursive
+ * @return array Searched file list
+ */
+ public static function regexFileSearch($folder, $pattern, $recursive = true)
+ {
+ $directoryIterator = $recursive ? new \RecursiveDirectoryIterator($folder) : new \DirectoryIterator($folder);
+ $iterator = $recursive ? new \RecursiveIteratorIterator($directoryIterator) : new \IteratorIterator($directoryIterator);
+ $regexIterator = new \RegexIterator($iterator, $pattern, \RegexIterator::MATCH);
+ $fileList = [];
+ foreach ($regexIterator as $file) {
+ if ($file instanceof \SplFileInfo) {
+ $fileList[] = $file->getPathname();
+ }
+ }
+ return $fileList;
+ }
+
+ /**
+ * Convert bytes to human size.
+ *
+ * @param int $size Size bytes
+ * @param string|null $unit Unit support 'GB', 'MB', 'KB'
+ * @return string
+ */
+ public static function humanSize($size, $unit = null)
+ {
+ if (($unit === null && $size >= 1 << 30) || $unit === "GB") {
+ return number_format($size / (1 << 30), 2) . "GB";
+ }
+ if (($unit === null && $size >= 1 << 20) || $unit === "MB") {
+ return number_format($size / (1 << 20), 2) . "MB";
+ }
+ if (($unit === null && $size >= 1 << 10) || $unit === "KB") {
+ return number_format($size / (1 << 10), 2) . "KB";
+ }
+ return number_format($size) . " bytes";
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Util/Iterator/IgnoreFilesFilterIterator.php b/vendor/nelexa/zip/src/PhpZip/Util/Iterator/IgnoreFilesFilterIterator.php
new file mode 100644
index 0000000..40e8fe0
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Util/Iterator/IgnoreFilesFilterIterator.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace PhpZip\Util\Iterator;
+
+use PhpZip\Util\StringUtil;
+
+/**
+ * Iterator for ignore files.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class IgnoreFilesFilterIterator extends \FilterIterator
+{
+ /**
+ * Ignore list files
+ *
+ * @var array
+ */
+ private $ignoreFiles = ['..'];
+
+ /**
+ * @param \Iterator $iterator
+ * @param array $ignoreFiles
+ */
+ public function __construct(\Iterator $iterator, array $ignoreFiles)
+ {
+ parent::__construct($iterator);
+ $this->ignoreFiles = array_merge($this->ignoreFiles, $ignoreFiles);
+ }
+
+ /**
+ * Check whether the current element of the iterator is acceptable
+ * @link http://php.net/manual/en/filteriterator.accept.php
+ * @return bool true if the current element is acceptable, otherwise false.
+ * @since 5.1.0
+ */
+ public function accept()
+ {
+ /**
+ * @var \SplFileInfo $fileInfo
+ */
+ $fileInfo = $this->current();
+ $pathname = str_replace('\\', '/', $fileInfo->getPathname());
+ foreach ($this->ignoreFiles as $ignoreFile) {
+ // handler dir and sub dir
+ if ($fileInfo->isDir()
+ && StringUtil::endsWith($ignoreFile, '/')
+ && StringUtil::endsWith($pathname, substr($ignoreFile, 0, -1))
+ ) {
+ return false;
+ }
+
+ // handler filename
+ if (StringUtil::endsWith($pathname, $ignoreFile)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Util/Iterator/IgnoreFilesRecursiveFilterIterator.php b/vendor/nelexa/zip/src/PhpZip/Util/Iterator/IgnoreFilesRecursiveFilterIterator.php
new file mode 100644
index 0000000..7781576
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Util/Iterator/IgnoreFilesRecursiveFilterIterator.php
@@ -0,0 +1,70 @@
+<?php
+
+namespace PhpZip\Util\Iterator;
+
+use PhpZip\Util\StringUtil;
+
+/**
+ * Recursive iterator for ignore files.
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class IgnoreFilesRecursiveFilterIterator extends \RecursiveFilterIterator
+{
+
+ /**
+ * Ignore list files
+ *
+ * @var array
+ */
+ private $ignoreFiles = ['..'];
+
+ /**
+ * @param \RecursiveIterator $iterator
+ * @param array $ignoreFiles
+ */
+ public function __construct(\RecursiveIterator $iterator, array $ignoreFiles)
+ {
+ parent::__construct($iterator);
+ $this->ignoreFiles = array_merge($this->ignoreFiles, $ignoreFiles);
+ }
+
+ /**
+ * Check whether the current element of the iterator is acceptable
+ * @link http://php.net/manual/en/filteriterator.accept.php
+ * @return bool true if the current element is acceptable, otherwise false.
+ * @since 5.1.0
+ */
+ public function accept()
+ {
+ /**
+ * @var \SplFileInfo $fileInfo
+ */
+ $fileInfo = $this->current();
+ $pathname = str_replace('\\', '/', $fileInfo->getPathname());
+ foreach ($this->ignoreFiles as $ignoreFile) {
+ // handler dir and sub dir
+ if ($fileInfo->isDir()
+ && $ignoreFile[strlen($ignoreFile) - 1] === '/'
+ && StringUtil::endsWith($pathname, substr($ignoreFile, 0, -1))
+ ) {
+ return false;
+ }
+
+ // handler filename
+ if (StringUtil::endsWith($pathname, $ignoreFile)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @return IgnoreFilesRecursiveFilterIterator
+ */
+ public function getChildren()
+ {
+ return new self($this->getInnerIterator()->getChildren(), $this->ignoreFiles);
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Util/PackUtil.php b/vendor/nelexa/zip/src/PhpZip/Util/PackUtil.php
new file mode 100644
index 0000000..c622360
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Util/PackUtil.php
@@ -0,0 +1,65 @@
+<?php
+
+namespace PhpZip\Util;
+
+use PhpZip\Exception\ZipException;
+
+/**
+ * Pack util
+ *
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class PackUtil
+{
+
+ /**
+ * @param int|string $longValue
+ * @return string
+ */
+ public static function packLongLE($longValue)
+ {
+ if (PHP_INT_SIZE === 8 && PHP_VERSION_ID >= 506030) {
+ return pack("P", $longValue);
+ }
+
+ $left = 0xffffffff00000000;
+ $right = 0x00000000ffffffff;
+
+ $r = ($longValue & $left) >> 32;
+ $l = $longValue & $right;
+
+ return pack('VV', $l, $r);
+ }
+
+ /**
+ * @param string|int $value
+ * @return int
+ * @throws ZipException
+ */
+ public static function unpackLongLE($value)
+ {
+ if (PHP_INT_SIZE === 8 && PHP_VERSION_ID >= 506030) {
+ return unpack('P', $value)[1];
+ }
+ $unpack = unpack('Va/Vb', $value);
+ return $unpack['a'] + ($unpack['b'] << 32);
+ }
+
+ /**
+ * Cast to signed int 32-bit
+ *
+ * @param int $int
+ * @return int
+ */
+ public static function toSignedInt32($int)
+ {
+ if (PHP_INT_SIZE === 8) {
+ $int = $int & 0xffffffff;
+ if ($int & 0x80000000) {
+ return $int - 0x100000000;
+ }
+ }
+ return $int;
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/Util/StringUtil.php b/vendor/nelexa/zip/src/PhpZip/Util/StringUtil.php
new file mode 100644
index 0000000..0b75040
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/Util/StringUtil.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace PhpZip\Util;
+
+/**
+ * String Util
+ */
+class StringUtil
+{
+
+ /**
+ * @param string $haystack
+ * @param string $needle
+ * @return bool
+ */
+ public static function startsWith($haystack, $needle)
+ {
+ return $needle === "" || strrpos($haystack, $needle, -strlen($haystack)) !== false;
+ }
+
+ /**
+ * @param string $haystack
+ * @param string $needle
+ * @return bool
+ */
+ public static function endsWith($haystack, $needle)
+ {
+ return $needle === "" || (($temp = strlen($haystack) - strlen($needle)) >= 0
+ && strpos($haystack, $needle, $temp) !== false);
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/ZipFile.php b/vendor/nelexa/zip/src/PhpZip/ZipFile.php
new file mode 100644
index 0000000..a5db71a
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/ZipFile.php
@@ -0,0 +1,1512 @@
+<?php
+
+namespace PhpZip;
+
+use PhpZip\Exception\InvalidArgumentException;
+use PhpZip\Exception\ZipException;
+use PhpZip\Exception\ZipNotFoundEntry;
+use PhpZip\Exception\ZipUnsupportMethod;
+use PhpZip\Model\Entry\ZipNewEntry;
+use PhpZip\Model\ZipEntry;
+use PhpZip\Model\ZipEntryMatcher;
+use PhpZip\Model\ZipInfo;
+use PhpZip\Model\ZipModel;
+use PhpZip\Stream\ResponseStream;
+use PhpZip\Stream\ZipInputStream;
+use PhpZip\Stream\ZipInputStreamInterface;
+use PhpZip\Stream\ZipOutputStream;
+use PhpZip\Util\FilesUtil;
+use PhpZip\Util\StringUtil;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Create, open .ZIP files, modify, get info and extract files.
+ *
+ * Implemented support traditional PKWARE encryption and WinZip AES encryption.
+ * Implemented support ZIP64.
+ * Implemented support skip a preamble like the one found in self extracting archives.
+ * Support ZipAlign functional.
+ *
+ * @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+class ZipFile implements ZipFileInterface
+{
+ /**
+ * Allow compression methods.
+ * @var int[]
+ */
+ private static $allowCompressionMethods = [
+ self::METHOD_STORED,
+ self::METHOD_DEFLATED,
+ self::METHOD_BZIP2,
+ ZipEntry::UNKNOWN
+ ];
+
+ /**
+ * Allow encryption methods.
+ * @var int[]
+ */
+ private static $allowEncryptionMethods = [
+ self::ENCRYPTION_METHOD_TRADITIONAL,
+ self::ENCRYPTION_METHOD_WINZIP_AES_128,
+ self::ENCRYPTION_METHOD_WINZIP_AES_192,
+ self::ENCRYPTION_METHOD_WINZIP_AES_256
+ ];
+
+ /**
+ * Default mime types.
+ *
+ * @var array
+ */
+ private static $defaultMimeTypes = [
+ 'zip' => 'application/zip',
+ 'apk' => 'application/vnd.android.package-archive',
+ 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+ 'jar' => 'application/java-archive',
+ 'epub' => 'application/epub+zip'
+ ];
+
+ /**
+ * Input seekable input stream.
+ *
+ * @var ZipInputStreamInterface
+ */
+ protected $inputStream;
+ /**
+ * @var ZipModel
+ */
+ protected $zipModel;
+
+ /**
+ * ZipFile constructor.
+ */
+ public function __construct()
+ {
+ $this->zipModel = new ZipModel();
+ }
+
+ /**
+ * Open zip archive from file
+ *
+ * @param string $filename
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException if file doesn't exists.
+ * @throws ZipException if can't open file.
+ */
+ public function openFile($filename)
+ {
+ if (!file_exists($filename)) {
+ throw new InvalidArgumentException("File $filename can't exists.");
+ }
+ if (!($handle = @fopen($filename, 'rb'))) {
+ throw new ZipException("File $filename can't open.");
+ }
+ $this->openFromStream($handle);
+ return $this;
+ }
+
+ /**
+ * Open zip archive from raw string data.
+ *
+ * @param string $data
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException if data not available.
+ * @throws ZipException if can't open temp stream.
+ */
+ public function openFromString($data)
+ {
+ if (null === $data || strlen($data) === 0) {
+ throw new InvalidArgumentException("Data not available");
+ }
+ if (!($handle = fopen('php://temp', 'r+b'))) {
+ throw new ZipException("Can't open temp stream.");
+ }
+ fwrite($handle, $data);
+ rewind($handle);
+ $this->openFromStream($handle);
+ return $this;
+ }
+
+ /**
+ * Open zip archive from stream resource
+ *
+ * @param resource $handle
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException Invalid stream resource
+ * or resource cannot seekable stream
+ */
+ public function openFromStream($handle)
+ {
+ if (!is_resource($handle)) {
+ throw new InvalidArgumentException("Invalid stream resource.");
+ }
+ $type = get_resource_type($handle);
+ if ('stream' !== $type) {
+ throw new InvalidArgumentException("Invalid resource type - $type.");
+ }
+ $meta = stream_get_meta_data($handle);
+ if ('dir' === $meta['stream_type']) {
+ throw new InvalidArgumentException("Invalid stream type - {$meta['stream_type']}.");
+ }
+ if (!$meta['seekable']) {
+ throw new InvalidArgumentException("Resource cannot seekable stream.");
+ }
+ $this->inputStream = new ZipInputStream($handle);
+ $this->zipModel = $this->inputStream->readZip();
+ return $this;
+ }
+
+ /**
+ * @return string[] Returns the list files.
+ */
+ public function getListFiles()
+ {
+ return array_keys($this->zipModel->getEntries());
+ }
+
+ /**
+ * @return int Returns the number of entries in this ZIP file.
+ */
+ public function count()
+ {
+ return $this->zipModel->count();
+ }
+
+ /**
+ * Returns the file comment.
+ *
+ * @return string The file comment.
+ */
+ public function getArchiveComment()
+ {
+ return $this->zipModel->getArchiveComment();
+ }
+
+ /**
+ * Set archive comment.
+ *
+ * @param null|string $comment
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException Length comment out of range
+ */
+ public function setArchiveComment($comment = null)
+ {
+ $this->zipModel->setArchiveComment($comment);
+ return $this;
+ }
+
+ /**
+ * Checks that the entry in the archive is a directory.
+ * Returns true if and only if this ZIP entry represents a directory entry
+ * (i.e. end with '/').
+ *
+ * @param string $entryName
+ * @return bool
+ * @throws ZipNotFoundEntry
+ */
+ public function isDirectory($entryName)
+ {
+ return $this->zipModel->getEntry($entryName)->isDirectory();
+ }
+
+ /**
+ * Returns entry comment.
+ *
+ * @param string $entryName
+ * @return string
+ * @throws ZipNotFoundEntry
+ */
+ public function getEntryComment($entryName)
+ {
+ return $this->zipModel->getEntry($entryName)->getComment();
+ }
+
+ /**
+ * Set entry comment.
+ *
+ * @param string $entryName
+ * @param string|null $comment
+ * @return ZipFileInterface
+ * @throws ZipNotFoundEntry
+ */
+ public function setEntryComment($entryName, $comment = null)
+ {
+ $this->zipModel->getEntryForChanges($entryName)->setComment($comment);
+ return $this;
+ }
+
+ /**
+ * Returns the entry contents.
+ *
+ * @param string $entryName
+ * @return string
+ */
+ public function getEntryContents($entryName)
+ {
+ return $this->zipModel->getEntry($entryName)->getEntryContent();
+ }
+
+ /**
+ * Checks if there is an entry in the archive.
+ *
+ * @param string $entryName
+ * @return bool
+ */
+ public function hasEntry($entryName)
+ {
+ return $this->zipModel->hasEntry($entryName);
+ }
+
+ /**
+ * Get info by entry.
+ *
+ * @param string|ZipEntry $entryName
+ * @return ZipInfo
+ * @throws ZipNotFoundEntry
+ */
+ public function getEntryInfo($entryName)
+ {
+ return new ZipInfo($this->zipModel->getEntry($entryName));
+ }
+
+ /**
+ * Get info by all entries.
+ *
+ * @return ZipInfo[]
+ */
+ public function getAllInfo()
+ {
+ return array_map([$this, 'getEntryInfo'], $this->zipModel->getEntries());
+ }
+
+ /**
+ * @return ZipEntryMatcher
+ */
+ public function matcher()
+ {
+ return $this->zipModel->matcher();
+ }
+
+ /**
+ * Extract the archive contents
+ *
+ * Extract the complete archive or the given files to the specified destination.
+ *
+ * @param string $destination Location where to extract the files.
+ * @param array|string|null $entries The entries to extract. It accepts either
+ * a single entry name or an array of names.
+ * @return ZipFileInterface
+ * @throws ZipException
+ */
+ public function extractTo($destination, $entries = null)
+ {
+ if (!file_exists($destination)) {
+ throw new ZipException("Destination " . $destination . " not found");
+ }
+ if (!is_dir($destination)) {
+ throw new ZipException("Destination is not directory");
+ }
+ if (!is_writable($destination)) {
+ throw new ZipException("Destination is not writable directory");
+ }
+
+ $zipEntries = $this->zipModel->getEntries();
+
+ if (!empty($entries)) {
+ if (is_string($entries)) {
+ $entries = (array)$entries;
+ }
+ if (is_array($entries)) {
+ $entries = array_unique($entries);
+ $flipEntries = array_flip($entries);
+ $zipEntries = array_filter($zipEntries, function (ZipEntry $zipEntry) use ($flipEntries) {
+ return isset($flipEntries[$zipEntry->getName()]);
+ });
+ }
+ }
+
+ foreach ($zipEntries as $entry) {
+ $file = $destination . DIRECTORY_SEPARATOR . $entry->getName();
+ if ($entry->isDirectory()) {
+ if (!is_dir($file)) {
+ if (!mkdir($file, 0755, true)) {
+ throw new ZipException("Can not create dir " . $file);
+ }
+ chmod($file, 0755);
+ touch($file, $entry->getTime());
+ }
+ continue;
+ }
+ $dir = dirname($file);
+ if (!is_dir($dir)) {
+ if (!mkdir($dir, 0755, true)) {
+ throw new ZipException("Can not create dir " . $dir);
+ }
+ chmod($dir, 0755);
+ touch($dir, $entry->getTime());
+ }
+ if (false === file_put_contents($file, $entry->getEntryContent())) {
+ throw new ZipException('Can not extract file ' . $entry->getName());
+ }
+ touch($file, $entry->getTime());
+ }
+ return $this;
+ }
+
+ /**
+ * Add entry from the string.
+ *
+ * @param string $localName Zip entry name.
+ * @param string $contents String contents.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException If incorrect data or entry name.
+ * @throws ZipUnsupportMethod
+ * @see ZipFileInterface::METHOD_STORED
+ * @see ZipFileInterface::METHOD_DEFLATED
+ * @see ZipFileInterface::METHOD_BZIP2
+ */
+ public function addFromString($localName, $contents, $compressionMethod = null)
+ {
+ if (null === $contents) {
+ throw new InvalidArgumentException("Contents is null");
+ }
+ $localName = (string)$localName;
+ if (null === $localName || 0 === strlen($localName)) {
+ throw new InvalidArgumentException("Incorrect entry name " . $localName);
+ }
+ $contents = (string)$contents;
+ $length = strlen($contents);
+ if (null === $compressionMethod) {
+ if ($length >= 512) {
+ $compressionMethod = ZipEntry::UNKNOWN;
+ } else {
+ $compressionMethod = ZipFileInterface::METHOD_STORED;
+ }
+ } elseif (!in_array($compressionMethod, self::$allowCompressionMethods, true)) {
+ throw new ZipUnsupportMethod('Unsupported compression method ' . $compressionMethod);
+ }
+ $externalAttributes = 0100644 << 16;
+
+ $entry = new ZipNewEntry($contents);
+ $entry->setName($localName);
+ $entry->setMethod($compressionMethod);
+ $entry->setTime(time());
+ $entry->setExternalAttributes($externalAttributes);
+
+ $this->zipModel->addEntry($entry);
+ return $this;
+ }
+
+ /**
+ * Add entry from the file.
+ *
+ * @param string $filename Destination file.
+ * @param string|null $localName Zip Entry name.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @throws ZipUnsupportMethod
+ * @see ZipFileInterface::METHOD_STORED
+ * @see ZipFileInterface::METHOD_DEFLATED
+ * @see ZipFileInterface::METHOD_BZIP2
+ */
+ public function addFile($filename, $localName = null, $compressionMethod = null)
+ {
+ if (null === $filename) {
+ throw new InvalidArgumentException("Filename is null");
+ }
+ if (!is_file($filename)) {
+ throw new InvalidArgumentException("File $filename is not exists");
+ }
+
+ if (null === $compressionMethod) {
+ if (function_exists('mime_content_type')) {
+ $mimeType = @mime_content_type($filename);
+ $type = strtok($mimeType, '/');
+ if ('image' === $type) {
+ $compressionMethod = ZipFileInterface::METHOD_STORED;
+ } elseif ('text' === $type && filesize($filename) < 150) {
+ $compressionMethod = ZipFileInterface::METHOD_STORED;
+ } else {
+ $compressionMethod = ZipEntry::UNKNOWN;
+ }
+ } elseif (@filesize($filename) >= 512) {
+ $compressionMethod = ZipEntry::UNKNOWN;
+ } else {
+ $compressionMethod = ZipFileInterface::METHOD_STORED;
+ }
+ } elseif (!in_array($compressionMethod, self::$allowCompressionMethods, true)) {
+ throw new ZipUnsupportMethod('Unsupported method ' . $compressionMethod);
+ }
+
+ if (!($handle = @fopen($filename, 'rb'))) {
+ throw new InvalidArgumentException('File ' . $filename . ' can not open.');
+ }
+ if (null === $localName) {
+ $localName = basename($filename);
+ }
+ $this->addFromStream($handle, $localName, $compressionMethod);
+ $this->zipModel->getEntry($localName)->setTime(filemtime($filename));
+ return $this;
+ }
+
+ /**
+ * Add entry from the stream.
+ *
+ * @param resource $stream Stream resource.
+ * @param string $localName Zip Entry name.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @throws ZipUnsupportMethod
+ * @see ZipFileInterface::METHOD_STORED
+ * @see ZipFileInterface::METHOD_DEFLATED
+ * @see ZipFileInterface::METHOD_BZIP2
+ */
+ public function addFromStream($stream, $localName, $compressionMethod = null)
+ {
+ if (!is_resource($stream)) {
+ throw new InvalidArgumentException("stream is not resource");
+ }
+ $localName = (string)$localName;
+ if (empty($localName)) {
+ throw new InvalidArgumentException("Incorrect entry name " . $localName);
+ }
+ $fstat = fstat($stream);
+ $length = $fstat['size'];
+ if (null === $compressionMethod) {
+ if ($length >= 512) {
+ $compressionMethod = ZipEntry::UNKNOWN;
+ } else {
+ $compressionMethod = ZipFileInterface::METHOD_STORED;
+ }
+ } elseif (!in_array($compressionMethod, self::$allowCompressionMethods, true)) {
+ throw new ZipUnsupportMethod('Unsupported method ' . $compressionMethod);
+ }
+
+ $mode = sprintf('%o', $fstat['mode']);
+ $externalAttributes = (octdec($mode) & 0xffff) << 16;
+
+ $entry = new ZipNewEntry($stream);
+ $entry->setName($localName);
+ $entry->setMethod($compressionMethod);
+ $entry->setTime(time());
+ $entry->setExternalAttributes($externalAttributes);
+
+ $this->zipModel->addEntry($entry);
+ return $this;
+ }
+
+ /**
+ * Add an empty directory in the zip archive.
+ *
+ * @param string $dirName
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ */
+ public function addEmptyDir($dirName)
+ {
+ $dirName = (string)$dirName;
+ if (strlen($dirName) === 0) {
+ throw new InvalidArgumentException("DirName empty");
+ }
+ $dirName = rtrim($dirName, '/') . '/';
+ $externalAttributes = 040755 << 16;
+
+ $entry = new ZipNewEntry();
+ $entry->setName($dirName);
+ $entry->setTime(time());
+ $entry->setMethod(ZipFileInterface::METHOD_STORED);
+ $entry->setSize(0);
+ $entry->setCompressedSize(0);
+ $entry->setCrc(0);
+ $entry->setExternalAttributes($externalAttributes);
+
+ $this->zipModel->addEntry($entry);
+ return $this;
+ }
+
+ /**
+ * Add directory not recursively to the zip archive.
+ *
+ * @param string $inputDir Input directory
+ * @param string $localPath Add files to this directory, or the root.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ */
+ public function addDir($inputDir, $localPath = "/", $compressionMethod = null)
+ {
+ $inputDir = (string)$inputDir;
+ if (null === $inputDir || strlen($inputDir) === 0) {
+ throw new InvalidArgumentException('Input dir empty');
+ }
+ if (!is_dir($inputDir)) {
+ throw new InvalidArgumentException('Directory ' . $inputDir . ' can\'t exists');
+ }
+ $inputDir = rtrim($inputDir, '/\\') . DIRECTORY_SEPARATOR;
+
+ $directoryIterator = new \DirectoryIterator($inputDir);
+ return $this->addFilesFromIterator($directoryIterator, $localPath, $compressionMethod);
+ }
+
+ /**
+ * Add recursive directory to the zip archive.
+ *
+ * @param string $inputDir Input directory
+ * @param string $localPath Add files to this directory, or the root.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @throws ZipUnsupportMethod
+ * @see ZipFileInterface::METHOD_STORED
+ * @see ZipFileInterface::METHOD_DEFLATED
+ * @see ZipFileInterface::METHOD_BZIP2
+ */
+ public function addDirRecursive($inputDir, $localPath = "/", $compressionMethod = null)
+ {
+ $inputDir = (string)$inputDir;
+ if (null === $inputDir || strlen($inputDir) === 0) {
+ throw new InvalidArgumentException('Input dir empty');
+ }
+ if (!is_dir($inputDir)) {
+ throw new InvalidArgumentException('Directory ' . $inputDir . ' can\'t exists');
+ }
+ $inputDir = rtrim($inputDir, '/\\') . DIRECTORY_SEPARATOR;
+
+ $directoryIterator = new \RecursiveDirectoryIterator($inputDir);
+ return $this->addFilesFromIterator($directoryIterator, $localPath, $compressionMethod);
+ }
+
+ /**
+ * Add directories from directory iterator.
+ *
+ * @param \Iterator $iterator Directory iterator.
+ * @param string $localPath Add files to this directory, or the root.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @throws ZipUnsupportMethod
+ * @see ZipFileInterface::METHOD_STORED
+ * @see ZipFileInterface::METHOD_DEFLATED
+ * @see ZipFileInterface::METHOD_BZIP2
+ */
+ public function addFilesFromIterator(
+ \Iterator $iterator,
+ $localPath = '/',
+ $compressionMethod = null
+ ) {
+ $localPath = (string)$localPath;
+ if (null !== $localPath && 0 !== strlen($localPath)) {
+ $localPath = rtrim($localPath, '/');
+ } else {
+ $localPath = "";
+ }
+
+ $iterator = $iterator instanceof \RecursiveIterator ?
+ new \RecursiveIteratorIterator($iterator) :
+ new \IteratorIterator($iterator);
+ /**
+ * @var string[] $files
+ * @var string $path
+ */
+ $files = [];
+ foreach ($iterator as $file) {
+ if ($file instanceof \SplFileInfo) {
+ if ('..' === $file->getBasename()) {
+ continue;
+ }
+ if ('.' === $file->getBasename()) {
+ $files[] = dirname($file->getPathname());
+ } else {
+ $files[] = $file->getPathname();
+ }
+ }
+ }
+ if (empty($files)) {
+ return $this;
+ }
+
+ natcasesort($files);
+ $path = array_shift($files);
+ foreach ($files as $file) {
+ $relativePath = str_replace($path, $localPath, $file);
+ $relativePath = ltrim($relativePath, '/');
+ if (is_dir($file)) {
+ FilesUtil::isEmptyDir($file) && $this->addEmptyDir($relativePath);
+ } elseif (is_file($file)) {
+ $this->addFile($file, $relativePath, $compressionMethod);
+ }
+ }
+ return $this;
+ }
+
+ /**
+ * Add files from glob pattern.
+ *
+ * @param string $inputDir Input directory
+ * @param string $globPattern Glob pattern.
+ * @param string|null $localPath Add files to this directory, or the root.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @sse https://en.wikipedia.org/wiki/Glob_(programming) Glob pattern syntax
+ */
+ public function addFilesFromGlob($inputDir, $globPattern, $localPath = '/', $compressionMethod = null)
+ {
+ return $this->addGlob($inputDir, $globPattern, $localPath, false, $compressionMethod);
+ }
+
+ /**
+ * Add files from glob pattern.
+ *
+ * @param string $inputDir Input directory
+ * @param string $globPattern Glob pattern.
+ * @param string|null $localPath Add files to this directory, or the root.
+ * @param bool $recursive Recursive search.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @sse https://en.wikipedia.org/wiki/Glob_(programming) Glob pattern syntax
+ */
+ private function addGlob(
+ $inputDir,
+ $globPattern,
+ $localPath = '/',
+ $recursive = true,
+ $compressionMethod = null
+ ) {
+ $inputDir = (string)$inputDir;
+ if (null === $inputDir || 0 === strlen($inputDir)) {
+ throw new InvalidArgumentException('Input dir empty');
+ }
+ if (!is_dir($inputDir)) {
+ throw new InvalidArgumentException('Directory ' . $inputDir . ' can\'t exists');
+ }
+ $globPattern = (string)$globPattern;
+ if (empty($globPattern)) {
+ throw new InvalidArgumentException("glob pattern empty");
+ }
+
+ $inputDir = rtrim($inputDir, '/\\') . DIRECTORY_SEPARATOR;
+ $globPattern = $inputDir . $globPattern;
+
+ $filesFound = FilesUtil::globFileSearch($globPattern, GLOB_BRACE, $recursive);
+ if (false === $filesFound || empty($filesFound)) {
+ return $this;
+ }
+ if (!empty($localPath) && is_string($localPath)) {
+ $localPath = rtrim($localPath, '/') . '/';
+ } else {
+ $localPath = "/";
+ }
+
+ /**
+ * @var string $file
+ */
+ foreach ($filesFound as $file) {
+ $filename = str_replace($inputDir, $localPath, $file);
+ $filename = ltrim($filename, '/');
+ if (is_dir($file)) {
+ FilesUtil::isEmptyDir($file) && $this->addEmptyDir($filename);
+ } elseif (is_file($file)) {
+ $this->addFile($file, $filename, $compressionMethod);
+ }
+ }
+ return $this;
+ }
+
+ /**
+ * Add files recursively from glob pattern.
+ *
+ * @param string $inputDir Input directory
+ * @param string $globPattern Glob pattern.
+ * @param string|null $localPath Add files to this directory, or the root.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @sse https://en.wikipedia.org/wiki/Glob_(programming) Glob pattern syntax
+ */
+ public function addFilesFromGlobRecursive($inputDir, $globPattern, $localPath = '/', $compressionMethod = null)
+ {
+ return $this->addGlob($inputDir, $globPattern, $localPath, true, $compressionMethod);
+ }
+
+ /**
+ * Add files from regex pattern.
+ *
+ * @param string $inputDir Search files in this directory.
+ * @param string $regexPattern Regex pattern.
+ * @param string|null $localPath Add files to this directory, or the root.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @internal param bool $recursive Recursive search.
+ */
+ public function addFilesFromRegex($inputDir, $regexPattern, $localPath = "/", $compressionMethod = null)
+ {
+ return $this->addRegex($inputDir, $regexPattern, $localPath, false, $compressionMethod);
+ }
+
+ /**
+ * Add files from regex pattern.
+ *
+ * @param string $inputDir Search files in this directory.
+ * @param string $regexPattern Regex pattern.
+ * @param string|null $localPath Add files to this directory, or the root.
+ * @param bool $recursive Recursive search.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ */
+ private function addRegex(
+ $inputDir,
+ $regexPattern,
+ $localPath = "/",
+ $recursive = true,
+ $compressionMethod = null
+ ) {
+ $regexPattern = (string)$regexPattern;
+ if (empty($regexPattern)) {
+ throw new InvalidArgumentException("regex pattern empty");
+ }
+ $inputDir = (string)$inputDir;
+ if (null === $inputDir || 0 === strlen($inputDir)) {
+ throw new InvalidArgumentException('Input dir empty');
+ }
+ if (!is_dir($inputDir)) {
+ throw new InvalidArgumentException('Directory ' . $inputDir . ' can\'t exists');
+ }
+ $inputDir = rtrim($inputDir, '/\\') . DIRECTORY_SEPARATOR;
+
+ $files = FilesUtil::regexFileSearch($inputDir, $regexPattern, $recursive);
+ if (false === $files || empty($files)) {
+ return $this;
+ }
+ if (!empty($localPath) && is_string($localPath)) {
+ $localPath = rtrim($localPath, '/') . '/';
+ } else {
+ $localPath = "/";
+ }
+ $inputDir = rtrim($inputDir, '/\\') . DIRECTORY_SEPARATOR;
+
+ /**
+ * @var string $file
+ */
+ foreach ($files as $file) {
+ $filename = str_replace($inputDir, $localPath, $file);
+ $filename = ltrim($filename, '/');
+ if (is_dir($file)) {
+ FilesUtil::isEmptyDir($file) && $this->addEmptyDir($filename);
+ } elseif (is_file($file)) {
+ $this->addFile($file, $filename, $compressionMethod);
+ }
+ }
+ return $this;
+ }
+
+ /**
+ * Add files recursively from regex pattern.
+ *
+ * @param string $inputDir Search files in this directory.
+ * @param string $regexPattern Regex pattern.
+ * @param string|null $localPath Add files to this directory, or the root.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @internal param bool $recursive Recursive search.
+ */
+ public function addFilesFromRegexRecursive($inputDir, $regexPattern, $localPath = "/", $compressionMethod = null)
+ {
+ return $this->addRegex($inputDir, $regexPattern, $localPath, true, $compressionMethod);
+ }
+
+ /**
+ * Add array data to archive.
+ * Keys is local names.
+ * Values is contents.
+ *
+ * @param array $mapData Associative array for added to zip.
+ */
+ public function addAll(array $mapData)
+ {
+ foreach ($mapData as $localName => $content) {
+ $this[$localName] = $content;
+ }
+ }
+
+ /**
+ * Rename the entry.
+ *
+ * @param string $oldName Old entry name.
+ * @param string $newName New entry name.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @throws ZipNotFoundEntry
+ */
+ public function rename($oldName, $newName)
+ {
+ if (null === $oldName || null === $newName) {
+ throw new InvalidArgumentException("name is null");
+ }
+ if ($oldName !== $newName) {
+ $this->zipModel->renameEntry($oldName, $newName);
+ }
+ return $this;
+ }
+
+ /**
+ * Delete entry by name.
+ *
+ * @param string $entryName Zip Entry name.
+ * @return ZipFileInterface
+ * @throws ZipNotFoundEntry If entry not found.
+ */
+ public function deleteFromName($entryName)
+ {
+ $entryName = (string)$entryName;
+ if (!$this->zipModel->deleteEntry($entryName)) {
+ throw new ZipNotFoundEntry("Entry " . $entryName . ' not found!');
+ }
+ return $this;
+ }
+
+ /**
+ * Delete entries by glob pattern.
+ *
+ * @param string $globPattern Glob pattern
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @sse https://en.wikipedia.org/wiki/Glob_(programming) Glob pattern syntax
+ */
+ public function deleteFromGlob($globPattern)
+ {
+ if (null === $globPattern || !is_string($globPattern) || empty($globPattern)) {
+ throw new InvalidArgumentException("Glob pattern is empty");
+ }
+ $globPattern = '~' . FilesUtil::convertGlobToRegEx($globPattern) . '~si';
+ $this->deleteFromRegex($globPattern);
+ return $this;
+ }
+
+ /**
+ * Delete entries by regex pattern.
+ *
+ * @param string $regexPattern Regex pattern
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ */
+ public function deleteFromRegex($regexPattern)
+ {
+ if (null === $regexPattern || !is_string($regexPattern) || empty($regexPattern)) {
+ throw new InvalidArgumentException("Regex pattern is empty.");
+ }
+ $this->matcher()->match($regexPattern)->delete();
+ return $this;
+ }
+
+ /**
+ * Delete all entries
+ * @return ZipFileInterface
+ */
+ public function deleteAll()
+ {
+ $this->zipModel->deleteAll();
+ return $this;
+ }
+
+ /**
+ * Set compression level for new entries.
+ *
+ * @param int $compressionLevel
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @see ZipFileInterface::LEVEL_DEFAULT_COMPRESSION
+ * @see ZipFileInterface::LEVEL_SUPER_FAST
+ * @see ZipFileInterface::LEVEL_FAST
+ * @see ZipFileInterface::LEVEL_BEST_COMPRESSION
+ */
+ public function setCompressionLevel($compressionLevel = ZipFileInterface::LEVEL_DEFAULT_COMPRESSION)
+ {
+ if ($compressionLevel < ZipFileInterface::LEVEL_DEFAULT_COMPRESSION ||
+ $compressionLevel > ZipFileInterface::LEVEL_BEST_COMPRESSION
+ ) {
+ throw new InvalidArgumentException('Invalid compression level. Minimum level ' .
+ ZipFileInterface::LEVEL_DEFAULT_COMPRESSION . '. Maximum level ' . ZipFileInterface::LEVEL_BEST_COMPRESSION);
+ }
+ $this->matcher()->all()->invoke(function ($entry) use ($compressionLevel) {
+ $this->setCompressionLevelEntry($entry, $compressionLevel);
+ });
+ return $this;
+ }
+
+ /**
+ * @param string $entryName
+ * @param int $compressionLevel
+ * @return ZipFileInterface
+ * @throws ZipException
+ * @see ZipFileInterface::LEVEL_DEFAULT_COMPRESSION
+ * @see ZipFileInterface::LEVEL_SUPER_FAST
+ * @see ZipFileInterface::LEVEL_FAST
+ * @see ZipFileInterface::LEVEL_BEST_COMPRESSION
+ */
+ public function setCompressionLevelEntry($entryName, $compressionLevel)
+ {
+ if (null !== $compressionLevel) {
+ if ($compressionLevel < ZipFileInterface::LEVEL_DEFAULT_COMPRESSION ||
+ $compressionLevel > ZipFileInterface::LEVEL_BEST_COMPRESSION
+ ) {
+ throw new InvalidArgumentException('Invalid compression level. Minimum level ' .
+ ZipFileInterface::LEVEL_DEFAULT_COMPRESSION . '. Maximum level ' . ZipFileInterface::LEVEL_BEST_COMPRESSION);
+ }
+ $entry = $this->zipModel->getEntry($entryName);
+ if ($entry->getCompressionLevel() !== $compressionLevel) {
+ $entry = $this->zipModel->getEntryForChanges($entry);
+ $entry->setCompressionLevel($compressionLevel);
+ }
+ }
+ return $this;
+ }
+
+ /**
+ * @param string $entryName
+ * @param int $compressionMethod
+ * @return ZipFileInterface
+ * @throws ZipException
+ * @see ZipFileInterface::METHOD_STORED
+ * @see ZipFileInterface::METHOD_DEFLATED
+ * @see ZipFileInterface::METHOD_BZIP2
+ */
+ public function setCompressionMethodEntry($entryName, $compressionMethod)
+ {
+ if (!in_array($compressionMethod, self::$allowCompressionMethods, true)) {
+ throw new ZipUnsupportMethod('Unsupported method ' . $compressionMethod);
+ }
+ $entry = $this->zipModel->getEntry($entryName);
+ if ($entry->getMethod() !== $compressionMethod) {
+ $this->zipModel
+ ->getEntryForChanges($entry)
+ ->setMethod($compressionMethod);
+ }
+ return $this;
+ }
+
+ /**
+ * zipalign is optimization to Android application (APK) files.
+ *
+ * @param int|null $align
+ * @return ZipFileInterface
+ * @link https://developer.android.com/studio/command-line/zipalign.html
+ */
+ public function setZipAlign($align = null)
+ {
+ $this->zipModel->setZipAlign($align);
+ return $this;
+ }
+
+ /**
+ * Set password to all input encrypted entries.
+ *
+ * @param string $password Password
+ * @return ZipFileInterface
+ * @deprecated using ZipFileInterface::setReadPassword()
+ */
+ public function withReadPassword($password)
+ {
+ return $this->setReadPassword($password);
+ }
+
+ /**
+ * Set password to all input encrypted entries.
+ *
+ * @param string $password Password
+ * @return ZipFileInterface
+ */
+ public function setReadPassword($password)
+ {
+ $this->zipModel->setReadPassword($password);
+ return $this;
+ }
+
+ /**
+ * Set password to concrete input entry.
+ *
+ * @param string $entryName
+ * @param string $password Password
+ * @return ZipFileInterface
+ */
+ public function setReadPasswordEntry($entryName, $password)
+ {
+ $this->zipModel->setReadPasswordEntry($entryName, $password);
+ return $this;
+ }
+
+ /**
+ * Set password for all entries for update.
+ *
+ * @param string $password If password null then encryption clear
+ * @param int|null $encryptionMethod Encryption method
+ * @return ZipFileInterface
+ * @deprecated using ZipFileInterface::setPassword()
+ */
+ public function withNewPassword($password, $encryptionMethod = self::ENCRYPTION_METHOD_WINZIP_AES_256)
+ {
+ return $this->setPassword($password, $encryptionMethod);
+ }
+
+ /**
+ * Sets a new password for all files in the archive.
+ *
+ * @param string $password
+ * @param int|null $encryptionMethod Encryption method
+ * @return ZipFileInterface
+ * @throws ZipException
+ */
+ public function setPassword($password, $encryptionMethod = self::ENCRYPTION_METHOD_WINZIP_AES_256)
+ {
+ $this->zipModel->setWritePassword($password);
+ if (null !== $encryptionMethod) {
+ if (!in_array($encryptionMethod, self::$allowEncryptionMethods)) {
+ throw new ZipException('Invalid encryption method');
+ }
+ $this->zipModel->setEncryptionMethod($encryptionMethod);
+ }
+ return $this;
+ }
+
+ /**
+ * Sets a new password of an entry defined by its name.
+ *
+ * @param string $entryName
+ * @param string $password
+ * @param int|null $encryptionMethod
+ * @return ZipFileInterface
+ * @throws ZipException
+ */
+ public function setPasswordEntry($entryName, $password, $encryptionMethod = null)
+ {
+ if (null !== $encryptionMethod) {
+ if (!in_array($encryptionMethod, self::$allowEncryptionMethods)) {
+ throw new ZipException('Invalid encryption method');
+ }
+ }
+ $this->matcher()->add($entryName)->setPassword($password, $encryptionMethod);
+ return $this;
+ }
+
+ /**
+ * Remove password for all entries for update.
+ * @return ZipFileInterface
+ * @deprecated using ZipFileInterface::disableEncryption()
+ */
+ public function withoutPassword()
+ {
+ return $this->disableEncryption();
+ }
+
+ /**
+ * Disable encryption for all entries that are already in the archive.
+ * @return ZipFileInterface
+ */
+ public function disableEncryption()
+ {
+ $this->zipModel->removePassword();
+ return $this;
+ }
+
+ /**
+ * Disable encryption of an entry defined by its name.
+ * @param string $entryName
+ * @return ZipFileInterface
+ */
+ public function disableEncryptionEntry($entryName)
+ {
+ $this->zipModel->removePasswordEntry($entryName);
+ return $this;
+ }
+
+ /**
+ * Undo all changes done in the archive
+ * @return ZipFileInterface
+ */
+ public function unchangeAll()
+ {
+ $this->zipModel->unchangeAll();
+ return $this;
+ }
+
+ /**
+ * Undo change archive comment
+ * @return ZipFileInterface
+ */
+ public function unchangeArchiveComment()
+ {
+ $this->zipModel->unchangeArchiveComment();
+ return $this;
+ }
+
+ /**
+ * Revert all changes done to an entry with the given name.
+ *
+ * @param string|ZipEntry $entry Entry name or ZipEntry
+ * @return ZipFileInterface
+ */
+ public function unchangeEntry($entry)
+ {
+ $this->zipModel->unchangeEntry($entry);
+ return $this;
+ }
+
+ /**
+ * Save as file.
+ *
+ * @param string $filename Output filename
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @throws ZipException
+ */
+ public function saveAsFile($filename)
+ {
+ $filename = (string)$filename;
+
+ $tempFilename = $filename . '.temp' . uniqid();
+ if (!($handle = @fopen($tempFilename, 'w+b'))) {
+ throw new InvalidArgumentException("File " . $tempFilename . ' can not open from write.');
+ }
+ $this->saveAsStream($handle);
+
+ if (!@rename($tempFilename, $filename)) {
+ throw new ZipException('Can not move ' . $tempFilename . ' to ' . $filename);
+ }
+ return $this;
+ }
+
+ /**
+ * Save as stream.
+ *
+ * @param resource $handle Output stream resource
+ * @return ZipFileInterface
+ * @throws ZipException
+ */
+ public function saveAsStream($handle)
+ {
+ if (!is_resource($handle)) {
+ throw new InvalidArgumentException('handle is not resource');
+ }
+ ftruncate($handle, 0);
+ $this->writeZipToStream($handle);
+ fclose($handle);
+ return $this;
+ }
+
+ /**
+ * Output .ZIP archive as attachment.
+ * Die after output.
+ *
+ * @param string $outputFilename Output filename
+ * @param string|null $mimeType Mime-Type
+ * @param bool $attachment Http Header 'Content-Disposition' if true then attachment otherwise inline
+ * @throws InvalidArgumentException
+ */
+ public function outputAsAttachment($outputFilename, $mimeType = null, $attachment = true)
+ {
+ $outputFilename = (string)$outputFilename;
+
+ if (empty($mimeType) || !is_string($mimeType) && !empty($outputFilename)) {
+ $ext = strtolower(pathinfo($outputFilename, PATHINFO_EXTENSION));
+
+ if (!empty($ext) && isset(self::$defaultMimeTypes[$ext])) {
+ $mimeType = self::$defaultMimeTypes[$ext];
+ }
+ }
+ if (empty($mimeType)) {
+ $mimeType = self::$defaultMimeTypes['zip'];
+ }
+
+ $content = $this->outputAsString();
+ $this->close();
+
+ $headerContentDisposition = 'Content-Disposition: ' . ($attachment ? 'attachment' : 'inline');
+ if (!empty($outputFilename)) {
+ $headerContentDisposition .= '; filename="' . basename($outputFilename) . '"';
+ }
+
+ header($headerContentDisposition);
+ header("Content-Type: " . $mimeType);
+ header("Content-Length: " . strlen($content));
+ exit($content);
+ }
+
+ /**
+ * Output .ZIP archive as PSR-7 Response.
+ *
+ * @param ResponseInterface $response Instance PSR-7 Response
+ * @param string $outputFilename Output filename
+ * @param string|null $mimeType Mime-Type
+ * @param bool $attachment Http Header 'Content-Disposition' if true then attachment otherwise inline
+ * @return ResponseInterface
+ * @throws InvalidArgumentException
+ */
+ public function outputAsResponse(ResponseInterface $response, $outputFilename, $mimeType = null, $attachment = true)
+ {
+ $outputFilename = (string)$outputFilename;
+
+ if (empty($mimeType) || !is_string($mimeType) && !empty($outputFilename)) {
+ $ext = strtolower(pathinfo($outputFilename, PATHINFO_EXTENSION));
+
+ if (!empty($ext) && isset(self::$defaultMimeTypes[$ext])) {
+ $mimeType = self::$defaultMimeTypes[$ext];
+ }
+ }
+ if (empty($mimeType)) {
+ $mimeType = self::$defaultMimeTypes['zip'];
+ }
+
+ if (!($handle = fopen('php://memory', 'w+b'))) {
+ throw new InvalidArgumentException("Memory can not open from write.");
+ }
+ $this->writeZipToStream($handle);
+ rewind($handle);
+
+ $contentDispositionValue = ($attachment ? 'attachment' : 'inline');
+ if (!empty($outputFilename)) {
+ $contentDispositionValue .= '; filename="' . basename($outputFilename) . '"';
+ }
+
+ $stream = new ResponseStream($handle);
+ return $response
+ ->withHeader('Content-Type', $mimeType)
+ ->withHeader('Content-Disposition', $contentDispositionValue)
+ ->withHeader('Content-Length', $stream->getSize())
+ ->withBody($stream);
+ }
+
+ /**
+ * @param $handle
+ */
+ protected function writeZipToStream($handle)
+ {
+ $output = new ZipOutputStream($handle, $this->zipModel);
+ $output->writeZip();
+ }
+
+ /**
+ * Returns the zip archive as a string.
+ * @return string
+ * @throws InvalidArgumentException
+ */
+ public function outputAsString()
+ {
+ if (!($handle = fopen('php://memory', 'w+b'))) {
+ throw new InvalidArgumentException("Memory can not open from write.");
+ }
+ $this->writeZipToStream($handle);
+ rewind($handle);
+ $content = stream_get_contents($handle);
+ fclose($handle);
+ return $content;
+ }
+
+ /**
+ * Close zip archive and release input stream.
+ */
+ public function close()
+ {
+ if (null !== $this->inputStream) {
+ $this->inputStream->close();
+ $this->inputStream = null;
+ $this->zipModel = new ZipModel();
+ }
+ }
+
+ /**
+ * Save and reopen zip archive.
+ * @return ZipFileInterface
+ * @throws ZipException
+ */
+ public function rewrite()
+ {
+ if (null === $this->inputStream) {
+ throw new ZipException('input stream is null');
+ }
+ $meta = stream_get_meta_data($this->inputStream->getStream());
+ $content = $this->outputAsString();
+ $this->close();
+ if ('plainfile' === $meta['wrapper_type']) {
+ /**
+ * @var resource $uri
+ */
+ $uri = $meta['uri'];
+ if (file_put_contents($uri, $content) === false) {
+ throw new ZipException("Can not overwrite the zip file in the {$uri} file.");
+ }
+ if (!($handle = @fopen($uri, 'rb'))) {
+ throw new ZipException("File {$uri} can't open.");
+ }
+ return $this->openFromStream($handle);
+ }
+ return $this->openFromString($content);
+ }
+
+ /**
+ * Release all resources
+ */
+ public function __destruct()
+ {
+ $this->close();
+ }
+
+ /**
+ * Offset to set
+ * @link http://php.net/manual/en/arrayaccess.offsetset.php
+ * @param string $entryName The offset to assign the value to.
+ * @param mixed $contents The value to set.
+ * @throws InvalidArgumentException
+ * @see ZipFile::addFromString
+ * @see ZipFile::addEmptyDir
+ * @see ZipFile::addFile
+ * @see ZipFile::addFilesFromIterator
+ */
+ public function offsetSet($entryName, $contents)
+ {
+ if (null === $entryName) {
+ throw new InvalidArgumentException('entryName is null');
+ }
+ $entryName = (string)$entryName;
+ if (strlen($entryName) === 0) {
+ throw new InvalidArgumentException('entryName is empty');
+ }
+ if ($contents instanceof \SplFileInfo) {
+ if ($contents instanceof \DirectoryIterator) {
+ $this->addFilesFromIterator($contents, $entryName);
+ return;
+ }
+ $this->addFile($contents->getPathname(), $entryName);
+ return;
+ }
+ if (StringUtil::endsWith($entryName, '/')) {
+ $this->addEmptyDir($entryName);
+ } elseif (is_resource($contents)) {
+ $this->addFromStream($contents, $entryName);
+ } else {
+ $contents = (string)$contents;
+ $this->addFromString($entryName, $contents);
+ }
+ }
+
+ /**
+ * Offset to unset
+ * @link http://php.net/manual/en/arrayaccess.offsetunset.php
+ * @param string $entryName The offset to unset.
+ * @throws ZipUnsupportMethod
+ */
+ public function offsetUnset($entryName)
+ {
+ $this->deleteFromName($entryName);
+ }
+
+ /**
+ * Return the current element
+ * @link http://php.net/manual/en/iterator.current.php
+ * @return mixed Can return any type.
+ * @since 5.0.0
+ */
+ public function current()
+ {
+ return $this->offsetGet($this->key());
+ }
+
+ /**
+ * Offset to retrieve
+ * @link http://php.net/manual/en/arrayaccess.offsetget.php
+ * @param string $entryName The offset to retrieve.
+ * @return string|null
+ * @throws ZipNotFoundEntry
+ */
+ public function offsetGet($entryName)
+ {
+ return $this->getEntryContents($entryName);
+ }
+
+ /**
+ * Return the key of the current element
+ * @link http://php.net/manual/en/iterator.key.php
+ * @return mixed scalar on success, or null on failure.
+ * @since 5.0.0
+ */
+ public function key()
+ {
+ return key($this->zipModel->getEntries());
+ }
+
+ /**
+ * Move forward to next element
+ * @link http://php.net/manual/en/iterator.next.php
+ * @return void Any returned value is ignored.
+ * @since 5.0.0
+ */
+ public function next()
+ {
+ next($this->zipModel->getEntries());
+ }
+
+ /**
+ * Checks if current position is valid
+ * @link http://php.net/manual/en/iterator.valid.php
+ * @return boolean The return value will be casted to boolean and then evaluated.
+ * Returns true on success or false on failure.
+ * @since 5.0.0
+ */
+ public function valid()
+ {
+ return $this->offsetExists($this->key());
+ }
+
+ /**
+ * Whether a offset exists
+ * @link http://php.net/manual/en/arrayaccess.offsetexists.php
+ * @param string $entryName An offset to check for.
+ * @return boolean true on success or false on failure.
+ * The return value will be casted to boolean if non-boolean was returned.
+ */
+ public function offsetExists($entryName)
+ {
+ return $this->hasEntry($entryName);
+ }
+
+ /**
+ * Rewind the Iterator to the first element
+ * @link http://php.net/manual/en/iterator.rewind.php
+ * @return void Any returned value is ignored.
+ * @since 5.0.0
+ */
+ public function rewind()
+ {
+ reset($this->zipModel->getEntries());
+ }
+}
diff --git a/vendor/nelexa/zip/src/PhpZip/ZipFileInterface.php b/vendor/nelexa/zip/src/PhpZip/ZipFileInterface.php
new file mode 100644
index 0000000..53ab761
--- /dev/null
+++ b/vendor/nelexa/zip/src/PhpZip/ZipFileInterface.php
@@ -0,0 +1,633 @@
+<?php
+
+namespace PhpZip;
+
+use PhpZip\Exception\InvalidArgumentException;
+use PhpZip\Exception\ZipException;
+use PhpZip\Exception\ZipNotFoundEntry;
+use PhpZip\Exception\ZipUnsupportMethod;
+use PhpZip\Model\ZipEntry;
+use PhpZip\Model\ZipEntryMatcher;
+use PhpZip\Model\ZipInfo;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Create, open .ZIP files, modify, get info and extract files.
+ *
+ * Implemented support traditional PKWARE encryption and WinZip AES encryption.
+ * Implemented support ZIP64.
+ * Implemented support skip a preamble like the one found in self extracting archives.
+ * Support ZipAlign functional.
+ *
+ * @see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT .ZIP File Format Specification
+ * @author Ne-Lexa alexey@nelexa.ru
+ * @license MIT
+ */
+interface ZipFileInterface extends \Countable, \ArrayAccess, \Iterator
+{
+ /**
+ * Method for Stored (uncompressed) entries.
+ * @see ZipEntry::setMethod()
+ */
+ const METHOD_STORED = 0;
+ /**
+ * Method for Deflated compressed entries.
+ * @see ZipEntry::setMethod()
+ */
+ const METHOD_DEFLATED = 8;
+ /**
+ * Method for BZIP2 compressed entries.
+ * Require php extension bz2.
+ * @see ZipEntry::setMethod()
+ */
+ const METHOD_BZIP2 = 12;
+
+ /**
+ * Default compression level.
+ */
+ const LEVEL_DEFAULT_COMPRESSION = -1;
+ /**
+ * Compression level for fastest compression.
+ */
+ const LEVEL_FAST = 2;
+ /**
+ * Compression level for fastest compression.
+ */
+ const LEVEL_BEST_SPEED = 1;
+ const LEVEL_SUPER_FAST = self::LEVEL_BEST_SPEED;
+ /**
+ * Compression level for best compression.
+ */
+ const LEVEL_BEST_COMPRESSION = 9;
+
+ /**
+ * No specified method for set encryption method to Traditional PKWARE encryption.
+ */
+ const ENCRYPTION_METHOD_TRADITIONAL = 0;
+ /**
+ * No specified method for set encryption method to WinZip AES encryption.
+ * Default value 256 bit
+ */
+ const ENCRYPTION_METHOD_WINZIP_AES = self::ENCRYPTION_METHOD_WINZIP_AES_256;
+ /**
+ * No specified method for set encryption method to WinZip AES encryption 128 bit.
+ */
+ const ENCRYPTION_METHOD_WINZIP_AES_128 = 2;
+ /**
+ * No specified method for set encryption method to WinZip AES encryption 194 bit.
+ */
+ const ENCRYPTION_METHOD_WINZIP_AES_192 = 3;
+ /**
+ * No specified method for set encryption method to WinZip AES encryption 256 bit.
+ */
+ const ENCRYPTION_METHOD_WINZIP_AES_256 = 1;
+
+ /**
+ * Open zip archive from file
+ *
+ * @param string $filename
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException if file doesn't exists.
+ * @throws ZipException if can't open file.
+ */
+ public function openFile($filename);
+
+ /**
+ * Open zip archive from raw string data.
+ *
+ * @param string $data
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException if data not available.
+ * @throws ZipException if can't open temp stream.
+ */
+ public function openFromString($data);
+
+ /**
+ * Open zip archive from stream resource
+ *
+ * @param resource $handle
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException Invalid stream resource
+ * or resource cannot seekable stream
+ */
+ public function openFromStream($handle);
+
+ /**
+ * @return string[] Returns the list files.
+ */
+ public function getListFiles();
+
+ /**
+ * Returns the file comment.
+ *
+ * @return string The file comment.
+ */
+ public function getArchiveComment();
+
+ /**
+ * Set archive comment.
+ *
+ * @param null|string $comment
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException Length comment out of range
+ */
+ public function setArchiveComment($comment = null);
+
+ /**
+ * Checks that the entry in the archive is a directory.
+ * Returns true if and only if this ZIP entry represents a directory entry
+ * (i.e. end with '/').
+ *
+ * @param string $entryName
+ * @return bool
+ * @throws ZipNotFoundEntry
+ */
+ public function isDirectory($entryName);
+
+ /**
+ * Returns entry comment.
+ *
+ * @param string $entryName
+ * @return string
+ * @throws ZipNotFoundEntry
+ */
+ public function getEntryComment($entryName);
+
+ /**
+ * Set entry comment.
+ *
+ * @param string $entryName
+ * @param string|null $comment
+ * @return ZipFileInterface
+ * @throws ZipNotFoundEntry
+ */
+ public function setEntryComment($entryName, $comment = null);
+
+ /**
+ * Returns the entry contents.
+ *
+ * @param string $entryName
+ * @return string
+ */
+ public function getEntryContents($entryName);
+
+ /**
+ * Checks if there is an entry in the archive.
+ *
+ * @param string $entryName
+ * @return bool
+ */
+ public function hasEntry($entryName);
+
+ /**
+ * Get info by entry.
+ *
+ * @param string|ZipEntry $entryName
+ * @return ZipInfo
+ * @throws ZipNotFoundEntry
+ */
+ public function getEntryInfo($entryName);
+
+ /**
+ * Get info by all entries.
+ *
+ * @return ZipInfo[]
+ */
+ public function getAllInfo();
+
+ /**
+ * @return ZipEntryMatcher
+ */
+ public function matcher();
+
+ /**
+ * Extract the archive contents
+ *
+ * Extract the complete archive or the given files to the specified destination.
+ *
+ * @param string $destination Location where to extract the files.
+ * @param array|string|null $entries The entries to extract. It accepts either
+ * a single entry name or an array of names.
+ * @return ZipFileInterface
+ * @throws ZipException
+ */
+ public function extractTo($destination, $entries = null);
+
+ /**
+ * Add entry from the string.
+ *
+ * @param string $localName Zip entry name.
+ * @param string $contents String contents.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException If incorrect data or entry name.
+ * @throws ZipUnsupportMethod
+ * @see ZipFileInterface::METHOD_STORED
+ * @see ZipFileInterface::METHOD_DEFLATED
+ * @see ZipFileInterface::METHOD_BZIP2
+ */
+ public function addFromString($localName, $contents, $compressionMethod = null);
+
+ /**
+ * Add entry from the file.
+ *
+ * @param string $filename Destination file.
+ * @param string|null $localName Zip Entry name.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @throws ZipUnsupportMethod
+ * @see ZipFileInterface::METHOD_STORED
+ * @see ZipFileInterface::METHOD_DEFLATED
+ * @see ZipFileInterface::METHOD_BZIP2
+ */
+ public function addFile($filename, $localName = null, $compressionMethod = null);
+
+ /**
+ * Add entry from the stream.
+ *
+ * @param resource $stream Stream resource.
+ * @param string $localName Zip Entry name.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @throws ZipUnsupportMethod
+ * @see ZipFileInterface::METHOD_STORED
+ * @see ZipFileInterface::METHOD_DEFLATED
+ * @see ZipFileInterface::METHOD_BZIP2
+ */
+ public function addFromStream($stream, $localName, $compressionMethod = null);
+
+ /**
+ * Add an empty directory in the zip archive.
+ *
+ * @param string $dirName
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ */
+ public function addEmptyDir($dirName);
+
+ /**
+ * Add directory not recursively to the zip archive.
+ *
+ * @param string $inputDir Input directory
+ * @param string $localPath Add files to this directory, or the root.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ */
+ public function addDir($inputDir, $localPath = "/", $compressionMethod = null);
+
+ /**
+ * Add recursive directory to the zip archive.
+ *
+ * @param string $inputDir Input directory
+ * @param string $localPath Add files to this directory, or the root.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @throws ZipUnsupportMethod
+ * @see ZipFileInterface::METHOD_STORED
+ * @see ZipFileInterface::METHOD_DEFLATED
+ * @see ZipFileInterface::METHOD_BZIP2
+ */
+ public function addDirRecursive($inputDir, $localPath = "/", $compressionMethod = null);
+
+ /**
+ * Add directories from directory iterator.
+ *
+ * @param \Iterator $iterator Directory iterator.
+ * @param string $localPath Add files to this directory, or the root.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @throws ZipUnsupportMethod
+ * @see ZipFileInterface::METHOD_STORED
+ * @see ZipFileInterface::METHOD_DEFLATED
+ * @see ZipFileInterface::METHOD_BZIP2
+ */
+ public function addFilesFromIterator(\Iterator $iterator, $localPath = '/', $compressionMethod = null);
+
+ /**
+ * Add files from glob pattern.
+ *
+ * @param string $inputDir Input directory
+ * @param string $globPattern Glob pattern.
+ * @param string|null $localPath Add files to this directory, or the root.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @sse https://en.wikipedia.org/wiki/Glob_(programming) Glob pattern syntax
+ */
+ public function addFilesFromGlob($inputDir, $globPattern, $localPath = '/', $compressionMethod = null);
+
+ /**
+ * Add files recursively from glob pattern.
+ *
+ * @param string $inputDir Input directory
+ * @param string $globPattern Glob pattern.
+ * @param string|null $localPath Add files to this directory, or the root.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @sse https://en.wikipedia.org/wiki/Glob_(programming) Glob pattern syntax
+ */
+ public function addFilesFromGlobRecursive($inputDir, $globPattern, $localPath = '/', $compressionMethod = null);
+
+ /**
+ * Add files from regex pattern.
+ *
+ * @param string $inputDir Search files in this directory.
+ * @param string $regexPattern Regex pattern.
+ * @param string|null $localPath Add files to this directory, or the root.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @internal param bool $recursive Recursive search.
+ */
+ public function addFilesFromRegex($inputDir, $regexPattern, $localPath = "/", $compressionMethod = null);
+
+ /**
+ * Add files recursively from regex pattern.
+ *
+ * @param string $inputDir Search files in this directory.
+ * @param string $regexPattern Regex pattern.
+ * @param string|null $localPath Add files to this directory, or the root.
+ * @param int|null $compressionMethod Compression method.
+ * Use ZipFile::METHOD_STORED, ZipFile::METHOD_DEFLATED or ZipFile::METHOD_BZIP2.
+ * If null, then auto choosing method.
+ * @return ZipFileInterface
+ * @internal param bool $recursive Recursive search.
+ */
+ public function addFilesFromRegexRecursive($inputDir, $regexPattern, $localPath = "/", $compressionMethod = null);
+
+ /**
+ * Add array data to archive.
+ * Keys is local names.
+ * Values is contents.
+ *
+ * @param array $mapData Associative array for added to zip.
+ */
+ public function addAll(array $mapData);
+
+ /**
+ * Rename the entry.
+ *
+ * @param string $oldName Old entry name.
+ * @param string $newName New entry name.
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @throws ZipNotFoundEntry
+ */
+ public function rename($oldName, $newName);
+
+ /**
+ * Delete entry by name.
+ *
+ * @param string $entryName Zip Entry name.
+ * @return ZipFileInterface
+ * @throws ZipNotFoundEntry If entry not found.
+ */
+ public function deleteFromName($entryName);
+
+ /**
+ * Delete entries by glob pattern.
+ *
+ * @param string $globPattern Glob pattern
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @sse https://en.wikipedia.org/wiki/Glob_(programming) Glob pattern syntax
+ */
+ public function deleteFromGlob($globPattern);
+
+ /**
+ * Delete entries by regex pattern.
+ *
+ * @param string $regexPattern Regex pattern
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ */
+ public function deleteFromRegex($regexPattern);
+
+ /**
+ * Delete all entries
+ * @return ZipFileInterface
+ */
+ public function deleteAll();
+
+ /**
+ * Set compression level for new entries.
+ *
+ * @param int $compressionLevel
+ * @see ZipFileInterface::LEVEL_DEFAULT_COMPRESSION
+ * @see ZipFileInterface::LEVEL_SUPER_FAST
+ * @see ZipFileInterface::LEVEL_FAST
+ * @see ZipFileInterface::LEVEL_BEST_COMPRESSION
+ * @return ZipFileInterface
+ */
+ public function setCompressionLevel($compressionLevel = self::LEVEL_DEFAULT_COMPRESSION);
+
+ /**
+ * @param string $entryName
+ * @param int $compressionLevel
+ * @return ZipFileInterface
+ * @throws ZipException
+ * @see ZipFileInterface::LEVEL_DEFAULT_COMPRESSION
+ * @see ZipFileInterface::LEVEL_SUPER_FAST
+ * @see ZipFileInterface::LEVEL_FAST
+ * @see ZipFileInterface::LEVEL_BEST_COMPRESSION
+ */
+ public function setCompressionLevelEntry($entryName, $compressionLevel);
+
+ /**
+ * @param string $entryName
+ * @param int $compressionMethod
+ * @return ZipFileInterface
+ * @throws ZipException
+ * @see ZipFileInterface::METHOD_STORED
+ * @see ZipFileInterface::METHOD_DEFLATED
+ * @see ZipFileInterface::METHOD_BZIP2
+ */
+ public function setCompressionMethodEntry($entryName, $compressionMethod);
+
+ /**
+ * zipalign is optimization to Android application (APK) files.
+ *
+ * @param int|null $align
+ * @return ZipFileInterface
+ * @link https://developer.android.com/studio/command-line/zipalign.html
+ */
+ public function setZipAlign($align = null);
+
+ /**
+ * Set password to all input encrypted entries.
+ *
+ * @param string $password Password
+ * @return ZipFileInterface
+ * @deprecated using ZipFileInterface::setReadPassword()
+ */
+ public function withReadPassword($password);
+
+ /**
+ * Set password to all input encrypted entries.
+ *
+ * @param string $password Password
+ * @return ZipFileInterface
+ */
+ public function setReadPassword($password);
+
+ /**
+ * Set password to concrete input entry.
+ *
+ * @param string $entryName
+ * @param string $password Password
+ * @return ZipFileInterface
+ */
+ public function setReadPasswordEntry($entryName, $password);
+
+ /**
+ * Set password for all entries for update.
+ *
+ * @param string $password If password null then encryption clear
+ * @param int|null $encryptionMethod Encryption method
+ * @return ZipFileInterface
+ * @deprecated using ZipFileInterface::setPassword()
+ */
+ public function withNewPassword($password, $encryptionMethod = self::ENCRYPTION_METHOD_WINZIP_AES_256);
+
+ /**
+ * Sets a new password for all files in the archive.
+ *
+ * @param string $password
+ * @param int|null $encryptionMethod Encryption method
+ * @return ZipFileInterface
+ */
+ public function setPassword($password, $encryptionMethod = self::ENCRYPTION_METHOD_WINZIP_AES_256);
+
+ /**
+ * Sets a new password of an entry defined by its name.
+ *
+ * @param string $entryName
+ * @param string $password
+ * @param int|null $encryptionMethod
+ * @return ZipFileInterface
+ */
+ public function setPasswordEntry($entryName, $password, $encryptionMethod = null);
+
+ /**
+ * Remove password for all entries for update.
+ * @return ZipFileInterface
+ * @deprecated using ZipFileInterface::disableEncryption()
+ */
+ public function withoutPassword();
+
+ /**
+ * Disable encryption for all entries that are already in the archive.
+ * @return ZipFileInterface
+ */
+ public function disableEncryption();
+
+ /**
+ * Disable encryption of an entry defined by its name.
+ * @param string $entryName
+ * @return ZipFileInterface
+ */
+ public function disableEncryptionEntry($entryName);
+
+ /**
+ * Undo all changes done in the archive
+ * @return ZipFileInterface
+ */
+ public function unchangeAll();
+
+ /**
+ * Undo change archive comment
+ * @return ZipFileInterface
+ */
+ public function unchangeArchiveComment();
+
+ /**
+ * Revert all changes done to an entry with the given name.
+ *
+ * @param string|ZipEntry $entry Entry name or ZipEntry
+ * @return ZipFileInterface
+ */
+ public function unchangeEntry($entry);
+
+ /**
+ * Save as file.
+ *
+ * @param string $filename Output filename
+ * @return ZipFileInterface
+ * @throws InvalidArgumentException
+ * @throws ZipException
+ */
+ public function saveAsFile($filename);
+
+ /**
+ * Save as stream.
+ *
+ * @param resource $handle Output stream resource
+ * @return ZipFileInterface
+ * @throws ZipException
+ */
+ public function saveAsStream($handle);
+
+ /**
+ * Output .ZIP archive as attachment.
+ * Die after output.
+ *
+ * @param string $outputFilename Output filename
+ * @param string|null $mimeType Mime-Type
+ * @param bool $attachment Http Header 'Content-Disposition' if true then attachment otherwise inline
+ */
+ public function outputAsAttachment($outputFilename, $mimeType = null, $attachment = true);
+
+ /**
+ * Output .ZIP archive as PSR-7 Response.
+ *
+ * @param ResponseInterface $response Instance PSR-7 Response
+ * @param string $outputFilename Output filename
+ * @param string|null $mimeType Mime-Type
+ * @param bool $attachment Http Header 'Content-Disposition' if true then attachment otherwise inline
+ * @return ResponseInterface
+ * @throws InvalidArgumentException
+ */
+ public function outputAsResponse(ResponseInterface $response, $outputFilename, $mimeType = null, $attachment = true);
+
+ /**
+ * Returns the zip archive as a string.
+ * @return string
+ * @throws InvalidArgumentException
+ */
+ public function outputAsString();
+
+ /**
+ * Save and reopen zip archive.
+ * @return ZipFileInterface
+ * @throws ZipException
+ */
+ public function rewrite();
+
+ /**
+ * Close zip archive and release input stream.
+ */
+ public function close();
+}
diff --git a/vendor/nelexa/zip/tests/PhpZip/PhpZipExtResourceTest.php b/vendor/nelexa/zip/tests/PhpZip/PhpZipExtResourceTest.php
new file mode 100644
index 0000000..f1efb6f
--- /dev/null
+++ b/vendor/nelexa/zip/tests/PhpZip/PhpZipExtResourceTest.php
@@ -0,0 +1,142 @@
+<?php
+
+namespace PhpZip;
+
+use PhpZip\Exception\ZipAuthenticationException;
+
+/**
+ * Some tests from the official extension of php-zip.
+ */
+class PhpZipExtResourceTest extends ZipTestCase
+{
+ /**
+ * Bug #7214 (zip_entry_read() binary safe)
+ * @see https://github.com/php/php-src/blob/master/ext/zip/tests/bug7214.phpt
+ */
+ public function testBinaryNull()
+ {
+ $filename = __DIR__ . '/php-zip-ext-test-resources/binarynull.zip';
+
+ $zipFile = new ZipFile();
+ $zipFile->openFile($filename);
+ foreach ($zipFile as $name => $contents) {
+ $info = $zipFile->getEntryInfo($name);
+ self::assertEquals(strlen($contents), $info->getSize());
+ }
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($filename);
+ }
+
+ /**
+ * Bug #8009 (cannot add again same entry to an archive)
+ * @see https://github.com/php/php-src/blob/master/ext/zip/tests/bug8009.phpt
+ */
+ public function testBug8009()
+ {
+ $filename = __DIR__ . '/php-zip-ext-test-resources/bug8009.zip';
+
+ $zipFile = new ZipFile();
+ $zipFile->openFile($filename);
+ $zipFile->addFromString('2.txt', '=)');
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertCount(2, $zipFile);
+ self::assertTrue(isset($zipFile['1.txt']));
+ self::assertTrue(isset($zipFile['2.txt']));
+ self::assertEquals($zipFile['2.txt'], $zipFile['1.txt']);
+ $zipFile->close();
+ }
+
+ /**
+ * Bug #40228 (extractTo does not create recursive empty path)
+ * @see https://github.com/php/php-src/blob/master/ext/zip/tests/bug40228.phpt
+ * @see https://github.com/php/php-src/blob/master/ext/zip/tests/bug40228-mb.phpt
+ * @dataProvider provideBug40228
+ * @param string $filename
+ */
+ public function testBug40228($filename)
+ {
+ self::assertTrue(mkdir($this->outputDirname, 0755, true));
+
+ $zipFile = new ZipFile();
+ $zipFile->openFile($filename);
+ $zipFile->extractTo($this->outputDirname);
+ $zipFile->close();
+
+ self::assertTrue(is_dir($this->outputDirname . '/test/empty'));
+ }
+
+ public function provideBug40228()
+ {
+ return [
+ [__DIR__ . '/php-zip-ext-test-resources/bug40228.zip'],
+ ];
+ }
+
+ /**
+ * Bug #49072 (feof never returns true for damaged file in zip)
+ * @see https://github.com/php/php-src/blob/master/ext/zip/tests/bug49072.phpt
+ * @expectedException \PhpZip\Exception\Crc32Exception
+ * @expectedExceptionMessage file1
+ */
+ public function testBug49072()
+ {
+ $filename = __DIR__ . '/php-zip-ext-test-resources/bug49072.zip';
+
+ $zipFile = new ZipFile();
+ $zipFile->openFile($filename);
+ $zipFile->getEntryContents('file1');
+ }
+
+ /**
+ * Bug #70752 (Depacking with wrong password leaves 0 length files)
+ * @see https://github.com/php/php-src/blob/master/ext/zip/tests/bug70752.phpt
+ * @expectedException \PhpZip\Exception\ZipAuthenticationException
+ * @expectedExceptionMessage Bad password for entry bug70752.txt
+ */
+ public function testBug70752()
+ {
+ $filename = __DIR__ . '/php-zip-ext-test-resources/bug70752.zip';
+
+ self::assertTrue(mkdir($this->outputDirname, 0755, true));
+
+ $zipFile = new ZipFile();
+ try {
+ $zipFile->openFile($filename);
+ $zipFile->setReadPassword('bar');
+ $zipFile->extractTo($this->outputDirname);
+ self::markTestIncomplete('failed test');
+ } catch (ZipAuthenticationException $exception) {
+ self::assertFalse(file_exists($this->outputDirname . '/bug70752.txt'));
+ $zipFile->close();
+ throw $exception;
+ }
+ }
+
+ /**
+ * Bug #12414 ( extracting files from damaged archives)
+ * @see https://github.com/php/php-src/blob/master/ext/zip/tests/pecl12414.phpt
+ */
+ public function testPecl12414()
+ {
+ $filename = __DIR__ . '/php-zip-ext-test-resources/pecl12414.zip';
+
+ $entryName = 'MYLOGOV2.GFX';
+
+ $zipFile = new ZipFile();
+ $zipFile->openFile($filename);
+
+ $info = $zipFile->getEntryInfo($entryName);
+ self::assertTrue($info->getSize() > 0);
+
+ $contents = $zipFile[$entryName];
+ self::assertEquals(strlen($contents), $info->getSize());
+
+ $zipFile->close();
+ }
+}
diff --git a/vendor/nelexa/zip/tests/PhpZip/ZipAlignTest.php b/vendor/nelexa/zip/tests/PhpZip/ZipAlignTest.php
new file mode 100644
index 0000000..bb98eab
--- /dev/null
+++ b/vendor/nelexa/zip/tests/PhpZip/ZipAlignTest.php
@@ -0,0 +1,147 @@
+<?php
+
+namespace PhpZip;
+
+use PhpZip\Util\CryptoUtil;
+
+/**
+ * Test ZipAlign
+ */
+class ZipAlignTest extends ZipTestCase
+{
+ public function testApkAlignedAndSetZipAlignAndReSave()
+ {
+ $filename = __DIR__ . '/resources/test.apk';
+
+ self::assertCorrectZipArchive($filename);
+ $result = self::doZipAlignVerify($filename);
+ if (null !== $result) {
+ self::assertTrue($result);
+ }
+
+ $zipFile = new ZipFile();
+ $zipFile->openFile($filename);
+ $zipFile->setZipAlign(4);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+ $result = self::doZipAlignVerify($this->outputFilename, true);
+ if (null !== $result) {
+ self::assertTrue($result);
+ }
+ }
+
+ /**
+ * Test zip alignment.
+ */
+ public function testZipAlignSourceZip()
+ {
+ $zipFile = new ZipFile();
+ for ($i = 0; $i < 100; $i++) {
+ $zipFile->addFromString(
+ 'entry' . $i . '.txt',
+ CryptoUtil::randomBytes(mt_rand(100, 4096)),
+ ZipFileInterface::METHOD_STORED
+ );
+ }
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $result = self::doZipAlignVerify($this->outputFilename);
+ if ($result === null) {
+ return;
+ } // zip align not installed
+
+ // check not zip align
+ self::assertFalse($result);
+
+ $zipFile->openFile($this->outputFilename);
+ $zipFile->setZipAlign(4);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $result = self::doZipAlignVerify($this->outputFilename, true);
+ self::assertNotNull($result);
+
+ // check zip align
+ self::assertTrue($result);
+ }
+
+ public function testZipAlignNewFiles()
+ {
+ $zipFile = new ZipFile();
+ for ($i = 0; $i < 100; $i++) {
+ $zipFile->addFromString(
+ 'entry' . $i . '.txt',
+ CryptoUtil::randomBytes(mt_rand(100, 4096)),
+ ZipFileInterface::METHOD_STORED
+ );
+ }
+ $zipFile->setZipAlign(4);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $result = self::doZipAlignVerify($this->outputFilename);
+ if ($result === null) {
+ return;
+ } // zip align not installed
+ // check not zip align
+ self::assertTrue($result);
+ }
+
+ public function testZipAlignFromModifiedZipArchive()
+ {
+ $zipFile = new ZipFile();
+ for ($i = 0; $i < 100; $i++) {
+ $zipFile->addFromString(
+ 'entry' . $i . '.txt',
+ CryptoUtil::randomBytes(mt_rand(100, 4096)),
+ ZipFileInterface::METHOD_STORED
+ );
+ }
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $result = self::doZipAlignVerify($this->outputFilename);
+ if ($result === null) {
+ return;
+ } // zip align not installed
+
+ // check not zip align
+ self::assertFalse($result);
+
+ $zipFile->openFile($this->outputFilename);
+ $zipFile->deleteFromRegex("~entry2[\d]+\.txt$~s");
+ for ($i = 0; $i < 100; $i++) {
+ $isStored = (bool)mt_rand(0, 1);
+
+ $zipFile->addFromString(
+ 'entry_new_' . ($isStored ? 'stored' : 'deflated') . '_' . $i . '.txt',
+ CryptoUtil::randomBytes(mt_rand(100, 4096)),
+ $isStored ?
+ ZipFileInterface::METHOD_STORED :
+ ZipFileInterface::METHOD_DEFLATED
+ );
+ }
+ $zipFile->setZipAlign(4);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $result = self::doZipAlignVerify($this->outputFilename, true);
+ self::assertNotNull($result);
+
+ // check zip align
+ self::assertTrue($result);
+ }
+}
diff --git a/vendor/nelexa/zip/tests/PhpZip/ZipFileAddDirTest.php b/vendor/nelexa/zip/tests/PhpZip/ZipFileAddDirTest.php
new file mode 100644
index 0000000..039c1c3
--- /dev/null
+++ b/vendor/nelexa/zip/tests/PhpZip/ZipFileAddDirTest.php
@@ -0,0 +1,383 @@
+<?php
+
+namespace PhpZip;
+
+use PhpZip\Util\Iterator\IgnoreFilesFilterIterator;
+use PhpZip\Util\Iterator\IgnoreFilesRecursiveFilterIterator;
+
+/**
+ * Test add directory to zip archive.
+ */
+class ZipFileAddDirTest extends ZipTestCase
+{
+ protected static $files = [
+ '.hidden' => 'Hidden file',
+ 'text file.txt' => 'Text file',
+ 'Текстовый документ.txt' => 'Текстовый документ',
+ 'empty dir/' => null,
+ 'empty dir2/ещё пустой каталог/' => null,
+ 'catalog/New File' => 'New Catalog File',
+ 'catalog/New File 2' => 'New Catalog File 2',
+ 'catalog/Empty Dir/' => null,
+ 'category/list.txt' => 'Category list',
+ 'category/Pictures/128x160/Car/01.jpg' => 'File 01.jpg',
+ 'category/Pictures/128x160/Car/02.jpg' => 'File 02.jpg',
+ 'category/Pictures/240x320/Car/01.jpg' => 'File 01.jpg',
+ 'category/Pictures/240x320/Car/02.jpg' => 'File 02.jpg',
+ ];
+
+ /**
+ * Before test
+ */
+ protected function setUp()
+ {
+ parent::setUp();
+ $this->fillDirectory();
+ }
+
+ protected function fillDirectory()
+ {
+ foreach (self::$files as $name => $content) {
+ $fullName = $this->outputDirname . '/' . $name;
+ if ($content === null) {
+ if (!is_dir($fullName)) {
+ mkdir($fullName, 0755, true);
+ }
+ } else {
+ $dirname = dirname($fullName);
+ if (!is_dir($dirname)) {
+ mkdir($dirname, 0755, true);
+ }
+ file_put_contents($fullName, $content);
+ }
+ }
+ }
+
+ protected static function assertFilesResult(ZipFileInterface $zipFile, array $actualResultFiles = [], $localPath = '/')
+ {
+ $localPath = rtrim($localPath, '/');
+ $localPath = empty($localPath) ? "" : $localPath . '/';
+ self::assertEquals(sizeof($zipFile), sizeof($actualResultFiles));
+ $actualResultFiles = array_flip($actualResultFiles);
+ foreach (self::$files as $file => $content) {
+ $zipEntryName = $localPath . $file;
+ if (isset($actualResultFiles[$file])) {
+ self::assertTrue(isset($zipFile[$zipEntryName]));
+ self::assertEquals($zipFile[$zipEntryName], $content);
+ unset($actualResultFiles[$file]);
+ } else {
+ self::assertFalse(isset($zipFile[$zipEntryName]));
+ }
+ }
+ self::assertEmpty($actualResultFiles);
+ }
+
+ public function testAddDirWithLocalPath()
+ {
+ $localPath = 'to/path';
+
+ $zipFile = new ZipFile();
+ $zipFile->addDir($this->outputDirname, $localPath);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertFilesResult($zipFile, [
+ '.hidden',
+ 'text file.txt',
+ 'Текстовый документ.txt',
+ 'empty dir/',
+ ], $localPath);
+ $zipFile->close();
+ }
+
+ public function testAddDirWithoutLocalPath()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addDir($this->outputDirname);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertFilesResult($zipFile, [
+ '.hidden',
+ 'text file.txt',
+ 'Текстовый документ.txt',
+ 'empty dir/',
+ ]);
+ $zipFile->close();
+ }
+
+ public function testAddFilesFromIterator()
+ {
+ $localPath = 'to/project';
+
+ $directoryIterator = new \DirectoryIterator($this->outputDirname);
+
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromIterator($directoryIterator, $localPath);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertFilesResult($zipFile, [
+ '.hidden',
+ 'text file.txt',
+ 'Текстовый документ.txt',
+ 'empty dir/',
+ ], $localPath);
+ $zipFile->close();
+ }
+
+ public function testAddFilesFromIteratorEmptyLocalPath()
+ {
+ $localPath = '';
+
+ $directoryIterator = new \DirectoryIterator($this->outputDirname);
+
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromIterator($directoryIterator, $localPath);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertFilesResult($zipFile, [
+ '.hidden',
+ 'text file.txt',
+ 'Текстовый документ.txt',
+ 'empty dir/',
+ ]);
+ $zipFile->close();
+ }
+
+ public function testAddFilesFromRecursiveIterator()
+ {
+ $localPath = 'to/project';
+
+ $directoryIterator = new \RecursiveDirectoryIterator($this->outputDirname);
+
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromIterator($directoryIterator, $localPath);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertFilesResult($zipFile, array_keys(self::$files), $localPath);
+ $zipFile->close();
+ }
+
+ public function testAddRecursiveDirWithLocalPath()
+ {
+ $localPath = 'to/path';
+
+ $zipFile = new ZipFile();
+ $zipFile->addDirRecursive($this->outputDirname, $localPath);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertFilesResult($zipFile, array_keys(self::$files), $localPath);
+ $zipFile->close();
+ }
+
+ public function testAddRecursiveDirWithoutLocalPath()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addDirRecursive($this->outputDirname);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertFilesResult($zipFile, array_keys(self::$files));
+ $zipFile->close();
+ }
+
+ public function testAddFilesFromIteratorWithIgnoreFiles()
+ {
+ $localPath = 'to/project';
+ $ignoreFiles = [
+ 'Текстовый документ.txt',
+ 'empty dir/'
+ ];
+
+ $directoryIterator = new \DirectoryIterator($this->outputDirname);
+ $ignoreIterator = new IgnoreFilesFilterIterator($directoryIterator, $ignoreFiles);
+
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromIterator($ignoreIterator, $localPath);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertFilesResult($zipFile, [
+ '.hidden',
+ 'text file.txt',
+ ], $localPath);
+ $zipFile->close();
+ }
+
+ public function testAddFilesFromRecursiveIteratorWithIgnoreFiles()
+ {
+ $localPath = 'to/project';
+ $ignoreFiles = [
+ '.hidden',
+ 'empty dir2/ещё пустой каталог/',
+ 'list.txt',
+ 'category/Pictures/240x320',
+ ];
+
+ $directoryIterator = new \RecursiveDirectoryIterator($this->outputDirname);
+ $ignoreIterator = new IgnoreFilesRecursiveFilterIterator($directoryIterator, $ignoreFiles);
+
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromIterator($ignoreIterator, $localPath);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertFilesResult($zipFile, [
+ 'text file.txt',
+ 'Текстовый документ.txt',
+ 'empty dir/',
+ 'catalog/New File',
+ 'catalog/New File 2',
+ 'catalog/Empty Dir/',
+ 'category/Pictures/128x160/Car/01.jpg',
+ 'category/Pictures/128x160/Car/02.jpg',
+ ], $localPath);
+ $zipFile->close();
+ }
+
+ /**
+ * Create archive and add files from glob pattern
+ */
+ public function testAddFilesFromGlob()
+ {
+ $localPath = '/';
+
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromGlob($this->outputDirname, '**.{txt,jpg}', $localPath);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertFilesResult($zipFile, [
+ 'text file.txt',
+ 'Текстовый документ.txt',
+ ], $localPath);
+ $zipFile->close();
+ }
+
+ /**
+ * Create archive and add recursively files from glob pattern
+ */
+ public function testAddFilesFromGlobRecursive()
+ {
+ $localPath = '/';
+
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromGlobRecursive($this->outputDirname, '**.{txt,jpg}', $localPath);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertFilesResult($zipFile, [
+ 'text file.txt',
+ 'Текстовый документ.txt',
+ 'category/list.txt',
+ 'category/Pictures/128x160/Car/01.jpg',
+ 'category/Pictures/128x160/Car/02.jpg',
+ 'category/Pictures/240x320/Car/01.jpg',
+ 'category/Pictures/240x320/Car/02.jpg',
+ ], $localPath);
+ $zipFile->close();
+ }
+
+ /**
+ * Create archive and add files from regex pattern
+ */
+ public function testAddFilesFromRegex()
+ {
+ $localPath = 'path';
+
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromRegex($this->outputDirname, '~\.(txt|jpe?g)$~i', $localPath);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertFilesResult($zipFile, [
+ 'text file.txt',
+ 'Текстовый документ.txt',
+ ], $localPath);
+ $zipFile->close();
+ }
+
+ /**
+ * Create archive and add files recursively from regex pattern
+ */
+ public function testAddFilesFromRegexRecursive()
+ {
+ $localPath = '/';
+
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromRegexRecursive($this->outputDirname, '~\.(txt|jpe?g)$~i', $localPath);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertFilesResult($zipFile, [
+ 'text file.txt',
+ 'Текстовый документ.txt',
+ 'category/list.txt',
+ 'category/Pictures/128x160/Car/01.jpg',
+ 'category/Pictures/128x160/Car/02.jpg',
+ 'category/Pictures/240x320/Car/01.jpg',
+ 'category/Pictures/240x320/Car/02.jpg',
+ ], $localPath);
+ $zipFile->close();
+ }
+
+ public function testArrayAccessAddDir()
+ {
+ $localPath = 'path/to';
+ $iterator = new \RecursiveDirectoryIterator($this->outputDirname);
+
+ $zipFile = new ZipFile();
+ $zipFile[$localPath] = $iterator;
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertFilesResult($zipFile, array_keys(self::$files), $localPath);
+ $zipFile->close();
+ }
+}
diff --git a/vendor/nelexa/zip/tests/PhpZip/ZipFileTest.php b/vendor/nelexa/zip/tests/PhpZip/ZipFileTest.php
new file mode 100644
index 0000000..4cbc75e
--- /dev/null
+++ b/vendor/nelexa/zip/tests/PhpZip/ZipFileTest.php
@@ -0,0 +1,2009 @@
+<?php
+
+namespace PhpZip;
+
+use PhpZip\Model\ZipEntry;
+use PhpZip\Model\ZipInfo;
+use PhpZip\Util\CryptoUtil;
+use PhpZip\Util\FilesUtil;
+use Psr\Http\Message\ResponseInterface;
+use Zend\Diactoros\Response;
+
+/**
+ * ZipFile test
+ */
+class ZipFileTest extends ZipTestCase
+{
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage can't exists
+ */
+ public function testOpenFileCantExists()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->openFile(uniqid());
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipException
+ * @expectedExceptionMessage can't open
+ */
+ public function testOpenFileCantOpen()
+ {
+ if (0 === posix_getuid()) {
+ $this->markTestSkipped('Skip the test for a user with root privileges');
+ }
+
+ self::assertNotFalse(file_put_contents($this->outputFilename, 'content'));
+ self::assertTrue(chmod($this->outputFilename, 0222));
+
+ $zipFile = new ZipFile();
+ $zipFile->openFile($this->outputFilename);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipException
+ * @expectedExceptionMessage Invalid zip file
+ */
+ public function testOpenFileEmptyFile()
+ {
+ self::assertNotFalse(touch($this->outputFilename));
+ $zipFile = new ZipFile();
+ $zipFile->openFile($this->outputFilename);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipException
+ * @expectedExceptionMessage Expected Local File Header or (ZIP64) End Of Central Directory Record
+ */
+ public function testOpenFileInvalidZip()
+ {
+ self::assertNotFalse(file_put_contents($this->outputFilename, CryptoUtil::randomBytes(255)));
+ $zipFile = new ZipFile();
+ $zipFile->openFile($this->outputFilename);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Data not available
+ */
+ public function testOpenFromStringNullString()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->openFromString(null);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Data not available
+ */
+ public function testOpenFromStringEmptyString()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->openFromString("");
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipException
+ * @expectedExceptionMessage Expected Local File Header or (ZIP64) End Of Central Directory Record
+ */
+ public function testOpenFromStringInvalidZip()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->openFromString(CryptoUtil::randomBytes(255));
+ }
+
+ public function testOpenFromString()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFromString('file', 'content');
+ $zipFile['file2'] = 'content 2';
+ $zipContents = $zipFile->outputAsString();
+ $zipFile->close();
+
+ $zipFile->openFromString($zipContents);
+ self::assertEquals($zipFile->count(), 2);
+ self::assertTrue(isset($zipFile['file']));
+ self::assertTrue(isset($zipFile['file2']));
+ self::assertEquals($zipFile['file'], 'content');
+ self::assertEquals($zipFile['file2'], 'content 2');
+ $zipFile->close();
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Invalid stream resource
+ */
+ public function testOpenFromStreamNullStream()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->openFromStream(null);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Invalid stream resource
+ */
+ public function testOpenFromStreamInvalidResourceType()
+ {
+ $zipFile = new ZipFile();
+ /** @noinspection PhpParamsInspection */
+ $zipFile->openFromStream("stream resource");
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Invalid resource type - gd.
+ */
+ public function testOpenFromStreamInvalidResourceType2()
+ {
+ $zipFile = new ZipFile();
+ if (!extension_loaded("gd")) {
+ $this->markTestSkipped('not extension gd');
+ }
+ $zipFile->openFromStream(imagecreate(1, 1));
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Invalid stream type - dir.
+ */
+ public function testOpenFromStreamInvalidResourceType3()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->openFromStream(opendir(__DIR__));
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Resource cannot seekable stream.
+ */
+ public function testOpenFromStreamNoSeekable()
+ {
+ if (!$fp = @fopen("http://localhost", 'r')) {
+ if (!$fp = @fopen("http://example.org", 'r')) {
+ $this->markTestSkipped('not connected to localhost or remote host');
+ return;
+ }
+ }
+
+ $zipFile = new ZipFile();
+ $zipFile->openFromStream($fp);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipException
+ * @expectedExceptionMessage Invalid zip file
+ */
+ public function testOpenFromStreamEmptyContents()
+ {
+ $fp = fopen($this->outputFilename, 'w+b');
+ $zipFile = new ZipFile();
+ $zipFile->openFromStream($fp);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipException
+ * @expectedExceptionMessage Expected Local File Header or (ZIP64) End Of Central Directory Record
+ */
+ public function testOpenFromStreamInvalidZip()
+ {
+ $fp = fopen($this->outputFilename, 'w+b');
+ fwrite($fp, CryptoUtil::randomBytes(255));
+ $zipFile = new ZipFile();
+ $zipFile->openFromStream($fp);
+ }
+
+ public function testOpenFromStream()
+ {
+ $zipFile = new ZipFile();
+ $zipFile
+ ->addFromString('file', 'content')
+ ->saveAsFile($this->outputFilename)
+ ->close();
+
+ $handle = fopen($this->outputFilename, 'rb');
+ $zipFile->openFromStream($handle);
+ self::assertEquals($zipFile->count(), 1);
+ self::assertTrue(isset($zipFile['file']));
+ self::assertEquals($zipFile['file'], 'content');
+ $zipFile->close();
+ }
+
+ /**
+ * Test create, open and extract empty archive.
+ */
+ public function testEmptyArchive()
+ {
+ $zipFile = new ZipFile();
+ $zipFile
+ ->saveAsFile($this->outputFilename)
+ ->close();
+
+ self::assertCorrectEmptyZip($this->outputFilename);
+ self::assertTrue(mkdir($this->outputDirname, 0755, true));
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertEquals($zipFile->count(), 0);
+ $zipFile
+ ->extractTo($this->outputDirname)
+ ->close();
+
+ self::assertTrue(FilesUtil::isEmptyDir($this->outputDirname));
+ }
+
+ /**
+ * No modified archive
+ *
+ * @see ZipOutputFile::create()
+ */
+ public function testNoModifiedArchive()
+ {
+ self::assertTrue(mkdir($this->outputDirname, 0755, true));
+
+ $fileActual = $this->outputDirname . DIRECTORY_SEPARATOR . 'file_actual.zip';
+ $fileExpected = $this->outputDirname . DIRECTORY_SEPARATOR . 'file_expected.zip';
+
+ $zipFile = new ZipFile();
+ $zipFile->addDirRecursive(__DIR__.'/../../src');
+ $sourceCount = $zipFile->count();
+ self::assertTrue($sourceCount > 0);
+ $zipFile
+ ->saveAsFile($fileActual)
+ ->close();
+ self::assertCorrectZipArchive($fileActual);
+
+ $zipFile
+ ->openFile($fileActual)
+ ->saveAsFile($fileExpected);
+ self::assertCorrectZipArchive($fileExpected);
+
+ $zipFileExpected = new ZipFile();
+ $zipFileExpected->openFile($fileExpected);
+
+ self::assertEquals($zipFile->count(), $sourceCount);
+ self::assertEquals($zipFileExpected->count(), $zipFile->count());
+ self::assertEquals($zipFileExpected->getListFiles(), $zipFile->getListFiles());
+
+ foreach ($zipFile as $entryName => $content) {
+ self::assertEquals($zipFileExpected[$entryName], $content);
+ }
+
+ $zipFileExpected->close();
+ $zipFile->close();
+ }
+
+ /**
+ * Create archive and add files.
+ *
+ * @see ZipOutputFile::addFromString()
+ * @see ZipOutputFile::addFromFile()
+ * @see ZipOutputFile::addFromStream()
+ * @see ZipFile::getEntryContents()
+ */
+ public function testCreateArchiveAndAddFiles()
+ {
+ $outputFromString = file_get_contents(__FILE__);
+ $outputFromString2 = file_get_contents(dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'README.md');
+ $outputFromFile = file_get_contents(dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'phpunit.xml');
+ $outputFromStream = file_get_contents(dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'composer.json');
+
+ $filenameFromString = basename(__FILE__);
+ $filenameFromString2 = 'test_file.txt';
+ $filenameFromFile = 'data/test file.txt';
+ $filenameFromStream = 'data/ডিরেক্টরি/αρχείο.json';
+ $emptyDirName = 'empty dir/пустой каталог/空目錄/ไดเรกทอรีที่ว่างเปล่า/';
+ $emptyDirName2 = 'empty dir/пустой каталог/';
+ $emptyDirName3 = 'empty dir/пустой каталог/ещё один пустой каталог/';
+
+ $tempFile = tempnam(sys_get_temp_dir(), 'txt');
+ file_put_contents($tempFile, $outputFromFile);
+
+ $tempStream = tmpfile();
+ fwrite($tempStream, $outputFromStream);
+
+ $zipFile = new ZipFile;
+ $zipFile
+ ->addFromString($filenameFromString, $outputFromString)
+ ->addFile($tempFile, $filenameFromFile)
+ ->addFromStream($tempStream, $filenameFromStream)
+ ->addEmptyDir($emptyDirName);
+ $zipFile[$filenameFromString2] = $outputFromString2;
+ $zipFile[$emptyDirName2] = null;
+ $zipFile[$emptyDirName3] = 'this content ignoring';
+ self::assertEquals(count($zipFile), 7);
+ $zipFile
+ ->saveAsFile($this->outputFilename)
+ ->close();
+ unlink($tempFile);
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertEquals(count($zipFile), 7);
+ self::assertEquals($zipFile[$filenameFromString], $outputFromString);
+ self::assertEquals($zipFile[$filenameFromFile], $outputFromFile);
+ self::assertEquals($zipFile[$filenameFromStream], $outputFromStream);
+ self::assertEquals($zipFile[$filenameFromString2], $outputFromString2);
+ self::assertTrue(isset($zipFile[$emptyDirName]));
+ self::assertTrue(isset($zipFile[$emptyDirName2]));
+ self::assertTrue(isset($zipFile[$emptyDirName3]));
+ self::assertTrue($zipFile->isDirectory($emptyDirName));
+ self::assertTrue($zipFile->isDirectory($emptyDirName2));
+ self::assertTrue($zipFile->isDirectory($emptyDirName3));
+
+ $listFiles = $zipFile->getListFiles();
+ self::assertEquals($listFiles[0], $filenameFromString);
+ self::assertEquals($listFiles[1], $filenameFromFile);
+ self::assertEquals($listFiles[2], $filenameFromStream);
+ self::assertEquals($listFiles[3], $emptyDirName);
+ self::assertEquals($listFiles[4], $filenameFromString2);
+ self::assertEquals($listFiles[5], $emptyDirName2);
+ self::assertEquals($listFiles[6], $emptyDirName3);
+
+ $zipFile->close();
+ }
+
+ public function testEmptyContent()
+ {
+ $zipFile = new ZipFile();
+ $zipFile['file'] = '';
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertEquals($zipFile['file'], '');
+ $zipFile->close();
+ }
+
+ /**
+ * Test compression method from image file.
+ */
+ public function testCompressionMethodFromImageMimeType()
+ {
+ if (!function_exists('mime_content_type')) {
+ $this->markTestSkipped('Function mime_content_type not exists');
+ }
+ $outputFilename = $this->outputFilename;
+ $this->outputFilename .= '.gif';
+ self::assertNotFalse(
+ file_put_contents(
+ $this->outputFilename,
+ base64_decode('R0lGODlhAQABAJAAAP8AAAAAACH5BAUQAAAALAAAAAABAAEAAAICBAEAOw==')
+ )
+ );
+ $basename = basename($this->outputFilename);
+
+ $zipFile = new ZipFile();
+ $zipFile->addFile($this->outputFilename, $basename);
+ $zipFile->saveAsFile($outputFilename);
+ unlink($this->outputFilename);
+ $this->outputFilename = $outputFilename;
+
+ $zipFile->openFile($this->outputFilename);
+ $info = $zipFile->getEntryInfo($basename);
+ self::assertEquals($info->getMethodName(), 'No compression');
+ $zipFile->close();
+ }
+
+ /**
+ * Rename zip entry name.
+ */
+ public function testRename()
+ {
+ $oldName = basename(__FILE__);
+ $newName = 'tests/' . $oldName;
+
+ $zipFile = new ZipFile();
+ $zipFile->addDir(__DIR__);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ $zipFile->rename($oldName, $newName);
+ $zipFile->addFromString('file1.txt', 'content');
+ $zipFile->addFromString('file2.txt', 'content');
+ $zipFile->addFromString('file3.txt', 'content');
+ $zipFile->rename('file1.txt', 'file_long_name.txt');
+ $zipFile->rename('file2.txt', 'file4.txt');
+ $zipFile->rename('file3.txt', 'fi.txt');
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertFalse(isset($zipFile[$oldName]));
+ self::assertTrue(isset($zipFile[$newName]));
+ self::assertFalse(isset($zipFile['file1.txt']));
+ self::assertFalse(isset($zipFile['file2.txt']));
+ self::assertFalse(isset($zipFile['file3.txt']));
+ self::assertTrue(isset($zipFile['file_long_name.txt']));
+ self::assertTrue(isset($zipFile['file4.txt']));
+ self::assertTrue(isset($zipFile['fi.txt']));
+ $zipFile->close();
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage name is null
+ */
+ public function testRenameEntryNull()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->rename(null, 'new-file');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage name is null
+ */
+ public function testRenameEntryNull2()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->rename('old-file', null);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage is exists
+ */
+ public function testRenameEntryNewEntyExists()
+ {
+ $zipFile = new ZipFile();
+ $zipFile['file'] = 'content';
+ $zipFile['file2'] = 'content 2';
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ $zipFile = new ZipFile();
+ $zipFile->openFile($this->outputFilename);
+ $zipFile->rename('file2', 'file');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipNotFoundEntry
+ */
+ public function testRenameEntryNotFound()
+ {
+ $zipFile = new ZipFile();
+ $zipFile['file'] = 'content';
+ $zipFile['file2'] = 'content 2';
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ $zipFile = new ZipFile();
+ $zipFile->openFile($this->outputFilename);
+ $zipFile->rename('file2.bak', 'file3');
+ }
+
+ /**
+ * Delete entry from name.
+ */
+ public function testDeleteFromName()
+ {
+ $inputDir = dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR;
+ $deleteEntryName = 'composer.json';
+
+ $zipFile = new ZipFile();
+ $zipFile->addDir($inputDir);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ $zipFile->deleteFromName($deleteEntryName);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertFalse(isset($zipFile[$deleteEntryName]));
+ $zipFile->close();
+ }
+
+ public function testDeleteNewEntry()
+ {
+ $zipFile = new ZipFile();
+ $zipFile['entry1'] = '';
+ $zipFile['entry2'] = '';
+ $zipFile->deleteFromName('entry2');
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertEquals(sizeof($zipFile), 1);
+ self::assertTrue(isset($zipFile['entry1']));
+ self::assertFalse(isset($zipFile['entry2']));
+ $zipFile->close();
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipNotFoundEntry
+ */
+ public function testDeleteFromNameNotFoundEntry()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->deleteFromName('entry');
+ }
+
+ /**
+ * Delete zip entries from glob pattern
+ */
+ public function testDeleteFromGlob()
+ {
+ $inputDir = dirname(dirname(__DIR__));
+
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromGlobRecursive($inputDir, '**.{xml,json,md}', '/');
+ self::assertTrue(isset($zipFile['composer.json']));
+ self::assertTrue(isset($zipFile['phpunit.xml']));
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertTrue(isset($zipFile['composer.json']));
+ self::assertTrue(isset($zipFile['phpunit.xml']));
+ $zipFile->deleteFromGlob('**.{xml,json}');
+ self::assertFalse(isset($zipFile['composer.json']));
+ self::assertFalse(isset($zipFile['phpunit.xml']));
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertTrue($zipFile->count() > 0);
+
+ foreach ($zipFile->getListFiles() as $name) {
+ self::assertStringEndsWith('.md', $name);
+ }
+
+ $zipFile->close();
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Glob pattern is empty
+ */
+ public function testDeleteFromGlobFailNull()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->deleteFromGlob(null);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Glob pattern is empty
+ */
+ public function testDeleteFromGlobFailEmpty()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->deleteFromGlob('');
+ }
+
+ /**
+ * Delete entries from regex pattern
+ */
+ public function testDeleteFromRegex()
+ {
+ $inputDir = dirname(dirname(__DIR__));
+
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromRegexRecursive($inputDir, '~\.(xml|json)$~i', 'Path');
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ $zipFile->deleteFromRegex('~\.(json)$~i');
+ $zipFile->addFromString('test.txt', 'content');
+ $zipFile->deleteFromRegex('~\.txt$~');
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertFalse(isset($zipFile['Path/composer.json']));
+ self::assertFalse(isset($zipFile['Path/test.txt']));
+ self::assertTrue(isset($zipFile['Path/phpunit.xml']));
+ $zipFile->close();
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Regex pattern is empty.
+ */
+ public function testDeleteFromRegexFailNull()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->deleteFromRegex(null);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Regex pattern is empty.
+ */
+ public function testDeleteFromRegexFailEmpty()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->deleteFromRegex('');
+ }
+
+ /**
+ * Delete all entries
+ */
+ public function testDeleteAll()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addDirRecursive(dirname(dirname(__DIR__)) .DIRECTORY_SEPARATOR. 'src');
+ self::assertTrue($zipFile->count() > 0);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertTrue($zipFile->count() > 0);
+ $zipFile->deleteAll();
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectEmptyZip($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertEquals($zipFile->count(), 0);
+ $zipFile->close();
+ }
+
+ /**
+ * Test zip archive comment.
+ */
+ public function testArchiveComment()
+ {
+ $comment = "This zip file comment" . PHP_EOL
+ . "Αυτό το σχόλιο αρχείο zip" . PHP_EOL
+ . "Это комментарий zip архива" . PHP_EOL
+ . "這個ZIP文件註釋" . PHP_EOL
+ . "ეს zip ფაილის კომენტარი" . PHP_EOL
+ . "このzipファイルにコメント" . PHP_EOL
+ . "ความคิดเห็นนี้ไฟล์ซิป";
+
+ $zipFile = new ZipFile();
+ $zipFile->setArchiveComment($comment);
+ $zipFile->addFile(__FILE__);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertEquals($zipFile->getArchiveComment(), $comment);
+ $zipFile->setArchiveComment(null); // remove archive comment
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ // check empty comment
+ $zipFile->openFile($this->outputFilename);
+ self::assertEquals($zipFile->getArchiveComment(), "");
+ $zipFile->close();
+ }
+
+ /**
+ * Test very long archive comment.
+ *
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ */
+ public function testVeryLongArchiveComment()
+ {
+ $comment = "Very long comment" . PHP_EOL .
+ "Очень длинный комментарий" . PHP_EOL;
+ $comment = str_repeat($comment, ceil(0xffff / strlen($comment)) + strlen($comment) + 1);
+
+ $zipFile = new ZipFile();
+ $zipFile->setArchiveComment($comment);
+ }
+
+ /**
+ * Test zip entry comment.
+ */
+ public function testEntryComment()
+ {
+ $entries = [
+ '文件1.txt' => [
+ 'data' => CryptoUtil::randomBytes(255),
+ 'comment' => "這是註釋的條目。",
+ ],
+ 'file2.txt' => [
+ 'data' => CryptoUtil::randomBytes(255),
+ 'comment' => null
+ ],
+ 'file3.txt' => [
+ 'data' => CryptoUtil::randomBytes(255),
+ 'comment' => CryptoUtil::randomBytes(255),
+ ],
+ 'file4.txt' => [
+ 'data' => CryptoUtil::randomBytes(255),
+ 'comment' => "Комментарий файла"
+ ],
+ 'file5.txt' => [
+ 'data' => CryptoUtil::randomBytes(255),
+ 'comment' => "ไฟล์แสดงความคิดเห็น"
+ ],
+ 'file6 emoji 🙍🏼.txt' => [
+ 'data' => CryptoUtil::randomBytes(255),
+ 'comment' => "Emoji comment file - 😀 ⛈ ❤️ 🤴🏽"
+ ],
+ ];
+
+ // create archive with entry comments
+ $zipFile = new ZipFile();
+ foreach ($entries as $entryName => $item) {
+ $zipFile->addFromString($entryName, $item['data']);
+ $zipFile->setEntryComment($entryName, $item['comment']);
+ }
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ // check and modify comments
+ $zipFile->openFile($this->outputFilename);
+ foreach ($zipFile->getListFiles() as $entryName) {
+ $entriesItem = $entries[$entryName];
+ self::assertNotEmpty($entriesItem);
+ self::assertEquals($zipFile[$entryName], $entriesItem['data']);
+ self::assertEquals($zipFile->getEntryComment($entryName), (string)$entriesItem['comment']);
+ }
+ // modify comment
+ $entries['file5.txt']['comment'] = mt_rand(1, 100000000);
+ $zipFile->setEntryComment('file5.txt', $entries['file5.txt']['comment']);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ // check modify comments
+ $zipFile->openFile($this->outputFilename);
+ foreach ($entries as $entryName => $entriesItem) {
+ self::assertTrue(isset($zipFile[$entryName]));
+ self::assertEquals($zipFile->getEntryComment($entryName), (string)$entriesItem['comment']);
+ self::assertEquals($zipFile[$entryName], $entriesItem['data']);
+ }
+ $zipFile->close();
+ }
+
+ /**
+ * Test zip entry very long comment.
+ *
+ * @expectedException \PhpZip\Exception\ZipException
+ * @expectedExceptionMessage Comment too long
+ */
+ public function testVeryLongEntryComment()
+ {
+ $comment = "Very long comment" . PHP_EOL .
+ "Очень длинный комментарий" . PHP_EOL;
+ $comment = str_repeat($comment, ceil(0xffff / strlen($comment)) + strlen($comment) + 1);
+
+ $zipFile = new ZipFile();
+ $zipFile->addFile(__FILE__, 'test');
+ $zipFile->setEntryComment('test', $comment);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipNotFoundEntry
+ */
+ public function testSetEntryCommentNotFoundEntry()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->setEntryComment('test', 'comment');
+ }
+
+ /**
+ * Test all available support compression methods.
+ */
+ public function testCompressionMethod()
+ {
+ $entries = [
+ '1' => [
+ 'data' => CryptoUtil::randomBytes(255),
+ 'method' => ZipFileInterface::METHOD_STORED,
+ 'expected' => 'No compression',
+ ],
+ '2' => [
+ 'data' => CryptoUtil::randomBytes(255),
+ 'method' => ZipFileInterface::METHOD_DEFLATED,
+ 'expected' => 'Deflate',
+ ],
+ ];
+ if (extension_loaded("bz2")) {
+ $entries['3'] = [
+ 'data' => CryptoUtil::randomBytes(255),
+ 'method' => ZipFileInterface::METHOD_BZIP2,
+ 'expected' => 'Bzip2',
+ ];
+ }
+
+ $zipFile = new ZipFile();
+ foreach ($entries as $entryName => $item) {
+ $zipFile->addFromString($entryName, $item['data'], $item['method']);
+ }
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ $zipFile->setCompressionLevel(ZipFileInterface::LEVEL_BEST_COMPRESSION);
+ $zipAllInfo = $zipFile->getAllInfo();
+
+ foreach ($zipAllInfo as $entryName => $info) {
+ self::assertEquals($zipFile[$entryName], $entries[$entryName]['data']);
+ self::assertEquals($info->getMethodName(), $entries[$entryName]['expected']);
+ $entryInfo = $zipFile->getEntryInfo($entryName);
+ self::assertEquals($entryInfo, $info);
+ }
+ $zipFile->close();
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Invalid compression level. Minimum level -1. Maximum level 9
+ */
+ public function testSetInvalidCompressionLevel()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->setCompressionLevel(-2);
+ }
+
+ /**
+ * /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Invalid compression level. Minimum level -1. Maximum level 9
+ */
+ public function testSetInvalidCompressionLevel2()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->setCompressionLevel(10);
+ }
+
+ /**
+ * Test extract all files.
+ */
+ public function testExtract()
+ {
+ $entries = [
+ 'test1.txt' => CryptoUtil::randomBytes(255),
+ 'test2.txt' => CryptoUtil::randomBytes(255),
+ 'test/test 2/test3.txt' => CryptoUtil::randomBytes(255),
+ 'test empty/dir' => null,
+ ];
+
+ $zipFile = new ZipFile();
+ foreach ($entries as $entryName => $value) {
+ if ($value === null) {
+ $zipFile->addEmptyDir($entryName);
+ } else {
+ $zipFile->addFromString($entryName, $value);
+ }
+ }
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertTrue(mkdir($this->outputDirname, 0755, true));
+
+ $zipFile->openFile($this->outputFilename);
+ $zipFile->extractTo($this->outputDirname);
+ foreach ($entries as $entryName => $value) {
+ $fullExtractedFilename = $this->outputDirname . DIRECTORY_SEPARATOR . $entryName;
+ if ($value === null) {
+ self::assertTrue(is_dir($fullExtractedFilename));
+ self::assertTrue(FilesUtil::isEmptyDir($fullExtractedFilename));
+ } else {
+ self::assertTrue(is_file($fullExtractedFilename));
+ $contents = file_get_contents($fullExtractedFilename);
+ self::assertEquals($contents, $value);
+ }
+ }
+ $zipFile->close();
+ }
+
+ /**
+ * Test extract some files
+ */
+ public function testExtractSomeFiles()
+ {
+ $entries = [
+ 'test1.txt' => CryptoUtil::randomBytes(255),
+ 'test2.txt' => CryptoUtil::randomBytes(255),
+ 'test3.txt' => CryptoUtil::randomBytes(255),
+ 'test4.txt' => CryptoUtil::randomBytes(255),
+ 'test5.txt' => CryptoUtil::randomBytes(255),
+ 'test/test/test.txt' => CryptoUtil::randomBytes(255),
+ 'test/test/test 2.txt' => CryptoUtil::randomBytes(255),
+ 'test empty/dir/' => null,
+ 'test empty/dir2/' => null,
+ ];
+
+ $extractEntries = [
+ 'test1.txt',
+ 'test3.txt',
+ 'test5.txt',
+ 'test/test/test 2.txt',
+ 'test empty/dir2/'
+ ];
+
+ self::assertTrue(mkdir($this->outputDirname, 0755, true));
+
+ $zipFile = new ZipFile();
+ $zipFile->addAll($entries);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ $zipFile->openFile($this->outputFilename);
+ $zipFile->extractTo($this->outputDirname, $extractEntries);
+
+ foreach ($entries as $entryName => $value) {
+ $fullExtractFilename = $this->outputDirname . DIRECTORY_SEPARATOR . $entryName;
+ if (in_array($entryName, $extractEntries)) {
+ if ($value === null) {
+ self::assertTrue(is_dir($fullExtractFilename));
+ self::assertTrue(FilesUtil::isEmptyDir($fullExtractFilename));
+ } else {
+ self::assertTrue(is_file($fullExtractFilename));
+ $contents = file_get_contents($fullExtractFilename);
+ self::assertEquals($contents, $value);
+ }
+ } else {
+ if ($value === null) {
+ self::assertFalse(is_dir($fullExtractFilename));
+ } else {
+ self::assertFalse(is_file($fullExtractFilename));
+ }
+ }
+ }
+ self::assertFalse(is_file($this->outputDirname . DIRECTORY_SEPARATOR . 'test/test/test.txt'));
+ $zipFile->extractTo($this->outputDirname, 'test/test/test.txt');
+ self::assertTrue(is_file($this->outputDirname . DIRECTORY_SEPARATOR . 'test/test/test.txt'));
+
+ $zipFile->close();
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipException
+ * @expectedExceptionMessage not found
+ */
+ public function testExtractFail()
+ {
+ $zipFile = new ZipFile();
+ $zipFile['file'] = 'content';
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ $zipFile->openFile($this->outputFilename);
+ $zipFile->extractTo('path/to/path');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipException
+ * @expectedExceptionMessage Destination is not directory
+ */
+ public function testExtractFail2()
+ {
+ $zipFile = new ZipFile();
+ $zipFile['file'] = 'content';
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ $zipFile->openFile($this->outputFilename);
+ $zipFile->extractTo($this->outputFilename);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipException
+ * @expectedExceptionMessage Destination is not writable directory
+ */
+ public function testExtractFail3()
+ {
+ if (0 === posix_getuid()) {
+ $this->markTestSkipped('Skip the test for a user with root privileges');
+ }
+
+ $zipFile = new ZipFile();
+ $zipFile['file'] = 'content';
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertTrue(mkdir($this->outputDirname, 0444, true));
+ self::assertTrue(chmod($this->outputDirname, 0444));
+
+ $zipFile->openFile($this->outputFilename);
+ $zipFile->extractTo($this->outputDirname);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage entryName is null
+ */
+ public function testAddFromArrayAccessNullName()
+ {
+ $zipFile = new ZipFile();
+ $zipFile[null] = 'content';
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage entryName is empty
+ */
+ public function testAddFromArrayAccessEmptyName()
+ {
+ $zipFile = new ZipFile();
+ $zipFile[''] = 'content';
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Contents is null
+ */
+ public function testAddFromStringNullContents()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFromString('file', null);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Incorrect entry name
+ */
+ public function testAddFromStringNullEntryName()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFromString(null, 'contents');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipUnsupportMethod
+ * @expectedExceptionMessage Unsupported compression method
+ */
+ public function testAddFromStringUnsupportedMethod()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFromString('file', 'contents', ZipEntry::METHOD_WINZIP_AES);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Incorrect entry name
+ */
+ public function testAddFromStringEmptyEntryName()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFromString('', 'contents');
+ }
+
+ /**
+ * Test compression method from add string.
+ */
+ public function testAddFromStringCompressionMethod()
+ {
+ $fileStored = sys_get_temp_dir() . '/zip-stored.txt';
+ $fileDeflated = sys_get_temp_dir() . '/zip-deflated.txt';
+
+ self::assertNotFalse(file_put_contents($fileStored, 'content'));
+ self::assertNotFalse(file_put_contents($fileDeflated, str_repeat('content', 200)));
+
+ $zipFile = new ZipFile();
+ $zipFile->addFromString(basename($fileStored), file_get_contents($fileStored));
+ $zipFile->addFromString(basename($fileDeflated), file_get_contents($fileDeflated));
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ unlink($fileStored);
+ unlink($fileDeflated);
+
+ $zipFile->openFile($this->outputFilename);
+ $infoStored = $zipFile->getEntryInfo(basename($fileStored));
+ $infoDeflated = $zipFile->getEntryInfo(basename($fileDeflated));
+ self::assertEquals($infoStored->getMethodName(), 'No compression');
+ self::assertEquals($infoDeflated->getMethodName(), 'Deflate');
+ $zipFile->close();
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage stream is not resource
+ */
+ public function testAddFromStreamInvalidResource()
+ {
+ $zipFile = new ZipFile();
+ /** @noinspection PhpParamsInspection */
+ $zipFile->addFromStream("invalid resource", "name");
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Incorrect entry name
+ */
+ public function testAddFromStreamEmptyEntryName()
+ {
+ $handle = fopen(__FILE__, 'rb');
+
+ $zipFile = new ZipFile();
+ $zipFile->addFromStream($handle, "");
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipUnsupportMethod
+ * @expectedExceptionMessage Unsupported method
+ */
+ public function testAddFromStreamUnsupportedMethod()
+ {
+ $handle = fopen(__FILE__, 'rb');
+
+ $zipFile = new ZipFile();
+ $zipFile->addFromStream($handle, basename(__FILE__), ZipEntry::METHOD_WINZIP_AES);
+ }
+
+ /**
+ * Test compression method from add stream.
+ */
+ public function testAddFromStreamCompressionMethod()
+ {
+ $fileStored = sys_get_temp_dir() . '/zip-stored.txt';
+ $fileDeflated = sys_get_temp_dir() . '/zip-deflated.txt';
+
+ self::assertNotFalse(file_put_contents($fileStored, 'content'));
+ self::assertNotFalse(file_put_contents($fileDeflated, str_repeat('content', 200)));
+
+ $fpStored = fopen($fileStored, 'rb');
+ $fpDeflated = fopen($fileDeflated, 'rb');
+
+ $zipFile = new ZipFile();
+ $zipFile->addFromStream($fpStored, basename($fileStored));
+ $zipFile->addFromStream($fpDeflated, basename($fileDeflated));
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ unlink($fileStored);
+ unlink($fileDeflated);
+
+ $zipFile->openFile($this->outputFilename);
+ $infoStored = $zipFile->getEntryInfo(basename($fileStored));
+ $infoDeflated = $zipFile->getEntryInfo(basename($fileDeflated));
+ self::assertEquals($infoStored->getMethodName(), 'No compression');
+ self::assertEquals($infoDeflated->getMethodName(), 'Deflate');
+ $zipFile->close();
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Filename is null
+ */
+ public function testAddFileNullFileName()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFile(null);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage is not exists
+ */
+ public function testAddFileCantExists()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFile('path/to/file');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipUnsupportMethod
+ * @expectedExceptionMessage Unsupported method
+ */
+ public function testAddFileUnsupportedMethod()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFile(__FILE__, null, ZipEntry::METHOD_WINZIP_AES);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage can not open
+ */
+ public function testAddFileCantOpen()
+ {
+ if (0 === posix_getuid()) {
+ $this->markTestSkipped('Skip the test for a user with root privileges');
+ }
+
+ self::assertNotFalse(file_put_contents($this->outputFilename, ''));
+ self::assertTrue(chmod($this->outputFilename, 0244));
+
+ $zipFile = new ZipFile();
+ $zipFile->addFile($this->outputFilename);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Input dir empty
+ */
+ public function testAddDirNullDirname()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addDir(null);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Input dir empty
+ */
+ public function testAddDirEmptyDirname()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addDir("");
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage can't exists
+ */
+ public function testAddDirCantExists()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addDir(uniqid());
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Input dir empty
+ */
+ public function testAddDirRecursiveNullDirname()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addDirRecursive(null);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Input dir empty
+ */
+ public function testAddDirRecursiveEmptyDirname()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addDirRecursive("");
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage can't exists
+ */
+ public function testAddDirRecursiveCantExists()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addDirRecursive(uniqid());
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Input dir empty
+ */
+ public function testAddFilesFromGlobNull()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromGlob(null, '*.png');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Input dir empty
+ */
+ public function testAddFilesFromGlobEmpty()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromGlob("", '*.png');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage can't exists
+ */
+ public function testAddFilesFromGlobCantExists()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromGlob("path/to/path", '*.png');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage glob pattern empty
+ */
+ public function testAddFilesFromGlobNullPattern()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromGlob(__DIR__, null);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage glob pattern empty
+ */
+ public function testAddFilesFromGlobEmptyPattern()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromGlob(__DIR__, '');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Input dir empty
+ */
+ public function testAddFilesFromGlobRecursiveNull()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromGlobRecursive(null, '*.png');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Input dir empty
+ */
+ public function testAddFilesFromGlobRecursiveEmpty()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromGlobRecursive("", '*.png');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage can't exists
+ */
+ public function testAddFilesFromGlobRecursiveCantExists()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromGlobRecursive("path/to/path", '*.png');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage glob pattern empty
+ */
+ public function testAddFilesFromGlobRecursiveNullPattern()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromGlobRecursive(__DIR__, null);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage glob pattern empty
+ */
+ public function testAddFilesFromGlobRecursiveEmptyPattern()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromGlobRecursive(__DIR__, '');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Input dir empty
+ */
+ public function testAddFilesFromRegexDirectoryNull()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromRegex(null, '~\.png$~i');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Input dir empty
+ */
+ public function testAddFilesFromRegexDirectoryEmpty()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromRegex("", '~\.png$~i');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage can't exists
+ */
+ public function testAddFilesFromRegexCantExists()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromRegex("path/to/path", '~\.png$~i');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage regex pattern empty
+ */
+ public function testAddFilesFromRegexNullPattern()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromRegex(__DIR__, null);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage regex pattern empty
+ */
+ public function testAddFilesFromRegexEmptyPattern()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromRegex(__DIR__, '');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Input dir empty
+ */
+ public function testAddFilesFromRegexRecursiveDirectoryNull()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromRegexRecursive(null, '~\.png$~i');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Input dir empty
+ */
+ public function testAddFilesFromRegexRecursiveEmpty()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromRegexRecursive("", '~\.png$~i');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage can't exists
+ */
+ public function testAddFilesFromRegexRecursiveCantExists()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromGlobRecursive("path/to/path", '~\.png$~i');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage regex pattern empty
+ */
+ public function testAddFilesFromRegexRecursiveNullPattern()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromRegexRecursive(__DIR__, null);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage regex pattern empty
+ */
+ public function testAddFilesFromRegexRecursiveEmptyPattern()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFilesFromRegexRecursive(__DIR__, '');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage handle is not resource
+ */
+ public function testSaveAsStreamBadStream()
+ {
+ $zipFile = new ZipFile();
+ /** @noinspection PhpParamsInspection */
+ $zipFile->saveAsStream("bad stream");
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage can not open from write
+ */
+ public function testSaveAsFileNotWritable()
+ {
+ if (0 === posix_getuid()) {
+ $this->markTestSkipped('Skip the test for a user with root privileges');
+ }
+
+ self::assertTrue(mkdir($this->outputDirname, 0444, true));
+ self::assertTrue(chmod($this->outputDirname, 0444));
+
+ $this->outputFilename = $this->outputDirname . DIRECTORY_SEPARATOR . basename($this->outputFilename);
+
+ $zipFile = new ZipFile();
+ $zipFile->saveAsFile($this->outputFilename);
+ }
+
+ /**
+ * Test `ZipFile` implemented \ArrayAccess, \Countable and |iterator.
+ */
+ public function testZipFileArrayAccessAndCountableAndIterator()
+ {
+ $files = [];
+ $numFiles = mt_rand(20, 100);
+ for ($i = 0; $i < $numFiles; $i++) {
+ $files['file' . $i . '.txt'] = CryptoUtil::randomBytes(255);
+ }
+
+ $methods = [ZipFileInterface::METHOD_STORED, ZipFileInterface::METHOD_DEFLATED];
+ if (extension_loaded("bz2")) {
+ $methods[] = ZipFileInterface::METHOD_BZIP2;
+ }
+
+ $zipFile = new ZipFile();
+ $zipFile->setCompressionLevel(ZipFileInterface::LEVEL_BEST_SPEED);
+ foreach ($files as $entryName => $content) {
+ $zipFile->addFromString($entryName, $content, $methods[array_rand($methods)]);
+ }
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+
+ // Test \Countable
+ self::assertEquals($zipFile->count(), $numFiles);
+ self::assertEquals(count($zipFile), $numFiles);
+
+ // Test \ArrayAccess
+ reset($files);
+ foreach ($zipFile as $entryName => $content) {
+ self::assertEquals($entryName, key($files));
+ self::assertEquals($content, current($files));
+ next($files);
+ }
+
+ // Test \Iterator
+ reset($files);
+ $iterator = new \ArrayIterator($zipFile);
+ $iterator->rewind();
+ while ($iterator->valid()) {
+ $key = $iterator->key();
+ $value = $iterator->current();
+
+ self::assertEquals($key, key($files));
+ self::assertEquals($value, current($files));
+
+ next($files);
+ $iterator->next();
+ }
+ $zipFile->close();
+
+ $zipFile = new ZipFile();
+ $zipFile['file1.txt'] = 'content 1';
+ $zipFile['dir/file2.txt'] = 'content 1';
+ $zipFile['dir/empty dir/'] = null;
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertTrue(isset($zipFile['file1.txt']));
+ self::assertTrue(isset($zipFile['dir/file2.txt']));
+ self::assertTrue(isset($zipFile['dir/empty dir/']));
+ self::assertFalse(isset($zipFile['dir/empty dir/2/']));
+ $zipFile['dir/empty dir/2/'] = null;
+ unset($zipFile['dir/file2.txt'], $zipFile['dir/empty dir/']);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertTrue(isset($zipFile['file1.txt']));
+ self::assertFalse(isset($zipFile['dir/file2.txt']));
+ self::assertFalse(isset($zipFile['dir/empty dir/']));
+ self::assertTrue(isset($zipFile['dir/empty dir/2/']));
+ $zipFile->close();
+ }
+
+ public function testArrayAccessAddFile()
+ {
+ $entryName = 'path/to/file.dat';
+ $entryNameStream = 'path/to/' . basename(__FILE__);
+
+ $zipFile = new ZipFile();
+ $zipFile[$entryName] = new \SplFileInfo(__FILE__);
+ $zipFile[$entryNameStream] = fopen(__FILE__, 'r');
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertEquals(sizeof($zipFile), 2);
+ self::assertTrue(isset($zipFile[$entryName]));
+ self::assertTrue(isset($zipFile[$entryNameStream]));
+ self::assertEquals($zipFile[$entryName], file_get_contents(__FILE__));
+ self::assertEquals($zipFile[$entryNameStream], file_get_contents(__FILE__));
+ $zipFile->close();
+ }
+
+ public function testUnknownCompressionMethod()
+ {
+ $zipFile = new ZipFile();
+
+ $zipFile->addFromString('file', 'content', ZipEntry::UNKNOWN);
+ $zipFile->addFromString('file2', base64_encode(CryptoUtil::randomBytes(512)), ZipEntry::UNKNOWN);
+
+ self::assertEquals($zipFile->getEntryInfo('file')->getMethodName(), 'Unknown');
+ self::assertEquals($zipFile->getEntryInfo('file2')->getMethodName(), 'Unknown');
+
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ $zipFile->openFile($this->outputFilename);
+
+ self::assertEquals($zipFile->getEntryInfo('file')->getMethodName(), 'No compression');
+ self::assertEquals($zipFile->getEntryInfo('file2')->getMethodName(), 'Deflate');
+
+ $zipFile->close();
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage DirName empty
+ */
+ public function testAddEmptyDirNullName()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addEmptyDir(null);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage DirName empty
+ */
+ public function testAddEmptyDirEmptyName()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addEmptyDir("");
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipNotFoundEntry
+ * @expectedExceptionMessage Zip entry "bad entry name" not found
+ */
+ public function testNotFoundEntry()
+ {
+ $zipFile = new ZipFile();
+ $zipFile['bad entry name'];
+ }
+
+ /**
+ * Test rewrite input file.
+ */
+ public function testRewriteFile()
+ {
+ $zipFile = new ZipFile();
+ $zipFile['file'] = 'content';
+ $zipFile['file2'] = 'content2';
+ self::assertEquals(count($zipFile), 2);
+ $zipFile
+ ->saveAsFile($this->outputFilename)
+ ->close();
+
+ $md5file = md5_file($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertEquals(count($zipFile), 2);
+ self::assertTrue(isset($zipFile['file']));
+ self::assertTrue(isset($zipFile['file2']));
+ $zipFile['file3'] = 'content3';
+ self::assertEquals(count($zipFile), 3);
+ $zipFile = $zipFile->rewrite();
+ self::assertEquals(count($zipFile), 3);
+ self::assertTrue(isset($zipFile['file']));
+ self::assertTrue(isset($zipFile['file2']));
+ self::assertTrue(isset($zipFile['file3']));
+ $zipFile->close();
+
+ self::assertNotEquals(md5_file($this->outputFilename), $md5file);
+ }
+
+ /**
+ * Test rewrite for string.
+ */
+ public function testRewriteString()
+ {
+ $zipFile = new ZipFile();
+ $zipFile['file'] = 'content';
+ $zipFile['file2'] = 'content2';
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ $zipFile->openFromString(file_get_contents($this->outputFilename));
+ self::assertEquals(count($zipFile), 2);
+ self::assertTrue(isset($zipFile['file']));
+ self::assertTrue(isset($zipFile['file2']));
+ $zipFile['file3'] = 'content3';
+ $zipFile = $zipFile->rewrite();
+ self::assertEquals(count($zipFile), 3);
+ self::assertTrue(isset($zipFile['file']));
+ self::assertTrue(isset($zipFile['file2']));
+ self::assertTrue(isset($zipFile['file3']));
+ $zipFile->close();
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipException
+ * @expectedExceptionMessage input stream is null
+ */
+ public function testRewriteNullStream()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->rewrite();
+ }
+
+ public function testFilename0()
+ {
+ $zipFile = new ZipFile();
+ $zipFile[0] = 0;
+ self::assertTrue(isset($zipFile[0]));
+ self::assertTrue(isset($zipFile['0']));
+ self::assertCount(1, $zipFile);
+ $zipFile
+ ->saveAsFile($this->outputFilename)
+ ->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertTrue(isset($zipFile[0]));
+ self::assertTrue(isset($zipFile['0']));
+ self::assertEquals($zipFile['0'], '0');
+ self::assertCount(1, $zipFile);
+ $zipFile->close();
+
+ self::assertTrue(unlink($this->outputFilename));
+
+ $zipFile = new ZipFile();
+ $zipFile->addFromString(0, 0);
+ self::assertTrue(isset($zipFile[0]));
+ self::assertTrue(isset($zipFile['0']));
+ self::assertCount(1, $zipFile);
+ $zipFile
+ ->saveAsFile($this->outputFilename)
+ ->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+ }
+
+ public function testPsrResponse()
+ {
+ $zipFile = new ZipFile();
+ for ($i = 0; $i < 10; $i++) {
+ $zipFile[$i] = $i;
+ }
+ $filename = 'file.jar';
+ $response = $zipFile->outputAsResponse(new Response(), $filename);
+ $this->assertInstanceOf(ResponseInterface::class, $response);
+ $this->assertEquals('application/java-archive', $response->getHeaderLine('content-type'));
+ $this->assertEquals('attachment; filename="file.jar"', $response->getHeaderLine('content-disposition'));
+ }
+
+ public function testCompressionLevel()
+ {
+ $zipFile = new ZipFile();
+ $zipFile
+ ->addFromString('file', 'content', ZipFileInterface::METHOD_DEFLATED)
+ ->setCompressionLevelEntry('file', ZipFileInterface::LEVEL_BEST_COMPRESSION)
+ ->addFromString('file2', 'content', ZipFileInterface::METHOD_DEFLATED)
+ ->setCompressionLevelEntry('file2', ZipFileInterface::LEVEL_FAST)
+ ->addFromString('file3', 'content', ZipFileInterface::METHOD_DEFLATED)
+ ->setCompressionLevelEntry('file3', ZipFileInterface::LEVEL_SUPER_FAST)
+ ->addFromString('file4', 'content', ZipFileInterface::METHOD_DEFLATED)
+ ->setCompressionLevelEntry('file4', ZipFileInterface::LEVEL_DEFAULT_COMPRESSION)
+ ->saveAsFile($this->outputFilename)
+ ->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertEquals($zipFile->getEntryInfo('file')
+ ->getCompressionLevel(), ZipFileInterface::LEVEL_BEST_COMPRESSION);
+ self::assertEquals($zipFile->getEntryInfo('file2')
+ ->getCompressionLevel(), ZipFileInterface::LEVEL_FAST);
+ self::assertEquals($zipFile->getEntryInfo('file3')
+ ->getCompressionLevel(), ZipFileInterface::LEVEL_SUPER_FAST);
+ self::assertEquals($zipFile->getEntryInfo('file4')
+ ->getCompressionLevel(), ZipFileInterface::LEVEL_DEFAULT_COMPRESSION);
+ $zipFile->close();
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Invalid compression level
+ */
+ public function testInvalidCompressionLevel()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFromString('file', 'content');
+ $zipFile->setCompressionLevel(15);
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Invalid compression level
+ */
+ public function testInvalidCompressionLevelEntry()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFromString('file', 'content');
+ $zipFile->setCompressionLevelEntry('file', 15);
+ }
+
+ public function testCompressionGlobal()
+ {
+ $zipFile = new ZipFile();
+ for ($i = 0; $i < 10; $i++) {
+ $zipFile->addFromString('file' . $i, 'content', ZipFileInterface::METHOD_DEFLATED);
+ }
+ $zipFile
+ ->setCompressionLevel(ZipFileInterface::LEVEL_BEST_SPEED)
+ ->saveAsFile($this->outputFilename)
+ ->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ $infoList = $zipFile->getAllInfo();
+ array_walk($infoList, function (ZipInfo $zipInfo) {
+ self::assertEquals($zipInfo->getCompressionLevel(), ZipFileInterface::LEVEL_BEST_SPEED);
+ });
+ $zipFile->close();
+ }
+
+ public function testCompressionMethodEntry()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFromString('file', 'content', ZipFileInterface::METHOD_STORED);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertEquals($zipFile->getEntryInfo('file')->getMethodName(), 'No compression');
+ $zipFile->setCompressionMethodEntry('file', ZipFileInterface::METHOD_DEFLATED);
+ self::assertEquals($zipFile->getEntryInfo('file')->getMethodName(), 'Deflate');
+
+ $zipFile->rewrite();
+ self::assertEquals($zipFile->getEntryInfo('file')->getMethodName(), 'Deflate');
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipUnsupportMethod
+ * @expectedExceptionMessage Unsupported method
+ */
+ public function testInvalidCompressionMethodEntry()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFromString('file', 'content', ZipFileInterface::METHOD_STORED);
+ $zipFile->setCompressionMethodEntry('file', 99);
+ }
+
+ public function testUnchangeAll()
+ {
+ $zipFile = new ZipFile();
+ for ($i = 0; $i < 10; $i++) {
+ $zipFile[$i] = $i;
+ }
+ $zipFile->setArchiveComment('comment');
+ self::assertCount(10, $zipFile);
+ self::assertEquals($zipFile->getArchiveComment(), 'comment');
+ $zipFile->saveAsFile($this->outputFilename);
+
+ $zipFile->unchangeAll();
+ self::assertCount(0, $zipFile);
+ self::assertEquals($zipFile->getArchiveComment(), null);
+ $zipFile->close();
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertCount(10, $zipFile);
+ self::assertEquals($zipFile->getArchiveComment(), 'comment');
+
+ for ($i = 10; $i < 100; $i++) {
+ $zipFile[$i] = $i;
+ }
+ $zipFile->setArchiveComment('comment 2');
+ self::assertCount(100, $zipFile);
+ self::assertEquals($zipFile->getArchiveComment(), 'comment 2');
+
+ $zipFile->unchangeAll();
+ self::assertCount(10, $zipFile);
+ self::assertEquals($zipFile->getArchiveComment(), 'comment');
+ $zipFile->close();
+ }
+
+ public function testUnchangeArchiveComment()
+ {
+ $zipFile = new ZipFile();
+ for ($i = 0; $i < 10; $i++) {
+ $zipFile[$i] = $i;
+ }
+ $zipFile->setArchiveComment('comment');
+ self::assertEquals($zipFile->getArchiveComment(), 'comment');
+ $zipFile->saveAsFile($this->outputFilename);
+
+ $zipFile->unchangeArchiveComment();
+ self::assertEquals($zipFile->getArchiveComment(), null);
+ $zipFile->close();
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertEquals($zipFile->getArchiveComment(), 'comment');
+ $zipFile->setArchiveComment('comment 2');
+ self::assertEquals($zipFile->getArchiveComment(), 'comment 2');
+
+ $zipFile->unchangeArchiveComment();
+ self::assertEquals($zipFile->getArchiveComment(), 'comment');
+ $zipFile->close();
+ }
+
+ public function testUnchangeEntry()
+ {
+ $zipFile = new ZipFile();
+ $zipFile['file 1'] = 'content 1';
+ $zipFile['file 2'] = 'content 2';
+ $zipFile
+ ->saveAsFile($this->outputFilename)
+ ->close();
+
+ $zipFile->openFile($this->outputFilename);
+
+ $zipFile['file 1'] = 'modify content 1';
+ $zipFile->setPasswordEntry('file 1', 'password');
+
+ self::assertEquals($zipFile['file 1'], 'modify content 1');
+ self::assertTrue($zipFile->getEntryInfo('file 1')->isEncrypted());
+
+ self::assertEquals($zipFile['file 2'], 'content 2');
+ self::assertFalse($zipFile->getEntryInfo('file 2')->isEncrypted());
+
+ $zipFile->unchangeEntry('file 1');
+
+ self::assertEquals($zipFile['file 1'], 'content 1');
+ self::assertFalse($zipFile->getEntryInfo('file 1')->isEncrypted());
+
+ self::assertEquals($zipFile['file 2'], 'content 2');
+ self::assertFalse($zipFile->getEntryInfo('file 2')->isEncrypted());
+ $zipFile->close();
+ }
+
+ /**
+ * Test support ZIP64 ext (slow test - normal).
+ * Create > 65535 files in archive and open and extract to /dev/null.
+ */
+ public function testCreateAndOpenZip64Ext()
+ {
+ $countFiles = 0xffff + 1;
+
+ $zipFile = new ZipFile();
+ for ($i = 0; $i < $countFiles; $i++) {
+ $zipFile[$i . '.txt'] = $i;
+ }
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertEquals($zipFile->count(), $countFiles);
+ $i = 0;
+ foreach ($zipFile as $entry => $content) {
+ self::assertEquals($entry, $i . '.txt');
+ self::assertEquals($content, $i);
+ $i++;
+ }
+ $zipFile->close();
+ }
+}
diff --git a/vendor/nelexa/zip/tests/PhpZip/ZipMatcherTest.php b/vendor/nelexa/zip/tests/PhpZip/ZipMatcherTest.php
new file mode 100644
index 0000000..c824765
--- /dev/null
+++ b/vendor/nelexa/zip/tests/PhpZip/ZipMatcherTest.php
@@ -0,0 +1,111 @@
+<?php
+
+namespace PhpZip;
+
+use PhpZip\Model\ZipEntryMatcher;
+use PhpZip\Model\ZipInfo;
+use PhpZip\Util\CryptoUtil;
+
+class ZipMatcherTest extends \PHPUnit_Framework_TestCase
+{
+ public function testMatcher()
+ {
+ $zipFile = new ZipFile();
+ for ($i = 0; $i < 100; $i++) {
+ $zipFile[$i] = $i;
+ }
+
+ $matcher = $zipFile->matcher();
+ self::assertInstanceOf(ZipEntryMatcher::class, $matcher);
+
+ $this->assertTrue(is_array($matcher->getMatches()));
+ $this->assertCount(0, $matcher);
+
+ $matcher->add(1)->add(10)->add(20);
+ $this->assertCount(3, $matcher);
+ $this->assertEquals($matcher->getMatches(), ['1', '10', '20']);
+
+ $matcher->delete();
+ $this->assertCount(97, $zipFile);
+ $this->assertCount(0, $matcher);
+
+ $matcher->match('~^[2][1-5]|[3][6-9]|40$~s');
+ $this->assertCount(10, $matcher);
+ $actualMatches = [
+ '21', '22', '23', '24', '25',
+ '36', '37', '38', '39',
+ '40'
+ ];
+ $this->assertEquals($matcher->getMatches(), $actualMatches);
+ $matcher->setPassword('qwerty');
+ $info = $zipFile->getAllInfo();
+ array_walk($info, function (ZipInfo $zipInfo) use ($actualMatches) {
+ self::assertEquals($zipInfo->isEncrypted(), in_array($zipInfo->getName(), $actualMatches));
+ });
+
+ $matcher->all();
+ $this->assertCount(count($zipFile), $matcher);
+
+ $expectedNames = [];
+ $matcher->invoke(function ($entryName) use (&$expectedNames) {
+ $expectedNames[] = $entryName;
+ });
+ $this->assertEquals($expectedNames, $matcher->getMatches());
+
+ $zipFile->close();
+ }
+
+ public function testDocsExample()
+ {
+ $zipFile = new ZipFile();
+ for ($i = 0; $i < 100; $i++) {
+ $zipFile['file_'.$i.'.jpg'] = CryptoUtil::randomBytes(100);
+ }
+
+ $renameEntriesArray = [
+ 'file_10.jpg',
+ 'file_11.jpg',
+ 'file_12.jpg',
+ 'file_13.jpg',
+ 'file_14.jpg',
+ 'file_15.jpg',
+ 'file_16.jpg',
+ 'file_17.jpg',
+ 'file_18.jpg',
+ 'file_19.jpg',
+ 'file_50.jpg',
+ 'file_51.jpg',
+ 'file_52.jpg',
+ 'file_53.jpg',
+ 'file_54.jpg',
+ 'file_55.jpg',
+ 'file_56.jpg',
+ 'file_57.jpg',
+ 'file_58.jpg',
+ 'file_59.jpg',
+ ];
+
+ foreach ($renameEntriesArray as $name) {
+ self::assertTrue(isset($zipFile[$name]));
+ }
+
+ $matcher = $zipFile->matcher();
+ $matcher->match('~^file_(1|5)\d+~');
+ self::assertEquals($matcher->getMatches(), $renameEntriesArray);
+
+ $matcher->invoke(function ($entryName) use ($zipFile) {
+ $newName = preg_replace('~\.(jpe?g)$~i', '.no_optimize.$1', $entryName);
+ $zipFile->rename($entryName, $newName);
+ });
+
+ foreach ($renameEntriesArray as $name) {
+ self::assertFalse(isset($zipFile[$name]));
+
+ $pathInfo = pathinfo($name);
+ $newName = $pathInfo['filename'].'.no_optimize.'.$pathInfo['extension'];
+ self::assertTrue(isset($zipFile[$newName]));
+ }
+
+ $zipFile->close();
+ }
+}
diff --git a/vendor/nelexa/zip/tests/PhpZip/ZipPasswordTest.php b/vendor/nelexa/zip/tests/PhpZip/ZipPasswordTest.php
new file mode 100644
index 0000000..1321530
--- /dev/null
+++ b/vendor/nelexa/zip/tests/PhpZip/ZipPasswordTest.php
@@ -0,0 +1,399 @@
+<?php
+
+namespace PhpZip;
+
+use PhpZip\Exception\ZipAuthenticationException;
+use PhpZip\Model\ZipInfo;
+use PhpZip\Util\CryptoUtil;
+
+/**
+ * Tests with zip password.
+ */
+class ZipPasswordTest extends ZipFileAddDirTest
+{
+ /**
+ * Test archive password.
+ */
+ public function testSetPassword()
+ {
+ if (PHP_INT_SIZE === 4) {
+ $this->markTestSkipped('Skip test for 32-bit system. Not support Traditional PKWARE Encryption.');
+ }
+
+ $password = base64_encode(CryptoUtil::randomBytes(100));
+ $badPassword = "bad password";
+
+ // create encryption password with ZipCrypto
+ $zipFile = new ZipFile();
+ $zipFile->addDir(__DIR__);
+ $zipFile->setPassword($password, ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename, $password);
+
+ // check bad password for ZipCrypto
+ $zipFile->openFile($this->outputFilename);
+ $zipFile->setReadPassword($badPassword);
+ foreach ($zipFile->getListFiles() as $entryName) {
+ try {
+ $zipFile[$entryName];
+ self::fail("Expected Exception has not been raised.");
+ } catch (ZipAuthenticationException $ae) {
+ self::assertNotNull($ae);
+ }
+ }
+
+ // check correct password for ZipCrypto
+ $zipFile->setReadPassword($password);
+ foreach ($zipFile->getAllInfo() as $info) {
+ self::assertTrue($info->isEncrypted());
+ self::assertContains('ZipCrypto', $info->getMethodName());
+ $decryptContent = $zipFile[$info->getName()];
+ self::assertNotEmpty($decryptContent);
+ self::assertContains('<?php', $decryptContent);
+ }
+
+ // change encryption method to WinZip Aes and update file
+ $zipFile->setPassword($password, ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES);
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename, $password);
+
+ // check from WinZip AES encryption
+ $zipFile->openFile($this->outputFilename);
+ // set bad password WinZip AES
+ $zipFile->setReadPassword($badPassword);
+ foreach ($zipFile->getListFiles() as $entryName) {
+ try {
+ $zipFile[$entryName];
+ self::fail("Expected Exception has not been raised.");
+ } catch (ZipAuthenticationException $ae) {
+ self::assertNotNull($ae);
+ }
+ }
+
+ // set correct password WinZip AES
+ $zipFile->setReadPassword($password);
+ foreach ($zipFile->getAllInfo() as $info) {
+ self::assertTrue($info->isEncrypted());
+ self::assertContains('WinZip', $info->getMethodName());
+ $decryptContent = $zipFile[$info->getName()];
+ self::assertNotEmpty($decryptContent);
+ self::assertContains('<?php', $decryptContent);
+ }
+
+ // clear password
+ $zipFile->addFromString('file1', '');
+ $zipFile->disableEncryption();
+ $zipFile->addFromString('file2', '');
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename);
+
+ // check remove password
+ $zipFile->openFile($this->outputFilename);
+ foreach ($zipFile->getAllInfo() as $info) {
+ self::assertFalse($info->isEncrypted());
+ }
+ $zipFile->close();
+ }
+
+ public function testTraditionalEncryption()
+ {
+ if (PHP_INT_SIZE === 4) {
+ $this->markTestSkipped('Skip test for 32-bit system. Not support Traditional PKWARE Encryption.');
+ }
+
+ $password = base64_encode(CryptoUtil::randomBytes(50));
+
+ $zip = new ZipFile();
+ $zip->addDirRecursive($this->outputDirname);
+ $zip->setPassword($password, ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL);
+ $zip->saveAsFile($this->outputFilename);
+ $zip->close();
+
+ self::assertCorrectZipArchive($this->outputFilename, $password);
+
+ $zip->openFile($this->outputFilename);
+ $zip->setReadPassword($password);
+ self::assertFilesResult($zip, array_keys(self::$files));
+ foreach ($zip->getAllInfo() as $info) {
+ if (!$info->isFolder()) {
+ self::assertTrue($info->isEncrypted());
+ self::assertContains('ZipCrypto', $info->getMethodName());
+ }
+ }
+ $zip->close();
+ }
+
+ /**
+ * @dataProvider winZipKeyStrengthProvider
+ * @param int $encryptionMethod
+ * @param int $bitSize
+ */
+ public function testWinZipAesEncryption($encryptionMethod, $bitSize)
+ {
+ $password = base64_encode(CryptoUtil::randomBytes(50));
+
+ $zip = new ZipFile();
+ $zip->addDirRecursive($this->outputDirname);
+ $zip->setPassword($password, $encryptionMethod);
+ $zip->saveAsFile($this->outputFilename);
+ $zip->close();
+
+ self::assertCorrectZipArchive($this->outputFilename, $password);
+
+ $zip->openFile($this->outputFilename);
+ $zip->setReadPassword($password);
+ self::assertFilesResult($zip, array_keys(self::$files));
+ foreach ($zip->getAllInfo() as $info) {
+ if (!$info->isFolder()) {
+ self::assertTrue($info->isEncrypted());
+ self::assertEquals($info->getEncryptionMethod(), $encryptionMethod);
+ self::assertContains('WinZip AES-' . $bitSize, $info->getMethodName());
+ }
+ }
+ $zip->close();
+ }
+
+ /**
+ * @return array
+ */
+ public function winZipKeyStrengthProvider()
+ {
+ return [
+ [ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_128, 128],
+ [ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_192, 192],
+ [ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES, 256],
+ [ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES_256, 256],
+ ];
+ }
+
+ public function testEncryptionEntries()
+ {
+ if (PHP_INT_SIZE === 4) {
+ $this->markTestSkipped('Skip test for 32-bit system. Not support Traditional PKWARE Encryption.');
+ }
+
+ $password1 = '353442434235424234';
+ $password2 = 'adgerhvrwjhqqehtqhkbqrgewg';
+
+ $zip = new ZipFile();
+ $zip->addDir($this->outputDirname);
+ $zip->setPasswordEntry('.hidden', $password1, ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL);
+ $zip->setPasswordEntry('text file.txt', $password2, ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES);
+ $zip->saveAsFile($this->outputFilename);
+ $zip->close();
+
+ $zip->openFile($this->outputFilename);
+ $zip->setReadPasswordEntry('.hidden', $password1);
+ $zip->setReadPasswordEntry('text file.txt', $password2);
+ self::assertFilesResult($zip, [
+ '.hidden',
+ 'text file.txt',
+ 'Текстовый документ.txt',
+ 'empty dir/',
+ ]);
+
+ $info = $zip->getEntryInfo('.hidden');
+ self::assertTrue($info->isEncrypted());
+ self::assertContains('ZipCrypto', $info->getMethodName());
+
+ $info = $zip->getEntryInfo('text file.txt');
+ self::assertTrue($info->isEncrypted());
+ self::assertContains('WinZip AES', $info->getMethodName());
+
+ self::assertFalse($zip->getEntryInfo('Текстовый документ.txt')->isEncrypted());
+ self::assertFalse($zip->getEntryInfo('empty dir/')->isEncrypted());
+
+ $zip->close();
+ }
+
+ public function testEncryptionEntriesWithDefaultPassword()
+ {
+ if (PHP_INT_SIZE === 4) {
+ $this->markTestSkipped('Skip test for 32-bit system. Not support Traditional PKWARE Encryption.');
+ }
+
+ $password1 = '353442434235424234';
+ $password2 = 'adgerhvrwjhqqehtqhkbqrgewg';
+ $defaultPassword = ' f f f f f ffff f5 ';
+
+ $zip = new ZipFile();
+ $zip->addDir($this->outputDirname);
+ $zip->setPassword($defaultPassword);
+ $zip->setPasswordEntry('.hidden', $password1, ZipFileInterface::ENCRYPTION_METHOD_TRADITIONAL);
+ $zip->setPasswordEntry('text file.txt', $password2, ZipFileInterface::ENCRYPTION_METHOD_WINZIP_AES);
+ $zip->saveAsFile($this->outputFilename);
+ $zip->close();
+
+ $zip->openFile($this->outputFilename);
+ $zip->setReadPassword($defaultPassword);
+ $zip->setReadPasswordEntry('.hidden', $password1);
+ $zip->setReadPasswordEntry('text file.txt', $password2);
+ self::assertFilesResult($zip, [
+ '.hidden',
+ 'text file.txt',
+ 'Текстовый документ.txt',
+ 'empty dir/',
+ ]);
+
+ $info = $zip->getEntryInfo('.hidden');
+ self::assertTrue($info->isEncrypted());
+ self::assertContains('ZipCrypto', $info->getMethodName());
+
+ $info = $zip->getEntryInfo('text file.txt');
+ self::assertTrue($info->isEncrypted());
+ self::assertContains('WinZip AES', $info->getMethodName());
+
+ $info = $zip->getEntryInfo('Текстовый документ.txt');
+ self::assertTrue($info->isEncrypted());
+ self::assertContains('WinZip AES', $info->getMethodName());
+
+ self::assertFalse($zip->getEntryInfo('empty dir/')->isEncrypted());
+
+ $zip->close();
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipException
+ * @expectedExceptionMessage Invalid encryption method
+ */
+ public function testSetEncryptionMethodInvalid()
+ {
+ $zipFile = new ZipFile();
+ $encryptionMethod = 9999;
+ $zipFile->setPassword('pass', $encryptionMethod);
+ $zipFile['entry'] = 'content';
+ $zipFile->outputAsString();
+ }
+
+ public function testEntryPassword()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->setPassword('pass');
+ $zipFile['file'] = 'content';
+ self::assertFalse($zipFile->getEntryInfo('file')->isEncrypted());
+ for ($i = 1; $i <= 10; $i++) {
+ $zipFile['file' . $i] = 'content';
+ if ($i < 6) {
+ $zipFile->setPasswordEntry('file' . $i, 'pass');
+ self::assertTrue($zipFile->getEntryInfo('file' . $i)->isEncrypted());
+ } else {
+ self::assertFalse($zipFile->getEntryInfo('file' . $i)->isEncrypted());
+ }
+ }
+ $zipFile->disableEncryptionEntry('file3');
+ self::assertFalse($zipFile->getEntryInfo('file3')->isEncrypted());
+ self::asserttrue($zipFile->getEntryInfo('file2')->isEncrypted());
+ $zipFile->disableEncryption();
+ $infoList = $zipFile->getAllInfo();
+ array_walk($infoList, function (ZipInfo $zipInfo) {
+ self::assertFalse($zipInfo->isEncrypted());
+ });
+ $zipFile->close();
+ }
+
+ /**
+ * @expectedException \PhpZip\Exception\ZipException
+ * @expectedExceptionMessage Invalid encryption method
+ */
+ public function testInvalidEncryptionMethodEntry()
+ {
+ $zipFile = new ZipFile();
+ $zipFile->addFromString('file', 'content', ZipFileInterface::METHOD_STORED);
+ $zipFile->setPasswordEntry('file', 'pass', 99);
+ }
+
+ public function testArchivePasswordUpdateWithoutSetReadPassword()
+ {
+ $zipFile = new ZipFile();
+ $zipFile['file1'] = 'content';
+ $zipFile['file2'] = 'content';
+ $zipFile['file3'] = 'content';
+ $zipFile->setPassword('password');
+ $zipFile->saveAsFile($this->outputFilename);
+ $zipFile->close();
+
+ self::assertCorrectZipArchive($this->outputFilename, 'password');
+
+ $zipFile->openFile($this->outputFilename);
+ self::assertCount(3, $zipFile);
+ foreach ($zipFile->getAllInfo() as $info) {
+ self::assertTrue($info->isEncrypted());
+ }
+ unset($zipFile['file3']);
+ $zipFile['file4'] = 'content';
+ $zipFile->rewrite();
+
+ self::assertCorrectZipArchive($this->outputFilename, 'password');
+
+ self::assertCount(3, $zipFile);
+ self::assertFalse(isset($zipFile['file3']));
+ self::assertTrue(isset($zipFile['file4']));
+ self::assertTrue($zipFile->getEntryInfo('file1')->isEncrypted());
+ self::assertTrue($zipFile->getEntryInfo('file2')->isEncrypted());
+ self::assertFalse($zipFile->getEntryInfo('file4')->isEncrypted());
+ self::assertEquals($zipFile['file4'], 'content');
+
+ $zipFile->extractTo($this->outputDirname, ['file4']);
+
+ self::assertTrue(file_exists($this->outputDirname . DIRECTORY_SEPARATOR . 'file4'));
+ self::assertEquals(file_get_contents($this->outputDirname . DIRECTORY_SEPARATOR . 'file4'), $zipFile['file4']);
+
+ $zipFile->close();
+ }
+
+ /**
+ * @see https://github.com/Ne-Lexa/php-zip/issues/9
+ */
+ public function testIssues9()
+ {
+ $contents = str_pad('', 1000, 'test;test2;test3' . PHP_EOL, STR_PAD_RIGHT);
+ $password = base64_encode(CryptoUtil::randomBytes(20));
+
+ $encryptMethod = ZipFile::ENCRYPTION_METHOD_WINZIP_AES_256;
+ $zipFile = new ZipFile();
+ $zipFile
+ ->addFromString('codes.csv', $contents)
+ ->setPassword($password, $encryptMethod)
+ ->saveAsFile($this->outputFilename)
+ ->close();
+
+ $this->assertCorrectZipArchive($this->outputFilename, $password);
+
+ $zipFile->openFile($this->outputFilename);
+ $zipFile->setReadPassword($password);
+ $this->assertEquals($zipFile['codes.csv'], $contents);
+ $zipFile->close();
+ }
+
+ public function testReadAesEncryptedAndRewriteArchive()
+ {
+ $file = __DIR__ . '/resources/aes_password_archive.zip';
+ $password = '1234567890';
+
+ $zipFile = new ZipFile();
+ $zipFile->openFile($file);
+ $zipFile->setReadPassword($password);
+ $zipFile->setEntryComment('contents.txt', 'comment'); // change entry, but not changed contents
+ $zipFile->saveAsFile($this->outputFilename);
+
+ $zipFile2 = new ZipFile();
+ $zipFile2->openFile($this->outputFilename);
+ $zipFile2->setReadPassword($password);
+ $this->assertEquals($zipFile2->getListFiles(), $zipFile->getListFiles());
+ foreach ($zipFile as $name => $contents) {
+ $this->assertNotEmpty($name);
+ $this->assertNotEmpty($contents);
+ $this->assertContains('test contents', $contents);
+ $this->assertEquals($zipFile2[$name], $contents);
+ }
+ $zipFile2->close();
+
+ $zipFile->close();
+ }
+}
diff --git a/vendor/nelexa/zip/tests/PhpZip/ZipTestCase.php b/vendor/nelexa/zip/tests/PhpZip/ZipTestCase.php
new file mode 100644
index 0000000..6de8537
--- /dev/null
+++ b/vendor/nelexa/zip/tests/PhpZip/ZipTestCase.php
@@ -0,0 +1,137 @@
+<?php
+
+namespace PhpZip;
+
+use PhpZip\Model\EndOfCentralDirectory;
+use PhpZip\Util\FilesUtil;
+
+/**
+ * PHPUnit test case and helper methods.
+ */
+class ZipTestCase extends \PHPUnit_Framework_TestCase
+{
+
+ /**
+ * @var string
+ */
+ protected $outputFilename;
+ /**
+ * @var string
+ */
+ protected $outputDirname;
+
+ /**
+ * Before test
+ */
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $id = uniqid('phpzip');
+ $tempDir = sys_get_temp_dir() . '/phpunit-phpzip';
+ if (!is_dir($tempDir)) {
+ if (!mkdir($tempDir, 0755, true)) {
+ throw new \RuntimeException("Dir " . $tempDir . " can't created");
+ }
+ }
+ $this->outputFilename = $tempDir . '/' . $id . '.zip';
+ $this->outputDirname = $tempDir . '/' . $id;
+ }
+
+ /**
+ * After test
+ */
+ protected function tearDown()
+ {
+ parent::tearDown();
+
+ if ($this->outputFilename !== null && file_exists($this->outputFilename)) {
+ unlink($this->outputFilename);
+ }
+ if ($this->outputDirname !== null && is_dir($this->outputDirname)) {
+ FilesUtil::removeDir($this->outputDirname);
+ }
+ }
+
+ /**
+ * Assert correct zip archive.
+ *
+ * @param string $filename
+ * @param string|null $password
+ */
+ public static function assertCorrectZipArchive($filename, $password = null)
+ {
+ if (DIRECTORY_SEPARATOR !== '\\' && `which unzip`) {
+ $command = "unzip";
+ if ($password !== null) {
+ $command .= " -P " . escapeshellarg($password);
+ }
+ $command .= " -t " . escapeshellarg($filename);
+ exec($command, $output, $returnCode);
+
+ $output = implode(PHP_EOL, $output);
+
+ if ($password !== null && $returnCode === 81) {
+ if (`which 7z`) {
+ // WinZip 99-character limit
+ // @see https://sourceforge.net/p/p7zip/discussion/383044/thread/c859a2f0/
+ $password = substr($password, 0, 99);
+
+ $command = "7z t -p" . escapeshellarg($password) . " " . escapeshellarg($filename);
+ exec($command, $output, $returnCode);
+
+ $output = implode(PHP_EOL, $output);
+
+ self::assertEquals($returnCode, 0);
+ self::assertNotContains(' Errors', $output);
+ self::assertContains(' Ok', $output);
+ } else {
+ fwrite(STDERR, 'Program unzip cannot support this function.' . PHP_EOL);
+ fwrite(STDERR, 'Please install 7z. For Ubuntu-like: sudo apt-get install p7zip-full' . PHP_EOL);
+ }
+ } else {
+ self::assertEquals($returnCode, 0, $output);
+ self::assertNotContains('incorrect password', $output);
+ self::assertContains(' OK', $output);
+ self::assertContains('No errors', $output);
+ }
+ }
+ }
+
+ /**
+ * Assert correct empty zip archive.
+ *
+ * @param $filename
+ */
+ public static function assertCorrectEmptyZip($filename)
+ {
+ if (DIRECTORY_SEPARATOR !== '\\' && `which zipinfo`) {
+ exec("zipinfo " . escapeshellarg($filename), $output, $returnCode);
+
+ $output = implode(PHP_EOL, $output);
+
+ self::assertContains('Empty zipfile', $output);
+ }
+ $actualEmptyZipData = pack('VVVVVv', EndOfCentralDirectory::END_OF_CENTRAL_DIRECTORY_RECORD_SIG, 0, 0, 0, 0, 0);
+ self::assertEquals(file_get_contents($filename), $actualEmptyZipData);
+ }
+
+ /**
+ * @param string $filename
+ * @param bool $showErrors
+ * @return bool|null If null - can not install zipalign
+ */
+ public static function doZipAlignVerify($filename, $showErrors = false)
+ {
+ if (DIRECTORY_SEPARATOR !== '\\' && `which zipalign`) {
+ exec("zipalign -c -v 4 " . escapeshellarg($filename), $output, $returnCode);
+ if ($showErrors && $returnCode !== 0) {
+ fwrite(STDERR, implode(PHP_EOL, $output));
+ }
+ return $returnCode === 0;
+ } else {
+ fwrite(STDERR, 'Can not find program "zipalign" for test' . PHP_EOL);
+ return null;
+ }
+ }
+}
diff --git a/vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/binarynull.zip b/vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/binarynull.zip
new file mode 100644
index 0000000..9da004e
--- /dev/null
+++ b/vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/binarynull.zip
Binary files differ
diff --git a/vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/bug40228.zip b/vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/bug40228.zip
new file mode 100644
index 0000000..bbcd951
--- /dev/null
+++ b/vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/bug40228.zip
Binary files differ
diff --git a/vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/bug49072.zip b/vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/bug49072.zip
new file mode 100644
index 0000000..16bbcd0
--- /dev/null
+++ b/vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/bug49072.zip
Binary files differ
diff --git a/vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/bug70752.zip b/vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/bug70752.zip
new file mode 100644
index 0000000..9bec61b
--- /dev/null
+++ b/vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/bug70752.zip
Binary files differ
diff --git a/vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/bug8009.zip b/vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/bug8009.zip
new file mode 100644
index 0000000..45bedcb
--- /dev/null
+++ b/vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/bug8009.zip
Binary files differ
diff --git a/vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/pecl12414.zip b/vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/pecl12414.zip
new file mode 100644
index 0000000..6cbc60f
--- /dev/null
+++ b/vendor/nelexa/zip/tests/PhpZip/php-zip-ext-test-resources/pecl12414.zip
Binary files differ
diff --git a/vendor/nelexa/zip/tests/PhpZip/resources/aes_password_archive.zip b/vendor/nelexa/zip/tests/PhpZip/resources/aes_password_archive.zip
new file mode 100644
index 0000000..7de71ae
--- /dev/null
+++ b/vendor/nelexa/zip/tests/PhpZip/resources/aes_password_archive.zip
Binary files differ
diff --git a/vendor/nelexa/zip/tests/PhpZip/resources/test.apk b/vendor/nelexa/zip/tests/PhpZip/resources/test.apk
new file mode 100644
index 0000000..00411d3
--- /dev/null
+++ b/vendor/nelexa/zip/tests/PhpZip/resources/test.apk
Binary files differ
diff --git a/vendor/phpdocumentor/reflection-common/.travis.yml b/vendor/phpdocumentor/reflection-common/.travis.yml
new file mode 100644
index 0000000..958ecf8
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-common/.travis.yml
@@ -0,0 +1,35 @@
+language: php
+php:
+ - 5.5
+ - 5.6
+ - 7.0
+ - 7.1
+ - hhvm
+ - nightly
+
+matrix:
+ allow_failures:
+ - php:
+ - hhvm
+ - nightly
+
+cache:
+ directories:
+ - $HOME/.composer/cache
+
+script:
+ - vendor/bin/phpunit --coverage-clover=coverage.clover -v
+ - composer update --no-interaction --prefer-source
+ - vendor/bin/phpunit -v
+
+before_script:
+ - composer install --no-interaction
+
+after_script:
+ - if [ $TRAVIS_PHP_VERSION = '5.6' ]; then wget https://scrutinizer-ci.com/ocular.phar; php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi
+
+notifications:
+ irc: "irc.freenode.org#phpdocumentor"
+ email:
+ - me@mikevanriel.com
+ - ashnazg@php.net
diff --git a/vendor/phpdocumentor/reflection-common/LICENSE b/vendor/phpdocumentor/reflection-common/LICENSE
new file mode 100644
index 0000000..ed6926c
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-common/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 phpDocumentor
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/vendor/phpdocumentor/reflection-common/README.md b/vendor/phpdocumentor/reflection-common/README.md
new file mode 100644
index 0000000..68a80c8
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-common/README.md
@@ -0,0 +1,2 @@
+# ReflectionCommon
+[![Build Status](https://travis-ci.org/phpDocumentor/ReflectionCommon.svg?branch=master)](https://travis-ci.org/phpDocumentor/ReflectionCommon)
diff --git a/vendor/phpdocumentor/reflection-common/composer.json b/vendor/phpdocumentor/reflection-common/composer.json
new file mode 100644
index 0000000..90eee0f
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-common/composer.json
@@ -0,0 +1,29 @@
+{
+ "name": "phpdocumentor/reflection-common",
+ "keywords": ["phpdoc", "phpDocumentor", "reflection", "static analysis", "FQSEN"],
+ "homepage": "http://www.phpdoc.org",
+ "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Jaap van Otterdijk",
+ "email": "opensource@ijaap.nl"
+ }
+ ],
+ "require": {
+ "php": ">=5.5"
+ },
+ "autoload" : {
+ "psr-4" : {
+ "phpDocumentor\\Reflection\\": ["src"]
+ }
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6"
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-common/src/Element.php b/vendor/phpdocumentor/reflection-common/src/Element.php
new file mode 100644
index 0000000..712e30e
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-common/src/Element.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * phpDocumentor
+ *
+ * PHP Version 5.5
+ *
+ * @copyright 2010-2015 Mike van Riel / Naenius (http://www.naenius.com)
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection;
+
+/**
+ * Interface for Api Elements
+ */
+interface Element
+{
+ /**
+ * Returns the Fqsen of the element.
+ *
+ * @return Fqsen
+ */
+ public function getFqsen();
+
+ /**
+ * Returns the name of the element.
+ *
+ * @return string
+ */
+ public function getName();
+} \ No newline at end of file
diff --git a/vendor/phpdocumentor/reflection-common/src/File.php b/vendor/phpdocumentor/reflection-common/src/File.php
new file mode 100644
index 0000000..0187594
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-common/src/File.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection;
+
+/**
+ * Interface for files processed by the ProjectFactory
+ */
+interface File
+{
+ /**
+ * Returns the content of the file as a string.
+ *
+ * @return string
+ */
+ public function getContents();
+
+ /**
+ * Returns md5 hash of the file.
+ *
+ * @return string
+ */
+ public function md5();
+
+ /**
+ * Returns an relative path to the file.
+ *
+ * @return string
+ */
+ public function path();
+}
diff --git a/vendor/phpdocumentor/reflection-common/src/Fqsen.php b/vendor/phpdocumentor/reflection-common/src/Fqsen.php
new file mode 100644
index 0000000..ce88d03
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-common/src/Fqsen.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * phpDocumentor
+ *
+ * PHP Version 5.5
+ *
+ * @copyright 2010-2015 Mike van Riel / Naenius (http://www.naenius.com)
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection;
+
+/**
+ * Value Object for Fqsen.
+ *
+ * @link https://github.com/phpDocumentor/fig-standards/blob/master/proposed/phpdoc-meta.md
+ */
+final class Fqsen
+{
+ /**
+ * @var string full quallified class name
+ */
+ private $fqsen;
+
+ /**
+ * @var string name of the element without path.
+ */
+ private $name;
+
+ /**
+ * Initializes the object.
+ *
+ * @param string $fqsen
+ *
+ * @throws \InvalidArgumentException when $fqsen is not matching the format.
+ */
+ public function __construct($fqsen)
+ {
+ $matches = array();
+ $result = preg_match(
+ '/^\\\\([a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff\\\\]*)?(?:[:]{2}\\$?([a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*))?(?:\\(\\))?$/',
+ $fqsen,
+ $matches
+ );
+
+ if ($result === 0) {
+ throw new \InvalidArgumentException(
+ sprintf('"%s" is not a valid Fqsen.', $fqsen)
+ );
+ }
+
+ $this->fqsen = $fqsen;
+
+ if (isset($matches[2])) {
+ $this->name = $matches[2];
+ } else {
+ $matches = explode('\\', $fqsen);
+ $this->name = trim(end($matches), '()');
+ }
+ }
+
+ /**
+ * converts this class to string.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->fqsen;
+ }
+
+ /**
+ * Returns the name of the element without path.
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-common/src/Location.php b/vendor/phpdocumentor/reflection-common/src/Location.php
new file mode 100644
index 0000000..5760321
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-common/src/Location.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection;
+
+/**
+ * The location where an element occurs within a file.
+ */
+final class Location
+{
+ /** @var int */
+ private $lineNumber = 0;
+
+ /** @var int */
+ private $columnNumber = 0;
+
+ /**
+ * Initializes the location for an element using its line number in the file and optionally the column number.
+ *
+ * @param int $lineNumber
+ * @param int $columnNumber
+ */
+ public function __construct($lineNumber, $columnNumber = 0)
+ {
+ $this->lineNumber = $lineNumber;
+ $this->columnNumber = $columnNumber;
+ }
+
+ /**
+ * Returns the line number that is covered by this location.
+ *
+ * @return integer
+ */
+ public function getLineNumber()
+ {
+ return $this->lineNumber;
+ }
+
+ /**
+ * Returns the column number (character position on a line) for this location object.
+ *
+ * @return integer
+ */
+ public function getColumnNumber()
+ {
+ return $this->columnNumber;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-common/src/Project.php b/vendor/phpdocumentor/reflection-common/src/Project.php
new file mode 100644
index 0000000..3ed1e39
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-common/src/Project.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * phpDocumentor
+ *
+ * PHP Version 5.5
+ *
+ * @copyright 2010-2015 Mike van Riel / Naenius (http://www.naenius.com)
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection;
+
+/**
+ * Interface for project. Since the definition of a project can be different per factory this interface will be small.
+ */
+interface Project
+{
+ /**
+ * Returns the name of the project.
+ *
+ * @return string
+ */
+ public function getName();
+}
diff --git a/vendor/phpdocumentor/reflection-common/src/ProjectFactory.php b/vendor/phpdocumentor/reflection-common/src/ProjectFactory.php
new file mode 100644
index 0000000..5602f84
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-common/src/ProjectFactory.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * phpDocumentor
+ *
+ * PHP Version 5.5
+ *
+ * @copyright 2010-2015 Mike van Riel / Naenius (http://www.naenius.com)
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+namespace phpDocumentor\Reflection;
+
+/**
+ * Interface for project factories. A project factory shall convert a set of files
+ * into an object implementing the Project interface.
+ */
+interface ProjectFactory
+{
+ /**
+ * Creates a project from the set of files.
+ *
+ * @param string $name
+ * @param File[] $files
+ * @return Project
+ */
+ public function create($name, array $files);
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/.coveralls.yml b/vendor/phpdocumentor/reflection-docblock/.coveralls.yml
new file mode 100644
index 0000000..c512a3d
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/.coveralls.yml
@@ -0,0 +1,3 @@
+service_name: travis-ci
+coverage_clover: coverage.xml
+json_path: coverage.json
diff --git a/vendor/phpdocumentor/reflection-docblock/LICENSE b/vendor/phpdocumentor/reflection-docblock/LICENSE
new file mode 100644
index 0000000..792e404
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2010 Mike van Riel
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/phpdocumentor/reflection-docblock/README.md b/vendor/phpdocumentor/reflection-docblock/README.md
new file mode 100644
index 0000000..5a7d326
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/README.md
@@ -0,0 +1,67 @@
+The ReflectionDocBlock Component [![Build Status](https://secure.travis-ci.org/phpDocumentor/ReflectionDocBlock.png)](https://travis-ci.org/phpDocumentor/ReflectionDocBlock)
+================================
+
+Introduction
+------------
+
+The ReflectionDocBlock component of phpDocumentor provides a DocBlock parser
+that is 100% compatible with the [PHPDoc standard](http://phpdoc.org/docs/latest).
+
+With this component, a library can provide support for annotations via DocBlocks
+or otherwise retrieve information that is embedded in a DocBlock.
+
+Installation
+------------
+
+```bash
+composer require phpdocumentor/reflection-docblock
+```
+
+Usage
+-----
+
+In order to parse the DocBlock one needs a DocBlockFactory that can be
+instantiated using its `createInstance` factory method like this:
+
+```php
+$factory = \phpDocumentor\Reflection\DocBlockFactory::createInstance();
+```
+
+Then we can use the `create` method of the factory to interpret the DocBlock.
+Please note that it is also possible to provide a class that has the
+`getDocComment()` method, such as an object of type `ReflectionClass`, the
+create method will read that if it exists.
+
+```php
+$docComment = <<<DOCCOMMENT
+/**
+ * This is an example of a summary.
+ *
+ * This is a Description. A Summary and Description are separated by either
+ * two subsequent newlines (thus a whiteline in between as can be seen in this
+ * example), or when the Summary ends with a dot (`.`) and some form of
+ * whitespace.
+ */
+DOCCOMMENT;
+
+$docblock = $factory->create($docComment);
+```
+
+The `create` method will yield an object of type `\phpDocumentor\Reflection\DocBlock`
+whose methods can be queried:
+
+```php
+// Contains the summary for this DocBlock
+$summary = $docblock->getSummary();
+
+// Contains \phpDocumentor\Reflection\DocBlock\Description object
+$description = $docblock->getDescription();
+
+// You can either cast it to string
+$description = (string) $docblock->getDescription();
+
+// Or use the render method to get a string representation of the Description.
+$description = $docblock->getDescription()->render();
+```
+
+> For more examples it would be best to review the scripts in the [`/examples` folder](/examples).
diff --git a/vendor/phpdocumentor/reflection-docblock/composer.json b/vendor/phpdocumentor/reflection-docblock/composer.json
new file mode 100644
index 0000000..e3dc38a
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/composer.json
@@ -0,0 +1,34 @@
+{
+ "name": "phpdocumentor/reflection-docblock",
+ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+ "type": "library",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "me@mikevanriel.com"
+ }
+ ],
+ "require": {
+ "php": "^7.0",
+ "phpdocumentor/reflection-common": "^1.0.0",
+ "phpdocumentor/type-resolver": "^0.4.0",
+ "webmozart/assert": "^1.0"
+ },
+ "autoload": {
+ "psr-4": {"phpDocumentor\\Reflection\\": ["src/"]}
+ },
+ "autoload-dev": {
+ "psr-4": {"phpDocumentor\\Reflection\\": ["tests/unit"]}
+ },
+ "require-dev": {
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^6.4",
+ "doctrine/instantiator": "~1.0.5"
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.x-dev"
+ }
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/easy-coding-standard.neon b/vendor/phpdocumentor/reflection-docblock/easy-coding-standard.neon
new file mode 100644
index 0000000..7c2ba6e
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/easy-coding-standard.neon
@@ -0,0 +1,31 @@
+includes:
+ - temp/ecs/config/clean-code.neon
+ - temp/ecs/config/psr2-checkers.neon
+ - temp/ecs/config/spaces.neon
+ - temp/ecs/config/common.neon
+
+checkers:
+ PhpCsFixer\Fixer\Operator\ConcatSpaceFixer:
+ spacing: one
+
+parameters:
+ exclude_checkers:
+ # from temp/ecs/config/common.neon
+ - PhpCsFixer\Fixer\ClassNotation\OrderedClassElementsFixer
+ - PhpCsFixer\Fixer\PhpUnit\PhpUnitStrictFixer
+ - PhpCsFixer\Fixer\ControlStructure\YodaStyleFixer
+ # from temp/ecs/config/spaces.neon
+ - PhpCsFixer\Fixer\Operator\NotOperatorWithSuccessorSpaceFixer
+
+ skip:
+ SlevomatCodingStandard\Sniffs\Classes\UnusedPrivateElementsSniff:
+ # WIP code
+ - src/DocBlock/StandardTagFactory.php
+ PHP_CodeSniffer\Standards\Generic\Sniffs\CodeAnalysis\EmptyStatementSniff:
+ # WIP code
+ - src/DocBlock/StandardTagFactory.php
+ PHP_CodeSniffer\Standards\Squiz\Sniffs\Classes\ValidClassNameSniff:
+ - src/DocBlock/Tags/Return_.php
+ - src/DocBlock/Tags/Var_.php
+ PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\CamelCapsFunctionNameSniff:
+ - */tests/**
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock.php
new file mode 100644
index 0000000..46605b7
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock.php
@@ -0,0 +1,236 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection;
+
+use phpDocumentor\Reflection\DocBlock\Tag;
+use Webmozart\Assert\Assert;
+
+final class DocBlock
+{
+ /** @var string The opening line for this docblock. */
+ private $summary = '';
+
+ /** @var DocBlock\Description The actual description for this docblock. */
+ private $description = null;
+
+ /** @var Tag[] An array containing all the tags in this docblock; except inline. */
+ private $tags = [];
+
+ /** @var Types\Context Information about the context of this DocBlock. */
+ private $context = null;
+
+ /** @var Location Information about the location of this DocBlock. */
+ private $location = null;
+
+ /** @var bool Is this DocBlock (the start of) a template? */
+ private $isTemplateStart = false;
+
+ /** @var bool Does this DocBlock signify the end of a DocBlock template? */
+ private $isTemplateEnd = false;
+
+ /**
+ * @param string $summary
+ * @param DocBlock\Description $description
+ * @param DocBlock\Tag[] $tags
+ * @param Types\Context $context The context in which the DocBlock occurs.
+ * @param Location $location The location within the file that this DocBlock occurs in.
+ * @param bool $isTemplateStart
+ * @param bool $isTemplateEnd
+ */
+ public function __construct(
+ $summary = '',
+ DocBlock\Description $description = null,
+ array $tags = [],
+ Types\Context $context = null,
+ Location $location = null,
+ $isTemplateStart = false,
+ $isTemplateEnd = false
+ ) {
+ Assert::string($summary);
+ Assert::boolean($isTemplateStart);
+ Assert::boolean($isTemplateEnd);
+ Assert::allIsInstanceOf($tags, Tag::class);
+
+ $this->summary = $summary;
+ $this->description = $description ?: new DocBlock\Description('');
+ foreach ($tags as $tag) {
+ $this->addTag($tag);
+ }
+
+ $this->context = $context;
+ $this->location = $location;
+
+ $this->isTemplateEnd = $isTemplateEnd;
+ $this->isTemplateStart = $isTemplateStart;
+ }
+
+ /**
+ * @return string
+ */
+ public function getSummary()
+ {
+ return $this->summary;
+ }
+
+ /**
+ * @return DocBlock\Description
+ */
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ /**
+ * Returns the current context.
+ *
+ * @return Types\Context
+ */
+ public function getContext()
+ {
+ return $this->context;
+ }
+
+ /**
+ * Returns the current location.
+ *
+ * @return Location
+ */
+ public function getLocation()
+ {
+ return $this->location;
+ }
+
+ /**
+ * Returns whether this DocBlock is the start of a Template section.
+ *
+ * A Docblock may serve as template for a series of subsequent DocBlocks. This is indicated by a special marker
+ * (`#@+`) that is appended directly after the opening `/**` of a DocBlock.
+ *
+ * An example of such an opening is:
+ *
+ * ```
+ * /**#@+
+ * * My DocBlock
+ * * /
+ * ```
+ *
+ * The description and tags (not the summary!) are copied onto all subsequent DocBlocks and also applied to all
+ * elements that follow until another DocBlock is found that contains the closing marker (`#@-`).
+ *
+ * @see self::isTemplateEnd() for the check whether a closing marker was provided.
+ *
+ * @return boolean
+ */
+ public function isTemplateStart()
+ {
+ return $this->isTemplateStart;
+ }
+
+ /**
+ * Returns whether this DocBlock is the end of a Template section.
+ *
+ * @see self::isTemplateStart() for a more complete description of the Docblock Template functionality.
+ *
+ * @return boolean
+ */
+ public function isTemplateEnd()
+ {
+ return $this->isTemplateEnd;
+ }
+
+ /**
+ * Returns the tags for this DocBlock.
+ *
+ * @return Tag[]
+ */
+ public function getTags()
+ {
+ return $this->tags;
+ }
+
+ /**
+ * Returns an array of tags matching the given name. If no tags are found
+ * an empty array is returned.
+ *
+ * @param string $name String to search by.
+ *
+ * @return Tag[]
+ */
+ public function getTagsByName($name)
+ {
+ Assert::string($name);
+
+ $result = [];
+
+ /** @var Tag $tag */
+ foreach ($this->getTags() as $tag) {
+ if ($tag->getName() !== $name) {
+ continue;
+ }
+
+ $result[] = $tag;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Checks if a tag of a certain type is present in this DocBlock.
+ *
+ * @param string $name Tag name to check for.
+ *
+ * @return bool
+ */
+ public function hasTag($name)
+ {
+ Assert::string($name);
+
+ /** @var Tag $tag */
+ foreach ($this->getTags() as $tag) {
+ if ($tag->getName() === $name) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Remove a tag from this DocBlock.
+ *
+ * @param Tag $tag The tag to remove.
+ *
+ * @return void
+ */
+ public function removeTag(Tag $tagToRemove)
+ {
+ foreach ($this->tags as $key => $tag) {
+ if ($tag === $tagToRemove) {
+ unset($this->tags[$key]);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Adds a tag to this DocBlock.
+ *
+ * @param Tag $tag The tag to add.
+ *
+ * @return void
+ */
+ private function addTag(Tag $tag)
+ {
+ $this->tags[] = $tag;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php
new file mode 100644
index 0000000..25a79e0
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php
@@ -0,0 +1,114 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock;
+
+use phpDocumentor\Reflection\DocBlock\Tags\Formatter;
+use phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter;
+use Webmozart\Assert\Assert;
+
+/**
+ * Object representing to description for a DocBlock.
+ *
+ * A Description object can consist of plain text but can also include tags. A Description Formatter can then combine
+ * a body template with sprintf-style placeholders together with formatted tags in order to reconstitute a complete
+ * description text using the format that you would prefer.
+ *
+ * Because parsing a Description text can be a verbose process this is handled by the {@see DescriptionFactory}. It is
+ * thus recommended to use that to create a Description object, like this:
+ *
+ * $description = $descriptionFactory->create('This is a {@see Description}', $context);
+ *
+ * The description factory will interpret the given body and create a body template and list of tags from them, and pass
+ * that onto the constructor if this class.
+ *
+ * > The $context variable is a class of type {@see \phpDocumentor\Reflection\Types\Context} and contains the namespace
+ * > and the namespace aliases that apply to this DocBlock. These are used by the Factory to resolve and expand partial
+ * > type names and FQSENs.
+ *
+ * If you do not want to use the DescriptionFactory you can pass a body template and tag listing like this:
+ *
+ * $description = new Description(
+ * 'This is a %1$s',
+ * [ new See(new Fqsen('\phpDocumentor\Reflection\DocBlock\Description')) ]
+ * );
+ *
+ * It is generally recommended to use the Factory as that will also apply escaping rules, while the Description object
+ * is mainly responsible for rendering.
+ *
+ * @see DescriptionFactory to create a new Description.
+ * @see Description\Formatter for the formatting of the body and tags.
+ */
+class Description
+{
+ /** @var string */
+ private $bodyTemplate;
+
+ /** @var Tag[] */
+ private $tags;
+
+ /**
+ * Initializes a Description with its body (template) and a listing of the tags used in the body template.
+ *
+ * @param string $bodyTemplate
+ * @param Tag[] $tags
+ */
+ public function __construct($bodyTemplate, array $tags = [])
+ {
+ Assert::string($bodyTemplate);
+
+ $this->bodyTemplate = $bodyTemplate;
+ $this->tags = $tags;
+ }
+
+ /**
+ * Returns the tags for this DocBlock.
+ *
+ * @return Tag[]
+ */
+ public function getTags()
+ {
+ return $this->tags;
+ }
+
+ /**
+ * Renders this description as a string where the provided formatter will format the tags in the expected string
+ * format.
+ *
+ * @param Formatter|null $formatter
+ *
+ * @return string
+ */
+ public function render(Formatter $formatter = null)
+ {
+ if ($formatter === null) {
+ $formatter = new PassthroughFormatter();
+ }
+
+ $tags = [];
+ foreach ($this->tags as $tag) {
+ $tags[] = '{' . $formatter->format($tag) . '}';
+ }
+
+ return vsprintf($this->bodyTemplate, $tags);
+ }
+
+ /**
+ * Returns a plain string representation of this description.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->render();
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php
new file mode 100644
index 0000000..48f9c21
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php
@@ -0,0 +1,191 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock;
+
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+
+/**
+ * Creates a new Description object given a body of text.
+ *
+ * Descriptions in phpDocumentor are somewhat complex entities as they can contain one or more tags inside their
+ * body that can be replaced with a readable output. The replacing is done by passing a Formatter object to the
+ * Description object's `render` method.
+ *
+ * In addition to the above does a Description support two types of escape sequences:
+ *
+ * 1. `{@}` to escape the `@` character to prevent it from being interpreted as part of a tag, i.e. `{{@}link}`
+ * 2. `{}` to escape the `}` character, this can be used if you want to use the `}` character in the description
+ * of an inline tag.
+ *
+ * If a body consists of multiple lines then this factory will also remove any superfluous whitespace at the beginning
+ * of each line while maintaining any indentation that is used. This will prevent formatting parsers from tripping
+ * over unexpected spaces as can be observed with tag descriptions.
+ */
+class DescriptionFactory
+{
+ /** @var TagFactory */
+ private $tagFactory;
+
+ /**
+ * Initializes this factory with the means to construct (inline) tags.
+ *
+ * @param TagFactory $tagFactory
+ */
+ public function __construct(TagFactory $tagFactory)
+ {
+ $this->tagFactory = $tagFactory;
+ }
+
+ /**
+ * Returns the parsed text of this description.
+ *
+ * @param string $contents
+ * @param TypeContext $context
+ *
+ * @return Description
+ */
+ public function create($contents, TypeContext $context = null)
+ {
+ list($text, $tags) = $this->parse($this->lex($contents), $context);
+
+ return new Description($text, $tags);
+ }
+
+ /**
+ * Strips the contents from superfluous whitespace and splits the description into a series of tokens.
+ *
+ * @param string $contents
+ *
+ * @return string[] A series of tokens of which the description text is composed.
+ */
+ private function lex($contents)
+ {
+ $contents = $this->removeSuperfluousStartingWhitespace($contents);
+
+ // performance optimalization; if there is no inline tag, don't bother splitting it up.
+ if (strpos($contents, '{@') === false) {
+ return [$contents];
+ }
+
+ return preg_split(
+ '/\{
+ # "{@}" is not a valid inline tag. This ensures that we do not treat it as one, but treat it literally.
+ (?!@\})
+ # We want to capture the whole tag line, but without the inline tag delimiters.
+ (\@
+ # Match everything up to the next delimiter.
+ [^{}]*
+ # Nested inline tag content should not be captured, or it will appear in the result separately.
+ (?:
+ # Match nested inline tags.
+ (?:
+ # Because we did not catch the tag delimiters earlier, we must be explicit with them here.
+ # Notice that this also matches "{}", as a way to later introduce it as an escape sequence.
+ \{(?1)?\}
+ |
+ # Make sure we match hanging "{".
+ \{
+ )
+ # Match content after the nested inline tag.
+ [^{}]*
+ )* # If there are more inline tags, match them as well. We use "*" since there may not be any
+ # nested inline tags.
+ )
+ \}/Sux',
+ $contents,
+ null,
+ PREG_SPLIT_DELIM_CAPTURE
+ );
+ }
+
+ /**
+ * Parses the stream of tokens in to a new set of tokens containing Tags.
+ *
+ * @param string[] $tokens
+ * @param TypeContext $context
+ *
+ * @return string[]|Tag[]
+ */
+ private function parse($tokens, TypeContext $context)
+ {
+ $count = count($tokens);
+ $tagCount = 0;
+ $tags = [];
+
+ for ($i = 1; $i < $count; $i += 2) {
+ $tags[] = $this->tagFactory->create($tokens[$i], $context);
+ $tokens[$i] = '%' . ++$tagCount . '$s';
+ }
+
+ //In order to allow "literal" inline tags, the otherwise invalid
+ //sequence "{@}" is changed to "@", and "{}" is changed to "}".
+ //"%" is escaped to "%%" because of vsprintf.
+ //See unit tests for examples.
+ for ($i = 0; $i < $count; $i += 2) {
+ $tokens[$i] = str_replace(['{@}', '{}', '%'], ['@', '}', '%%'], $tokens[$i]);
+ }
+
+ return [implode('', $tokens), $tags];
+ }
+
+ /**
+ * Removes the superfluous from a multi-line description.
+ *
+ * When a description has more than one line then it can happen that the second and subsequent lines have an
+ * additional indentation. This is commonly in use with tags like this:
+ *
+ * {@}since 1.1.0 This is an example
+ * description where we have an
+ * indentation in the second and
+ * subsequent lines.
+ *
+ * If we do not normalize the indentation then we have superfluous whitespace on the second and subsequent
+ * lines and this may cause rendering issues when, for example, using a Markdown converter.
+ *
+ * @param string $contents
+ *
+ * @return string
+ */
+ private function removeSuperfluousStartingWhitespace($contents)
+ {
+ $lines = explode("\n", $contents);
+
+ // if there is only one line then we don't have lines with superfluous whitespace and
+ // can use the contents as-is
+ if (count($lines) <= 1) {
+ return $contents;
+ }
+
+ // determine how many whitespace characters need to be stripped
+ $startingSpaceCount = 9999999;
+ for ($i = 1; $i < count($lines); $i++) {
+ // lines with a no length do not count as they are not indented at all
+ if (strlen(trim($lines[$i])) === 0) {
+ continue;
+ }
+
+ // determine the number of prefixing spaces by checking the difference in line length before and after
+ // an ltrim
+ $startingSpaceCount = min($startingSpaceCount, strlen($lines[$i]) - strlen(ltrim($lines[$i])));
+ }
+
+ // strip the number of spaces from each line
+ if ($startingSpaceCount > 0) {
+ for ($i = 1; $i < count($lines); $i++) {
+ $lines[$i] = substr($lines[$i], $startingSpaceCount);
+ }
+ }
+
+ return implode("\n", $lines);
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php
new file mode 100644
index 0000000..571ed74
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php
@@ -0,0 +1,170 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock;
+
+use phpDocumentor\Reflection\DocBlock\Tags\Example;
+
+/**
+ * Class used to find an example file's location based on a given ExampleDescriptor.
+ */
+class ExampleFinder
+{
+ /** @var string */
+ private $sourceDirectory = '';
+
+ /** @var string[] */
+ private $exampleDirectories = [];
+
+ /**
+ * Attempts to find the example contents for the given descriptor.
+ *
+ * @param Example $example
+ *
+ * @return string
+ */
+ public function find(Example $example)
+ {
+ $filename = $example->getFilePath();
+
+ $file = $this->getExampleFileContents($filename);
+ if (!$file) {
+ return "** File not found : {$filename} **";
+ }
+
+ return implode('', array_slice($file, $example->getStartingLine() - 1, $example->getLineCount()));
+ }
+
+ /**
+ * Registers the project's root directory where an 'examples' folder can be expected.
+ *
+ * @param string $directory
+ *
+ * @return void
+ */
+ public function setSourceDirectory($directory = '')
+ {
+ $this->sourceDirectory = $directory;
+ }
+
+ /**
+ * Returns the project's root directory where an 'examples' folder can be expected.
+ *
+ * @return string
+ */
+ public function getSourceDirectory()
+ {
+ return $this->sourceDirectory;
+ }
+
+ /**
+ * Registers a series of directories that may contain examples.
+ *
+ * @param string[] $directories
+ */
+ public function setExampleDirectories(array $directories)
+ {
+ $this->exampleDirectories = $directories;
+ }
+
+ /**
+ * Returns a series of directories that may contain examples.
+ *
+ * @return string[]
+ */
+ public function getExampleDirectories()
+ {
+ return $this->exampleDirectories;
+ }
+
+ /**
+ * Attempts to find the requested example file and returns its contents or null if no file was found.
+ *
+ * This method will try several methods in search of the given example file, the first one it encounters is
+ * returned:
+ *
+ * 1. Iterates through all examples folders for the given filename
+ * 2. Checks the source folder for the given filename
+ * 3. Checks the 'examples' folder in the current working directory for examples
+ * 4. Checks the path relative to the current working directory for the given filename
+ *
+ * @param string $filename
+ *
+ * @return string|null
+ */
+ private function getExampleFileContents($filename)
+ {
+ $normalizedPath = null;
+
+ foreach ($this->exampleDirectories as $directory) {
+ $exampleFileFromConfig = $this->constructExamplePath($directory, $filename);
+ if (is_readable($exampleFileFromConfig)) {
+ $normalizedPath = $exampleFileFromConfig;
+ break;
+ }
+ }
+
+ if (!$normalizedPath) {
+ if (is_readable($this->getExamplePathFromSource($filename))) {
+ $normalizedPath = $this->getExamplePathFromSource($filename);
+ } elseif (is_readable($this->getExamplePathFromExampleDirectory($filename))) {
+ $normalizedPath = $this->getExamplePathFromExampleDirectory($filename);
+ } elseif (is_readable($filename)) {
+ $normalizedPath = $filename;
+ }
+ }
+
+ return $normalizedPath && is_readable($normalizedPath) ? file($normalizedPath) : null;
+ }
+
+ /**
+ * Get example filepath based on the example directory inside your project.
+ *
+ * @param string $file
+ *
+ * @return string
+ */
+ private function getExamplePathFromExampleDirectory($file)
+ {
+ return getcwd() . DIRECTORY_SEPARATOR . 'examples' . DIRECTORY_SEPARATOR . $file;
+ }
+
+ /**
+ * Returns a path to the example file in the given directory..
+ *
+ * @param string $directory
+ * @param string $file
+ *
+ * @return string
+ */
+ private function constructExamplePath($directory, $file)
+ {
+ return rtrim($directory, '\\/') . DIRECTORY_SEPARATOR . $file;
+ }
+
+ /**
+ * Get example filepath based on sourcecode.
+ *
+ * @param string $file
+ *
+ * @return string
+ */
+ private function getExamplePathFromSource($file)
+ {
+ return sprintf(
+ '%s%s%s',
+ trim($this->getSourceDirectory(), '\\/'),
+ DIRECTORY_SEPARATOR,
+ trim($file, '"')
+ );
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php
new file mode 100644
index 0000000..0f355f5
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php
@@ -0,0 +1,155 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock;
+
+use phpDocumentor\Reflection\DocBlock;
+use Webmozart\Assert\Assert;
+
+/**
+ * Converts a DocBlock back from an object to a complete DocComment including Asterisks.
+ */
+class Serializer
+{
+ /** @var string The string to indent the comment with. */
+ protected $indentString = ' ';
+
+ /** @var int The number of times the indent string is repeated. */
+ protected $indent = 0;
+
+ /** @var bool Whether to indent the first line with the given indent amount and string. */
+ protected $isFirstLineIndented = true;
+
+ /** @var int|null The max length of a line. */
+ protected $lineLength = null;
+
+ /** @var DocBlock\Tags\Formatter A custom tag formatter. */
+ protected $tagFormatter = null;
+
+ /**
+ * Create a Serializer instance.
+ *
+ * @param int $indent The number of times the indent string is repeated.
+ * @param string $indentString The string to indent the comment with.
+ * @param bool $indentFirstLine Whether to indent the first line.
+ * @param int|null $lineLength The max length of a line or NULL to disable line wrapping.
+ * @param DocBlock\Tags\Formatter $tagFormatter A custom tag formatter, defaults to PassthroughFormatter.
+ */
+ public function __construct($indent = 0, $indentString = ' ', $indentFirstLine = true, $lineLength = null, $tagFormatter = null)
+ {
+ Assert::integer($indent);
+ Assert::string($indentString);
+ Assert::boolean($indentFirstLine);
+ Assert::nullOrInteger($lineLength);
+ Assert::nullOrIsInstanceOf($tagFormatter, 'phpDocumentor\Reflection\DocBlock\Tags\Formatter');
+
+ $this->indent = $indent;
+ $this->indentString = $indentString;
+ $this->isFirstLineIndented = $indentFirstLine;
+ $this->lineLength = $lineLength;
+ $this->tagFormatter = $tagFormatter ?: new DocBlock\Tags\Formatter\PassthroughFormatter();
+ }
+
+ /**
+ * Generate a DocBlock comment.
+ *
+ * @param DocBlock $docblock The DocBlock to serialize.
+ *
+ * @return string The serialized doc block.
+ */
+ public function getDocComment(DocBlock $docblock)
+ {
+ $indent = str_repeat($this->indentString, $this->indent);
+ $firstIndent = $this->isFirstLineIndented ? $indent : '';
+ // 3 === strlen(' * ')
+ $wrapLength = $this->lineLength ? $this->lineLength - strlen($indent) - 3 : null;
+
+ $text = $this->removeTrailingSpaces(
+ $indent,
+ $this->addAsterisksForEachLine(
+ $indent,
+ $this->getSummaryAndDescriptionTextBlock($docblock, $wrapLength)
+ )
+ );
+
+ $comment = "{$firstIndent}/**\n";
+ if ($text) {
+ $comment .= "{$indent} * {$text}\n";
+ $comment .= "{$indent} *\n";
+ }
+
+ $comment = $this->addTagBlock($docblock, $wrapLength, $indent, $comment);
+ $comment .= $indent . ' */';
+
+ return $comment;
+ }
+
+ /**
+ * @param $indent
+ * @param $text
+ * @return mixed
+ */
+ private function removeTrailingSpaces($indent, $text)
+ {
+ return str_replace("\n{$indent} * \n", "\n{$indent} *\n", $text);
+ }
+
+ /**
+ * @param $indent
+ * @param $text
+ * @return mixed
+ */
+ private function addAsterisksForEachLine($indent, $text)
+ {
+ return str_replace("\n", "\n{$indent} * ", $text);
+ }
+
+ /**
+ * @param DocBlock $docblock
+ * @param $wrapLength
+ * @return string
+ */
+ private function getSummaryAndDescriptionTextBlock(DocBlock $docblock, $wrapLength)
+ {
+ $text = $docblock->getSummary() . ((string)$docblock->getDescription() ? "\n\n" . $docblock->getDescription()
+ : '');
+ if ($wrapLength !== null) {
+ $text = wordwrap($text, $wrapLength);
+ return $text;
+ }
+
+ return $text;
+ }
+
+ /**
+ * @param DocBlock $docblock
+ * @param $wrapLength
+ * @param $indent
+ * @param $comment
+ * @return string
+ */
+ private function addTagBlock(DocBlock $docblock, $wrapLength, $indent, $comment)
+ {
+ foreach ($docblock->getTags() as $tag) {
+ $tagText = $this->tagFormatter->format($tag);
+ if ($wrapLength !== null) {
+ $tagText = wordwrap($tagText, $wrapLength);
+ }
+
+ $tagText = str_replace("\n", "\n{$indent} * ", $tagText);
+
+ $comment .= "{$indent} * {$tagText}\n";
+ }
+
+ return $comment;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php
new file mode 100644
index 0000000..5a8143c
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php
@@ -0,0 +1,319 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock;
+
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\StaticMethod;
+use phpDocumentor\Reflection\DocBlock\Tags\Generic;
+use phpDocumentor\Reflection\FqsenResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Creates a Tag object given the contents of a tag.
+ *
+ * This Factory is capable of determining the appropriate class for a tag and instantiate it using its `create`
+ * factory method. The `create` factory method of a Tag can have a variable number of arguments; this way you can
+ * pass the dependencies that you need to construct a tag object.
+ *
+ * > Important: each parameter in addition to the body variable for the `create` method must default to null, otherwise
+ * > it violates the constraint with the interface; it is recommended to use the {@see Assert::notNull()} method to
+ * > verify that a dependency is actually passed.
+ *
+ * This Factory also features a Service Locator component that is used to pass the right dependencies to the
+ * `create` method of a tag; each dependency should be registered as a service or as a parameter.
+ *
+ * When you want to use a Tag of your own with custom handling you need to call the `registerTagHandler` method, pass
+ * the name of the tag and a Fully Qualified Class Name pointing to a class that implements the Tag interface.
+ */
+final class StandardTagFactory implements TagFactory
+{
+ /** PCRE regular expression matching a tag name. */
+ const REGEX_TAGNAME = '[\w\-\_\\\\]+';
+
+ /**
+ * @var string[] An array with a tag as a key, and an FQCN to a class that handles it as an array value.
+ */
+ private $tagHandlerMappings = [
+ 'author' => '\phpDocumentor\Reflection\DocBlock\Tags\Author',
+ 'covers' => '\phpDocumentor\Reflection\DocBlock\Tags\Covers',
+ 'deprecated' => '\phpDocumentor\Reflection\DocBlock\Tags\Deprecated',
+ // 'example' => '\phpDocumentor\Reflection\DocBlock\Tags\Example',
+ 'link' => '\phpDocumentor\Reflection\DocBlock\Tags\Link',
+ 'method' => '\phpDocumentor\Reflection\DocBlock\Tags\Method',
+ 'param' => '\phpDocumentor\Reflection\DocBlock\Tags\Param',
+ 'property-read' => '\phpDocumentor\Reflection\DocBlock\Tags\PropertyRead',
+ 'property' => '\phpDocumentor\Reflection\DocBlock\Tags\Property',
+ 'property-write' => '\phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite',
+ 'return' => '\phpDocumentor\Reflection\DocBlock\Tags\Return_',
+ 'see' => '\phpDocumentor\Reflection\DocBlock\Tags\See',
+ 'since' => '\phpDocumentor\Reflection\DocBlock\Tags\Since',
+ 'source' => '\phpDocumentor\Reflection\DocBlock\Tags\Source',
+ 'throw' => '\phpDocumentor\Reflection\DocBlock\Tags\Throws',
+ 'throws' => '\phpDocumentor\Reflection\DocBlock\Tags\Throws',
+ 'uses' => '\phpDocumentor\Reflection\DocBlock\Tags\Uses',
+ 'var' => '\phpDocumentor\Reflection\DocBlock\Tags\Var_',
+ 'version' => '\phpDocumentor\Reflection\DocBlock\Tags\Version'
+ ];
+
+ /**
+ * @var \ReflectionParameter[][] a lazy-loading cache containing parameters for each tagHandler that has been used.
+ */
+ private $tagHandlerParameterCache = [];
+
+ /**
+ * @var FqsenResolver
+ */
+ private $fqsenResolver;
+
+ /**
+ * @var mixed[] an array representing a simple Service Locator where we can store parameters and
+ * services that can be inserted into the Factory Methods of Tag Handlers.
+ */
+ private $serviceLocator = [];
+
+ /**
+ * Initialize this tag factory with the means to resolve an FQSEN and optionally a list of tag handlers.
+ *
+ * If no tag handlers are provided than the default list in the {@see self::$tagHandlerMappings} property
+ * is used.
+ *
+ * @param FqsenResolver $fqsenResolver
+ * @param string[] $tagHandlers
+ *
+ * @see self::registerTagHandler() to add a new tag handler to the existing default list.
+ */
+ public function __construct(FqsenResolver $fqsenResolver, array $tagHandlers = null)
+ {
+ $this->fqsenResolver = $fqsenResolver;
+ if ($tagHandlers !== null) {
+ $this->tagHandlerMappings = $tagHandlers;
+ }
+
+ $this->addService($fqsenResolver, FqsenResolver::class);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function create($tagLine, TypeContext $context = null)
+ {
+ if (! $context) {
+ $context = new TypeContext('');
+ }
+
+ list($tagName, $tagBody) = $this->extractTagParts($tagLine);
+
+ if ($tagBody !== '' && $tagBody[0] === '[') {
+ throw new \InvalidArgumentException(
+ 'The tag "' . $tagLine . '" does not seem to be wellformed, please check it for errors'
+ );
+ }
+
+ return $this->createTag($tagBody, $tagName, $context);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function addParameter($name, $value)
+ {
+ $this->serviceLocator[$name] = $value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function addService($service, $alias = null)
+ {
+ $this->serviceLocator[$alias ?: get_class($service)] = $service;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function registerTagHandler($tagName, $handler)
+ {
+ Assert::stringNotEmpty($tagName);
+ Assert::stringNotEmpty($handler);
+ Assert::classExists($handler);
+ Assert::implementsInterface($handler, StaticMethod::class);
+
+ if (strpos($tagName, '\\') && $tagName[0] !== '\\') {
+ throw new \InvalidArgumentException(
+ 'A namespaced tag must have a leading backslash as it must be fully qualified'
+ );
+ }
+
+ $this->tagHandlerMappings[$tagName] = $handler;
+ }
+
+ /**
+ * Extracts all components for a tag.
+ *
+ * @param string $tagLine
+ *
+ * @return string[]
+ */
+ private function extractTagParts($tagLine)
+ {
+ $matches = [];
+ if (! preg_match('/^@(' . self::REGEX_TAGNAME . ')(?:\s*([^\s].*)|$)/us', $tagLine, $matches)) {
+ throw new \InvalidArgumentException(
+ 'The tag "' . $tagLine . '" does not seem to be wellformed, please check it for errors'
+ );
+ }
+
+ if (count($matches) < 3) {
+ $matches[] = '';
+ }
+
+ return array_slice($matches, 1);
+ }
+
+ /**
+ * Creates a new tag object with the given name and body or returns null if the tag name was recognized but the
+ * body was invalid.
+ *
+ * @param string $body
+ * @param string $name
+ * @param TypeContext $context
+ *
+ * @return Tag|null
+ */
+ private function createTag($body, $name, TypeContext $context)
+ {
+ $handlerClassName = $this->findHandlerClassName($name, $context);
+ $arguments = $this->getArgumentsForParametersFromWiring(
+ $this->fetchParametersForHandlerFactoryMethod($handlerClassName),
+ $this->getServiceLocatorWithDynamicParameters($context, $name, $body)
+ );
+
+ return call_user_func_array([$handlerClassName, 'create'], $arguments);
+ }
+
+ /**
+ * Determines the Fully Qualified Class Name of the Factory or Tag (containing a Factory Method `create`).
+ *
+ * @param string $tagName
+ * @param TypeContext $context
+ *
+ * @return string
+ */
+ private function findHandlerClassName($tagName, TypeContext $context)
+ {
+ $handlerClassName = Generic::class;
+ if (isset($this->tagHandlerMappings[$tagName])) {
+ $handlerClassName = $this->tagHandlerMappings[$tagName];
+ } elseif ($this->isAnnotation($tagName)) {
+ // TODO: Annotation support is planned for a later stage and as such is disabled for now
+ // $tagName = (string)$this->fqsenResolver->resolve($tagName, $context);
+ // if (isset($this->annotationMappings[$tagName])) {
+ // $handlerClassName = $this->annotationMappings[$tagName];
+ // }
+ }
+
+ return $handlerClassName;
+ }
+
+ /**
+ * Retrieves the arguments that need to be passed to the Factory Method with the given Parameters.
+ *
+ * @param \ReflectionParameter[] $parameters
+ * @param mixed[] $locator
+ *
+ * @return mixed[] A series of values that can be passed to the Factory Method of the tag whose parameters
+ * is provided with this method.
+ */
+ private function getArgumentsForParametersFromWiring($parameters, $locator)
+ {
+ $arguments = [];
+ foreach ($parameters as $index => $parameter) {
+ $typeHint = $parameter->getClass() ? $parameter->getClass()->getName() : null;
+ if (isset($locator[$typeHint])) {
+ $arguments[] = $locator[$typeHint];
+ continue;
+ }
+
+ $parameterName = $parameter->getName();
+ if (isset($locator[$parameterName])) {
+ $arguments[] = $locator[$parameterName];
+ continue;
+ }
+
+ $arguments[] = null;
+ }
+
+ return $arguments;
+ }
+
+ /**
+ * Retrieves a series of ReflectionParameter objects for the static 'create' method of the given
+ * tag handler class name.
+ *
+ * @param string $handlerClassName
+ *
+ * @return \ReflectionParameter[]
+ */
+ private function fetchParametersForHandlerFactoryMethod($handlerClassName)
+ {
+ if (! isset($this->tagHandlerParameterCache[$handlerClassName])) {
+ $methodReflection = new \ReflectionMethod($handlerClassName, 'create');
+ $this->tagHandlerParameterCache[$handlerClassName] = $methodReflection->getParameters();
+ }
+
+ return $this->tagHandlerParameterCache[$handlerClassName];
+ }
+
+ /**
+ * Returns a copy of this class' Service Locator with added dynamic parameters, such as the tag's name, body and
+ * Context.
+ *
+ * @param TypeContext $context The Context (namespace and aliasses) that may be passed and is used to resolve FQSENs.
+ * @param string $tagName The name of the tag that may be passed onto the factory method of the Tag class.
+ * @param string $tagBody The body of the tag that may be passed onto the factory method of the Tag class.
+ *
+ * @return mixed[]
+ */
+ private function getServiceLocatorWithDynamicParameters(TypeContext $context, $tagName, $tagBody)
+ {
+ $locator = array_merge(
+ $this->serviceLocator,
+ [
+ 'name' => $tagName,
+ 'body' => $tagBody,
+ TypeContext::class => $context
+ ]
+ );
+
+ return $locator;
+ }
+
+ /**
+ * Returns whether the given tag belongs to an annotation.
+ *
+ * @param string $tagContent
+ *
+ * @todo this method should be populated once we implement Annotation notation support.
+ *
+ * @return bool
+ */
+ private function isAnnotation($tagContent)
+ {
+ // 1. Contains a namespace separator
+ // 2. Contains parenthesis
+ // 3. Is present in a list of known annotations (make the algorithm smart by first checking is the last part
+ // of the annotation class name matches the found tag name
+
+ return false;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php
new file mode 100644
index 0000000..e765367
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock;
+
+use phpDocumentor\Reflection\DocBlock\Tags\Formatter;
+
+interface Tag
+{
+ public function getName();
+
+ public static function create($body);
+
+ public function render(Formatter $formatter = null);
+
+ public function __toString();
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php
new file mode 100644
index 0000000..3c1d113
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock;
+
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+
+interface TagFactory
+{
+ /**
+ * Adds a parameter to the service locator that can be injected in a tag's factory method.
+ *
+ * When calling a tag's "create" method we always check the signature for dependencies to inject. One way is to
+ * typehint a parameter in the signature so that we can use that interface or class name to inject a dependency
+ * (see {@see addService()} for more information on that).
+ *
+ * Another way is to check the name of the argument against the names in the Service Locator. With this method
+ * you can add a variable that will be inserted when a tag's create method is not typehinted and has a matching
+ * name.
+ *
+ * Be aware that there are two reserved names:
+ *
+ * - name, representing the name of the tag.
+ * - body, representing the complete body of the tag.
+ *
+ * These parameters are injected at the last moment and will override any existing parameter with those names.
+ *
+ * @param string $name
+ * @param mixed $value
+ *
+ * @return void
+ */
+ public function addParameter($name, $value);
+
+ /**
+ * Registers a service with the Service Locator using the FQCN of the class or the alias, if provided.
+ *
+ * When calling a tag's "create" method we always check the signature for dependencies to inject. If a parameter
+ * has a typehint then the ServiceLocator is queried to see if a Service is registered for that typehint.
+ *
+ * Because interfaces are regularly used as type-hints this method provides an alias parameter; if the FQCN of the
+ * interface is passed as alias then every time that interface is requested the provided service will be returned.
+ *
+ * @param object $service
+ * @param string $alias
+ *
+ * @return void
+ */
+ public function addService($service);
+
+ /**
+ * Factory method responsible for instantiating the correct sub type.
+ *
+ * @param string $tagLine The text for this tag, including description.
+ * @param TypeContext $context
+ *
+ * @throws \InvalidArgumentException if an invalid tag line was presented.
+ *
+ * @return Tag A new tag object.
+ */
+ public function create($tagLine, TypeContext $context = null);
+
+ /**
+ * Registers a handler for tags.
+ *
+ * If you want to use your own tags then you can use this method to instruct the TagFactory to register the name
+ * of a tag with the FQCN of a 'Tag Handler'. The Tag handler should implement the {@see Tag} interface (and thus
+ * the create method).
+ *
+ * @param string $tagName Name of tag to register a handler for. When registering a namespaced tag, the full
+ * name, along with a prefixing slash MUST be provided.
+ * @param string $handler FQCN of handler.
+ *
+ * @throws \InvalidArgumentException if the tag name is not a string
+ * @throws \InvalidArgumentException if the tag name is namespaced (contains backslashes) but does not start with
+ * a backslash
+ * @throws \InvalidArgumentException if the handler is not a string
+ * @throws \InvalidArgumentException if the handler is not an existing class
+ * @throws \InvalidArgumentException if the handler does not implement the {@see Tag} interface
+ *
+ * @return void
+ */
+ public function registerTagHandler($tagName, $handler);
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php
new file mode 100644
index 0000000..29d7f1d
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for an {@}author tag in a Docblock.
+ */
+final class Author extends BaseTag implements Factory\StaticMethod
+{
+ /** @var string register that this is the author tag. */
+ protected $name = 'author';
+
+ /** @var string The name of the author */
+ private $authorName = '';
+
+ /** @var string The email of the author */
+ private $authorEmail = '';
+
+ /**
+ * Initializes this tag with the author name and e-mail.
+ *
+ * @param string $authorName
+ * @param string $authorEmail
+ */
+ public function __construct($authorName, $authorEmail)
+ {
+ Assert::string($authorName);
+ Assert::string($authorEmail);
+ if ($authorEmail && !filter_var($authorEmail, FILTER_VALIDATE_EMAIL)) {
+ throw new \InvalidArgumentException('The author tag does not have a valid e-mail address');
+ }
+
+ $this->authorName = $authorName;
+ $this->authorEmail = $authorEmail;
+ }
+
+ /**
+ * Gets the author's name.
+ *
+ * @return string The author's name.
+ */
+ public function getAuthorName()
+ {
+ return $this->authorName;
+ }
+
+ /**
+ * Returns the author's email.
+ *
+ * @return string The author's email.
+ */
+ public function getEmail()
+ {
+ return $this->authorEmail;
+ }
+
+ /**
+ * Returns this tag in string form.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->authorName . (strlen($this->authorEmail) ? ' <' . $this->authorEmail . '>' : '');
+ }
+
+ /**
+ * Attempts to create a new Author object based on †he tag body.
+ *
+ * @param string $body
+ *
+ * @return static
+ */
+ public static function create($body)
+ {
+ Assert::string($body);
+
+ $splitTagContent = preg_match('/^([^\<]*)(?:\<([^\>]*)\>)?$/u', $body, $matches);
+ if (!$splitTagContent) {
+ return null;
+ }
+
+ $authorName = trim($matches[1]);
+ $email = isset($matches[2]) ? trim($matches[2]) : '';
+
+ return new static($authorName, $email);
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php
new file mode 100644
index 0000000..14bb717
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock;
+use phpDocumentor\Reflection\DocBlock\Description;
+
+/**
+ * Parses a tag definition for a DocBlock.
+ */
+abstract class BaseTag implements DocBlock\Tag
+{
+ /** @var string Name of the tag */
+ protected $name = '';
+
+ /** @var Description|null Description of the tag. */
+ protected $description;
+
+ /**
+ * Gets the name of this tag.
+ *
+ * @return string The name of this tag.
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ public function render(Formatter $formatter = null)
+ {
+ if ($formatter === null) {
+ $formatter = new Formatter\PassthroughFormatter();
+ }
+
+ return $formatter->format($this);
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php
new file mode 100644
index 0000000..8d65403
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Fqsen;
+use phpDocumentor\Reflection\FqsenResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a @covers tag in a Docblock.
+ */
+final class Covers extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'covers';
+
+ /** @var Fqsen */
+ private $refers = null;
+
+ /**
+ * Initializes this tag.
+ *
+ * @param Fqsen $refers
+ * @param Description $description
+ */
+ public function __construct(Fqsen $refers, Description $description = null)
+ {
+ $this->refers = $refers;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ DescriptionFactory $descriptionFactory = null,
+ FqsenResolver $resolver = null,
+ TypeContext $context = null
+ ) {
+ Assert::string($body);
+ Assert::notEmpty($body);
+
+ $parts = preg_split('/\s+/Su', $body, 2);
+
+ return new static(
+ $resolver->resolve($parts[0], $context),
+ $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context)
+ );
+ }
+
+ /**
+ * Returns the structural element this tag refers to.
+ *
+ * @return Fqsen
+ */
+ public function getReference()
+ {
+ return $this->refers;
+ }
+
+ /**
+ * Returns a string representation of this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->refers . ($this->description ? ' ' . $this->description->render() : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php
new file mode 100644
index 0000000..822c305
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}deprecated tag in a Docblock.
+ */
+final class Deprecated extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'deprecated';
+
+ /**
+ * PCRE regular expression matching a version vector.
+ * Assumes the "x" modifier.
+ */
+ const REGEX_VECTOR = '(?:
+ # Normal release vectors.
+ \d\S*
+ |
+ # VCS version vectors. Per PHPCS, they are expected to
+ # follow the form of the VCS name, followed by ":", followed
+ # by the version vector itself.
+ # By convention, popular VCSes like CVS, SVN and GIT use "$"
+ # around the actual version vector.
+ [^\s\:]+\:\s*\$[^\$]+\$
+ )';
+
+ /** @var string The version vector. */
+ private $version = '';
+
+ public function __construct($version = null, Description $description = null)
+ {
+ Assert::nullOrStringNotEmpty($version);
+
+ $this->version = $version;
+ $this->description = $description;
+ }
+
+ /**
+ * @return static
+ */
+ public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null)
+ {
+ Assert::nullOrString($body);
+ if (empty($body)) {
+ return new static();
+ }
+
+ $matches = [];
+ if (!preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) {
+ return new static(
+ null,
+ null !== $descriptionFactory ? $descriptionFactory->create($body, $context) : null
+ );
+ }
+
+ return new static(
+ $matches[1],
+ $descriptionFactory->create(isset($matches[2]) ? $matches[2] : '', $context)
+ );
+ }
+
+ /**
+ * Gets the version section of the tag.
+ *
+ * @return string
+ */
+ public function getVersion()
+ {
+ return $this->version;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->version . ($this->description ? ' ' . $this->description->render() : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php
new file mode 100644
index 0000000..ecb199b
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php
@@ -0,0 +1,176 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}example tag in a Docblock.
+ */
+final class Example extends BaseTag
+{
+ /**
+ * @var string Path to a file to use as an example. May also be an absolute URI.
+ */
+ private $filePath;
+
+ /**
+ * @var bool Whether the file path component represents an URI. This determines how the file portion
+ * appears at {@link getContent()}.
+ */
+ private $isURI = false;
+
+ /**
+ * @var int
+ */
+ private $startingLine;
+
+ /**
+ * @var int
+ */
+ private $lineCount;
+
+ public function __construct($filePath, $isURI, $startingLine, $lineCount, $description)
+ {
+ Assert::notEmpty($filePath);
+ Assert::integer($startingLine);
+ Assert::greaterThanEq($startingLine, 0);
+
+ $this->filePath = $filePath;
+ $this->startingLine = $startingLine;
+ $this->lineCount = $lineCount;
+ $this->name = 'example';
+ if ($description !== null) {
+ $this->description = trim($description);
+ }
+
+ $this->isURI = $isURI;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContent()
+ {
+ if (null === $this->description) {
+ $filePath = '"' . $this->filePath . '"';
+ if ($this->isURI) {
+ $filePath = $this->isUriRelative($this->filePath)
+ ? str_replace('%2F', '/', rawurlencode($this->filePath))
+ :$this->filePath;
+ }
+
+ return trim($filePath . ' ' . parent::getDescription());
+ }
+
+ return $this->description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create($body)
+ {
+ // File component: File path in quotes or File URI / Source information
+ if (! preg_match('/^(?:\"([^\"]+)\"|(\S+))(?:\s+(.*))?$/sux', $body, $matches)) {
+ return null;
+ }
+
+ $filePath = null;
+ $fileUri = null;
+ if ('' !== $matches[1]) {
+ $filePath = $matches[1];
+ } else {
+ $fileUri = $matches[2];
+ }
+
+ $startingLine = 1;
+ $lineCount = null;
+ $description = null;
+
+ if (array_key_exists(3, $matches)) {
+ $description = $matches[3];
+
+ // Starting line / Number of lines / Description
+ if (preg_match('/^([1-9]\d*)(?:\s+((?1))\s*)?(.*)$/sux', $matches[3], $contentMatches)) {
+ $startingLine = (int)$contentMatches[1];
+ if (isset($contentMatches[2]) && $contentMatches[2] !== '') {
+ $lineCount = (int)$contentMatches[2];
+ }
+
+ if (array_key_exists(3, $contentMatches)) {
+ $description = $contentMatches[3];
+ }
+ }
+ }
+
+ return new static(
+ $filePath !== null?$filePath:$fileUri,
+ $fileUri !== null,
+ $startingLine,
+ $lineCount,
+ $description
+ );
+ }
+
+ /**
+ * Returns the file path.
+ *
+ * @return string Path to a file to use as an example.
+ * May also be an absolute URI.
+ */
+ public function getFilePath()
+ {
+ return $this->filePath;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->filePath . ($this->description ? ' ' . $this->description : '');
+ }
+
+ /**
+ * Returns true if the provided URI is relative or contains a complete scheme (and thus is absolute).
+ *
+ * @param string $uri
+ *
+ * @return bool
+ */
+ private function isUriRelative($uri)
+ {
+ return false === strpos($uri, ':');
+ }
+
+ /**
+ * @return int
+ */
+ public function getStartingLine()
+ {
+ return $this->startingLine;
+ }
+
+ /**
+ * @return int
+ */
+ public function getLineCount()
+ {
+ return $this->lineCount;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php
new file mode 100644
index 0000000..98aea45
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+interface StaticMethod
+{
+ public static function create($body);
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Strategy.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Strategy.php
new file mode 100644
index 0000000..b9ca0b8
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/Strategy.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+interface Strategy
+{
+ public function create($body);
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php
new file mode 100644
index 0000000..64b2c60
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Tag;
+
+interface Formatter
+{
+ /**
+ * Formats a tag into a string representation according to a specific format, such as Markdown.
+ *
+ * @param Tag $tag
+ *
+ * @return string
+ */
+ public function format(Tag $tag);
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php
new file mode 100644
index 0000000..ceb40cc
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @copyright 2017 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Formatter;
+
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\Formatter;
+
+class AlignFormatter implements Formatter
+{
+ /** @var int The maximum tag name length. */
+ protected $maxLen = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param Tag[] $tags All tags that should later be aligned with the formatter.
+ */
+ public function __construct(array $tags)
+ {
+ foreach ($tags as $tag) {
+ $this->maxLen = max($this->maxLen, strlen($tag->getName()));
+ }
+ }
+
+ /**
+ * Formats the given tag to return a simple plain text version.
+ *
+ * @param Tag $tag
+ *
+ * @return string
+ */
+ public function format(Tag $tag)
+ {
+ return '@' . $tag->getName() . str_repeat(' ', $this->maxLen - strlen($tag->getName()) + 1) . (string)$tag;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php
new file mode 100644
index 0000000..4e2c576
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Formatter;
+
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\Formatter;
+
+class PassthroughFormatter implements Formatter
+{
+ /**
+ * Formats the given tag to return a simple plain text version.
+ *
+ * @param Tag $tag
+ *
+ * @return string
+ */
+ public function format(Tag $tag)
+ {
+ return trim('@' . $tag->getName() . ' ' . (string)$tag);
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php
new file mode 100644
index 0000000..e4c53e0
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\StandardTagFactory;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Parses a tag definition for a DocBlock.
+ */
+class Generic extends BaseTag implements Factory\StaticMethod
+{
+ /**
+ * Parses a tag and populates the member variables.
+ *
+ * @param string $name Name of the tag.
+ * @param Description $description The contents of the given tag.
+ */
+ public function __construct($name, Description $description = null)
+ {
+ $this->validateTagName($name);
+
+ $this->name = $name;
+ $this->description = $description;
+ }
+
+ /**
+ * Creates a new tag that represents any unknown tag type.
+ *
+ * @param string $body
+ * @param string $name
+ * @param DescriptionFactory $descriptionFactory
+ * @param TypeContext $context
+ *
+ * @return static
+ */
+ public static function create(
+ $body,
+ $name = '',
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::string($body);
+ Assert::stringNotEmpty($name);
+ Assert::notNull($descriptionFactory);
+
+ $description = $descriptionFactory && $body ? $descriptionFactory->create($body, $context) : null;
+
+ return new static($name, $description);
+ }
+
+ /**
+ * Returns the tag as a serialized string
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return ($this->description ? $this->description->render() : '');
+ }
+
+ /**
+ * Validates if the tag name matches the expected format, otherwise throws an exception.
+ *
+ * @param string $name
+ *
+ * @return void
+ */
+ private function validateTagName($name)
+ {
+ if (! preg_match('/^' . StandardTagFactory::REGEX_TAGNAME . '$/u', $name)) {
+ throw new \InvalidArgumentException(
+ 'The tag name "' . $name . '" is not wellformed. Tags may only consist of letters, underscores, '
+ . 'hyphens and backslashes.'
+ );
+ }
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php
new file mode 100644
index 0000000..9c0e367
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * phpDocumentor
+ *
+ * PHP Version 5.3
+ *
+ * @author Ben Selby <benmatselby@gmail.com>
+ * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a @link tag in a Docblock.
+ */
+final class Link extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'link';
+
+ /** @var string */
+ private $link = '';
+
+ /**
+ * Initializes a link to a URL.
+ *
+ * @param string $link
+ * @param Description $description
+ */
+ public function __construct($link, Description $description = null)
+ {
+ Assert::string($link);
+
+ $this->link = $link;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null)
+ {
+ Assert::string($body);
+ Assert::notNull($descriptionFactory);
+
+ $parts = preg_split('/\s+/Su', $body, 2);
+ $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null;
+
+ return new static($parts[0], $description);
+ }
+
+ /**
+ * Gets the link
+ *
+ * @return string
+ */
+ public function getLink()
+ {
+ return $this->link;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->link . ($this->description ? ' ' . $this->description->render() : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php
new file mode 100644
index 0000000..7522529
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php
@@ -0,0 +1,242 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use phpDocumentor\Reflection\Types\Void_;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for an {@}method in a Docblock.
+ */
+final class Method extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'method';
+
+ /** @var string */
+ private $methodName = '';
+
+ /** @var string[] */
+ private $arguments = [];
+
+ /** @var bool */
+ private $isStatic = false;
+
+ /** @var Type */
+ private $returnType;
+
+ public function __construct(
+ $methodName,
+ array $arguments = [],
+ Type $returnType = null,
+ $static = false,
+ Description $description = null
+ ) {
+ Assert::stringNotEmpty($methodName);
+ Assert::boolean($static);
+
+ if ($returnType === null) {
+ $returnType = new Void_();
+ }
+
+ $this->methodName = $methodName;
+ $this->arguments = $this->filterArguments($arguments);
+ $this->returnType = $returnType;
+ $this->isStatic = $static;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ TypeResolver $typeResolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::stringNotEmpty($body);
+ Assert::allNotNull([ $typeResolver, $descriptionFactory ]);
+
+ // 1. none or more whitespace
+ // 2. optionally the keyword "static" followed by whitespace
+ // 3. optionally a word with underscores followed by whitespace : as
+ // type for the return value
+ // 4. then optionally a word with underscores followed by () and
+ // whitespace : as method name as used by phpDocumentor
+ // 5. then a word with underscores, followed by ( and any character
+ // until a ) and whitespace : as method name with signature
+ // 6. any remaining text : as description
+ if (!preg_match(
+ '/^
+ # Static keyword
+ # Declares a static method ONLY if type is also present
+ (?:
+ (static)
+ \s+
+ )?
+ # Return type
+ (?:
+ (
+ (?:[\w\|_\\\\]*\$this[\w\|_\\\\]*)
+ |
+ (?:
+ (?:[\w\|_\\\\]+)
+ # array notation
+ (?:\[\])*
+ )*
+ )
+ \s+
+ )?
+ # Legacy method name (not captured)
+ (?:
+ [\w_]+\(\)\s+
+ )?
+ # Method name
+ ([\w\|_\\\\]+)
+ # Arguments
+ (?:
+ \(([^\)]*)\)
+ )?
+ \s*
+ # Description
+ (.*)
+ $/sux',
+ $body,
+ $matches
+ )) {
+ return null;
+ }
+
+ list(, $static, $returnType, $methodName, $arguments, $description) = $matches;
+
+ $static = $static === 'static';
+
+ if ($returnType === '') {
+ $returnType = 'void';
+ }
+
+ $returnType = $typeResolver->resolve($returnType, $context);
+ $description = $descriptionFactory->create($description, $context);
+
+ if (is_string($arguments) && strlen($arguments) > 0) {
+ $arguments = explode(',', $arguments);
+ foreach ($arguments as &$argument) {
+ $argument = explode(' ', self::stripRestArg(trim($argument)), 2);
+ if ($argument[0][0] === '$') {
+ $argumentName = substr($argument[0], 1);
+ $argumentType = new Void_();
+ } else {
+ $argumentType = $typeResolver->resolve($argument[0], $context);
+ $argumentName = '';
+ if (isset($argument[1])) {
+ $argument[1] = self::stripRestArg($argument[1]);
+ $argumentName = substr($argument[1], 1);
+ }
+ }
+
+ $argument = [ 'name' => $argumentName, 'type' => $argumentType];
+ }
+ } else {
+ $arguments = [];
+ }
+
+ return new static($methodName, $arguments, $returnType, $static, $description);
+ }
+
+ /**
+ * Retrieves the method name.
+ *
+ * @return string
+ */
+ public function getMethodName()
+ {
+ return $this->methodName;
+ }
+
+ /**
+ * @return string[]
+ */
+ public function getArguments()
+ {
+ return $this->arguments;
+ }
+
+ /**
+ * Checks whether the method tag describes a static method or not.
+ *
+ * @return bool TRUE if the method declaration is for a static method, FALSE otherwise.
+ */
+ public function isStatic()
+ {
+ return $this->isStatic;
+ }
+
+ /**
+ * @return Type
+ */
+ public function getReturnType()
+ {
+ return $this->returnType;
+ }
+
+ public function __toString()
+ {
+ $arguments = [];
+ foreach ($this->arguments as $argument) {
+ $arguments[] = $argument['type'] . ' $' . $argument['name'];
+ }
+
+ return trim(($this->isStatic() ? 'static ' : '')
+ . (string)$this->returnType . ' '
+ . $this->methodName
+ . '(' . implode(', ', $arguments) . ')'
+ . ($this->description ? ' ' . $this->description->render() : ''));
+ }
+
+ private function filterArguments($arguments)
+ {
+ foreach ($arguments as &$argument) {
+ if (is_string($argument)) {
+ $argument = [ 'name' => $argument ];
+ }
+
+ if (! isset($argument['type'])) {
+ $argument['type'] = new Void_();
+ }
+
+ $keys = array_keys($argument);
+ sort($keys);
+ if ($keys !== [ 'name', 'type' ]) {
+ throw new \InvalidArgumentException(
+ 'Arguments can only have the "name" and "type" fields, found: ' . var_export($keys, true)
+ );
+ }
+ }
+
+ return $arguments;
+ }
+
+ private static function stripRestArg($argument)
+ {
+ if (strpos($argument, '...') === 0) {
+ $argument = trim(substr($argument, 3));
+ }
+
+ return $argument;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php
new file mode 100644
index 0000000..7d699d8
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php
@@ -0,0 +1,141 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for the {@}param tag in a Docblock.
+ */
+final class Param extends BaseTag implements Factory\StaticMethod
+{
+ /** @var string */
+ protected $name = 'param';
+
+ /** @var Type */
+ private $type;
+
+ /** @var string */
+ private $variableName = '';
+
+ /** @var bool determines whether this is a variadic argument */
+ private $isVariadic = false;
+
+ /**
+ * @param string $variableName
+ * @param Type $type
+ * @param bool $isVariadic
+ * @param Description $description
+ */
+ public function __construct($variableName, Type $type = null, $isVariadic = false, Description $description = null)
+ {
+ Assert::string($variableName);
+ Assert::boolean($isVariadic);
+
+ $this->variableName = $variableName;
+ $this->type = $type;
+ $this->isVariadic = $isVariadic;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ TypeResolver $typeResolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::stringNotEmpty($body);
+ Assert::allNotNull([$typeResolver, $descriptionFactory]);
+
+ $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE);
+ $type = null;
+ $variableName = '';
+ $isVariadic = false;
+
+ // if the first item that is encountered is not a variable; it is a type
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) {
+ $type = $typeResolver->resolve(array_shift($parts), $context);
+ array_shift($parts);
+ }
+
+ // if the next item starts with a $ or ...$ it must be the variable name
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$' || substr($parts[0], 0, 4) === '...$')) {
+ $variableName = array_shift($parts);
+ array_shift($parts);
+
+ if (substr($variableName, 0, 3) === '...') {
+ $isVariadic = true;
+ $variableName = substr($variableName, 3);
+ }
+
+ if (substr($variableName, 0, 1) === '$') {
+ $variableName = substr($variableName, 1);
+ }
+ }
+
+ $description = $descriptionFactory->create(implode('', $parts), $context);
+
+ return new static($variableName, $type, $isVariadic, $description);
+ }
+
+ /**
+ * Returns the variable's name.
+ *
+ * @return string
+ */
+ public function getVariableName()
+ {
+ return $this->variableName;
+ }
+
+ /**
+ * Returns the variable's type or null if unknown.
+ *
+ * @return Type|null
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ /**
+ * Returns whether this tag is variadic.
+ *
+ * @return boolean
+ */
+ public function isVariadic()
+ {
+ return $this->isVariadic;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return ($this->type ? $this->type . ' ' : '')
+ . ($this->isVariadic() ? '...' : '')
+ . '$' . $this->variableName
+ . ($this->description ? ' ' . $this->description : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php
new file mode 100644
index 0000000..f0ef7c0
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}property tag in a Docblock.
+ */
+class Property extends BaseTag implements Factory\StaticMethod
+{
+ /** @var string */
+ protected $name = 'property';
+
+ /** @var Type */
+ private $type;
+
+ /** @var string */
+ protected $variableName = '';
+
+ /**
+ * @param string $variableName
+ * @param Type $type
+ * @param Description $description
+ */
+ public function __construct($variableName, Type $type = null, Description $description = null)
+ {
+ Assert::string($variableName);
+
+ $this->variableName = $variableName;
+ $this->type = $type;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ TypeResolver $typeResolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::stringNotEmpty($body);
+ Assert::allNotNull([$typeResolver, $descriptionFactory]);
+
+ $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE);
+ $type = null;
+ $variableName = '';
+
+ // if the first item that is encountered is not a variable; it is a type
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) {
+ $type = $typeResolver->resolve(array_shift($parts), $context);
+ array_shift($parts);
+ }
+
+ // if the next item starts with a $ or ...$ it must be the variable name
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) {
+ $variableName = array_shift($parts);
+ array_shift($parts);
+
+ if (substr($variableName, 0, 1) === '$') {
+ $variableName = substr($variableName, 1);
+ }
+ }
+
+ $description = $descriptionFactory->create(implode('', $parts), $context);
+
+ return new static($variableName, $type, $description);
+ }
+
+ /**
+ * Returns the variable's name.
+ *
+ * @return string
+ */
+ public function getVariableName()
+ {
+ return $this->variableName;
+ }
+
+ /**
+ * Returns the variable's type or null if unknown.
+ *
+ * @return Type|null
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return ($this->type ? $this->type . ' ' : '')
+ . '$' . $this->variableName
+ . ($this->description ? ' ' . $this->description : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php
new file mode 100644
index 0000000..e41c0c1
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}property-read tag in a Docblock.
+ */
+class PropertyRead extends BaseTag implements Factory\StaticMethod
+{
+ /** @var string */
+ protected $name = 'property-read';
+
+ /** @var Type */
+ private $type;
+
+ /** @var string */
+ protected $variableName = '';
+
+ /**
+ * @param string $variableName
+ * @param Type $type
+ * @param Description $description
+ */
+ public function __construct($variableName, Type $type = null, Description $description = null)
+ {
+ Assert::string($variableName);
+
+ $this->variableName = $variableName;
+ $this->type = $type;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ TypeResolver $typeResolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::stringNotEmpty($body);
+ Assert::allNotNull([$typeResolver, $descriptionFactory]);
+
+ $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE);
+ $type = null;
+ $variableName = '';
+
+ // if the first item that is encountered is not a variable; it is a type
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) {
+ $type = $typeResolver->resolve(array_shift($parts), $context);
+ array_shift($parts);
+ }
+
+ // if the next item starts with a $ or ...$ it must be the variable name
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) {
+ $variableName = array_shift($parts);
+ array_shift($parts);
+
+ if (substr($variableName, 0, 1) === '$') {
+ $variableName = substr($variableName, 1);
+ }
+ }
+
+ $description = $descriptionFactory->create(implode('', $parts), $context);
+
+ return new static($variableName, $type, $description);
+ }
+
+ /**
+ * Returns the variable's name.
+ *
+ * @return string
+ */
+ public function getVariableName()
+ {
+ return $this->variableName;
+ }
+
+ /**
+ * Returns the variable's type or null if unknown.
+ *
+ * @return Type|null
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return ($this->type ? $this->type . ' ' : '')
+ . '$' . $this->variableName
+ . ($this->description ? ' ' . $this->description : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php
new file mode 100644
index 0000000..cfdb0ed
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}property-write tag in a Docblock.
+ */
+class PropertyWrite extends BaseTag implements Factory\StaticMethod
+{
+ /** @var string */
+ protected $name = 'property-write';
+
+ /** @var Type */
+ private $type;
+
+ /** @var string */
+ protected $variableName = '';
+
+ /**
+ * @param string $variableName
+ * @param Type $type
+ * @param Description $description
+ */
+ public function __construct($variableName, Type $type = null, Description $description = null)
+ {
+ Assert::string($variableName);
+
+ $this->variableName = $variableName;
+ $this->type = $type;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ TypeResolver $typeResolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::stringNotEmpty($body);
+ Assert::allNotNull([$typeResolver, $descriptionFactory]);
+
+ $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE);
+ $type = null;
+ $variableName = '';
+
+ // if the first item that is encountered is not a variable; it is a type
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) {
+ $type = $typeResolver->resolve(array_shift($parts), $context);
+ array_shift($parts);
+ }
+
+ // if the next item starts with a $ or ...$ it must be the variable name
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) {
+ $variableName = array_shift($parts);
+ array_shift($parts);
+
+ if (substr($variableName, 0, 1) === '$') {
+ $variableName = substr($variableName, 1);
+ }
+ }
+
+ $description = $descriptionFactory->create(implode('', $parts), $context);
+
+ return new static($variableName, $type, $description);
+ }
+
+ /**
+ * Returns the variable's name.
+ *
+ * @return string
+ */
+ public function getVariableName()
+ {
+ return $this->variableName;
+ }
+
+ /**
+ * Returns the variable's type or null if unknown.
+ *
+ * @return Type|null
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return ($this->type ? $this->type . ' ' : '')
+ . '$' . $this->variableName
+ . ($this->description ? ' ' . $this->description : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php
new file mode 100644
index 0000000..dc7b8b6
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2017 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Reference;
+
+use phpDocumentor\Reflection\Fqsen as RealFqsen;
+
+/**
+ * Fqsen reference used by {@see phpDocumentor\Reflection\DocBlock\Tags\See}
+ */
+final class Fqsen implements Reference
+{
+ /**
+ * @var RealFqsen
+ */
+ private $fqsen;
+
+ /**
+ * Fqsen constructor.
+ */
+ public function __construct(RealFqsen $fqsen)
+ {
+ $this->fqsen = $fqsen;
+ }
+
+ /**
+ * @return string string representation of the referenced fqsen
+ */
+ public function __toString()
+ {
+ return (string)$this->fqsen;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php
new file mode 100644
index 0000000..a3ffd24
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2017 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Reference;
+
+/**
+ * Interface for references in {@see phpDocumentor\Reflection\DocBlock\Tags\See}
+ */
+interface Reference
+{
+ public function __toString();
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Url.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Url.php
new file mode 100644
index 0000000..2671d5e
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Url.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2017 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Reference;
+
+use Webmozart\Assert\Assert;
+
+/**
+ * Url reference used by {@see phpDocumentor\Reflection\DocBlock\Tags\See}
+ */
+final class Url implements Reference
+{
+ /**
+ * @var string
+ */
+ private $uri;
+
+ /**
+ * Url constructor.
+ */
+ public function __construct($uri)
+ {
+ Assert::stringNotEmpty($uri);
+ $this->uri = $uri;
+ }
+
+ public function __toString()
+ {
+ return $this->uri;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php
new file mode 100644
index 0000000..ca5bda7
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}return tag in a Docblock.
+ */
+final class Return_ extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'return';
+
+ /** @var Type */
+ private $type;
+
+ public function __construct(Type $type, Description $description = null)
+ {
+ $this->type = $type;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ TypeResolver $typeResolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::string($body);
+ Assert::allNotNull([$typeResolver, $descriptionFactory]);
+
+ $parts = preg_split('/\s+/Su', $body, 2);
+
+ $type = $typeResolver->resolve(isset($parts[0]) ? $parts[0] : '', $context);
+ $description = $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context);
+
+ return new static($type, $description);
+ }
+
+ /**
+ * Returns the type section of the variable.
+ *
+ * @return Type
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ public function __toString()
+ {
+ return $this->type . ' ' . $this->description;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php
new file mode 100644
index 0000000..9e9e723
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\Tags\Reference\Fqsen as FqsenRef;
+use phpDocumentor\Reflection\DocBlock\Tags\Reference\Reference;
+use phpDocumentor\Reflection\DocBlock\Tags\Reference\Url;
+use phpDocumentor\Reflection\FqsenResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for an {@}see tag in a Docblock.
+ */
+class See extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'see';
+
+ /** @var Reference */
+ protected $refers = null;
+
+ /**
+ * Initializes this tag.
+ *
+ * @param Reference $refers
+ * @param Description $description
+ */
+ public function __construct(Reference $refers, Description $description = null)
+ {
+ $this->refers = $refers;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ FqsenResolver $resolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::string($body);
+ Assert::allNotNull([$resolver, $descriptionFactory]);
+
+ $parts = preg_split('/\s+/Su', $body, 2);
+ $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null;
+
+ // https://tools.ietf.org/html/rfc2396#section-3
+ if (preg_match('/\w:\/\/\w/i', $parts[0])) {
+ return new static(new Url($parts[0]), $description);
+ }
+
+ return new static(new FqsenRef($resolver->resolve($parts[0], $context)), $description);
+ }
+
+ /**
+ * Returns the ref of this tag.
+ *
+ * @return Reference
+ */
+ public function getReference()
+ {
+ return $this->refers;
+ }
+
+ /**
+ * Returns a string representation of this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->refers . ($this->description ? ' ' . $this->description->render() : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php
new file mode 100644
index 0000000..835fb0d
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}since tag in a Docblock.
+ */
+final class Since extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'since';
+
+ /**
+ * PCRE regular expression matching a version vector.
+ * Assumes the "x" modifier.
+ */
+ const REGEX_VECTOR = '(?:
+ # Normal release vectors.
+ \d\S*
+ |
+ # VCS version vectors. Per PHPCS, they are expected to
+ # follow the form of the VCS name, followed by ":", followed
+ # by the version vector itself.
+ # By convention, popular VCSes like CVS, SVN and GIT use "$"
+ # around the actual version vector.
+ [^\s\:]+\:\s*\$[^\$]+\$
+ )';
+
+ /** @var string The version vector. */
+ private $version = '';
+
+ public function __construct($version = null, Description $description = null)
+ {
+ Assert::nullOrStringNotEmpty($version);
+
+ $this->version = $version;
+ $this->description = $description;
+ }
+
+ /**
+ * @return static
+ */
+ public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null)
+ {
+ Assert::nullOrString($body);
+ if (empty($body)) {
+ return new static();
+ }
+
+ $matches = [];
+ if (! preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) {
+ return null;
+ }
+
+ return new static(
+ $matches[1],
+ $descriptionFactory->create(isset($matches[2]) ? $matches[2] : '', $context)
+ );
+ }
+
+ /**
+ * Gets the version section of the tag.
+ *
+ * @return string
+ */
+ public function getVersion()
+ {
+ return $this->version;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->version . ($this->description ? ' ' . $this->description->render() : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php
new file mode 100644
index 0000000..247b1b3
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}source tag in a Docblock.
+ */
+final class Source extends BaseTag implements Factory\StaticMethod
+{
+ /** @var string */
+ protected $name = 'source';
+
+ /** @var int The starting line, relative to the structural element's location. */
+ private $startingLine = 1;
+
+ /** @var int|null The number of lines, relative to the starting line. NULL means "to the end". */
+ private $lineCount = null;
+
+ public function __construct($startingLine, $lineCount = null, Description $description = null)
+ {
+ Assert::integerish($startingLine);
+ Assert::nullOrIntegerish($lineCount);
+
+ $this->startingLine = (int)$startingLine;
+ $this->lineCount = $lineCount !== null ? (int)$lineCount : null;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null)
+ {
+ Assert::stringNotEmpty($body);
+ Assert::notNull($descriptionFactory);
+
+ $startingLine = 1;
+ $lineCount = null;
+ $description = null;
+
+ // Starting line / Number of lines / Description
+ if (preg_match('/^([1-9]\d*)\s*(?:((?1))\s+)?(.*)$/sux', $body, $matches)) {
+ $startingLine = (int)$matches[1];
+ if (isset($matches[2]) && $matches[2] !== '') {
+ $lineCount = (int)$matches[2];
+ }
+
+ $description = $matches[3];
+ }
+
+ return new static($startingLine, $lineCount, $descriptionFactory->create($description, $context));
+ }
+
+ /**
+ * Gets the starting line.
+ *
+ * @return int The starting line, relative to the structural element's
+ * location.
+ */
+ public function getStartingLine()
+ {
+ return $this->startingLine;
+ }
+
+ /**
+ * Returns the number of lines.
+ *
+ * @return int|null The number of lines, relative to the starting line. NULL
+ * means "to the end".
+ */
+ public function getLineCount()
+ {
+ return $this->lineCount;
+ }
+
+ public function __toString()
+ {
+ return $this->startingLine
+ . ($this->lineCount !== null ? ' ' . $this->lineCount : '')
+ . ($this->description ? ' ' . $this->description->render() : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php
new file mode 100644
index 0000000..349e773
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}throws tag in a Docblock.
+ */
+final class Throws extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'throws';
+
+ /** @var Type */
+ private $type;
+
+ public function __construct(Type $type, Description $description = null)
+ {
+ $this->type = $type;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ TypeResolver $typeResolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::string($body);
+ Assert::allNotNull([$typeResolver, $descriptionFactory]);
+
+ $parts = preg_split('/\s+/Su', $body, 2);
+
+ $type = $typeResolver->resolve(isset($parts[0]) ? $parts[0] : '', $context);
+ $description = $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context);
+
+ return new static($type, $description);
+ }
+
+ /**
+ * Returns the type section of the variable.
+ *
+ * @return Type
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ public function __toString()
+ {
+ return $this->type . ' ' . $this->description;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php
new file mode 100644
index 0000000..00dc3e3
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Fqsen;
+use phpDocumentor\Reflection\FqsenResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}uses tag in a Docblock.
+ */
+final class Uses extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'uses';
+
+ /** @var Fqsen */
+ protected $refers = null;
+
+ /**
+ * Initializes this tag.
+ *
+ * @param Fqsen $refers
+ * @param Description $description
+ */
+ public function __construct(Fqsen $refers, Description $description = null)
+ {
+ $this->refers = $refers;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ FqsenResolver $resolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::string($body);
+ Assert::allNotNull([$resolver, $descriptionFactory]);
+
+ $parts = preg_split('/\s+/Su', $body, 2);
+
+ return new static(
+ $resolver->resolve($parts[0], $context),
+ $descriptionFactory->create(isset($parts[1]) ? $parts[1] : '', $context)
+ );
+ }
+
+ /**
+ * Returns the structural element this tag refers to.
+ *
+ * @return Fqsen
+ */
+ public function getReference()
+ {
+ return $this->refers;
+ }
+
+ /**
+ * Returns a string representation of this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->refers . ' ' . $this->description->render();
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php
new file mode 100644
index 0000000..8907c95
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}var tag in a Docblock.
+ */
+class Var_ extends BaseTag implements Factory\StaticMethod
+{
+ /** @var string */
+ protected $name = 'var';
+
+ /** @var Type */
+ private $type;
+
+ /** @var string */
+ protected $variableName = '';
+
+ /**
+ * @param string $variableName
+ * @param Type $type
+ * @param Description $description
+ */
+ public function __construct($variableName, Type $type = null, Description $description = null)
+ {
+ Assert::string($variableName);
+
+ $this->variableName = $variableName;
+ $this->type = $type;
+ $this->description = $description;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(
+ $body,
+ TypeResolver $typeResolver = null,
+ DescriptionFactory $descriptionFactory = null,
+ TypeContext $context = null
+ ) {
+ Assert::stringNotEmpty($body);
+ Assert::allNotNull([$typeResolver, $descriptionFactory]);
+
+ $parts = preg_split('/(\s+)/Su', $body, 3, PREG_SPLIT_DELIM_CAPTURE);
+ $type = null;
+ $variableName = '';
+
+ // if the first item that is encountered is not a variable; it is a type
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] !== '$')) {
+ $type = $typeResolver->resolve(array_shift($parts), $context);
+ array_shift($parts);
+ }
+
+ // if the next item starts with a $ or ...$ it must be the variable name
+ if (isset($parts[0]) && (strlen($parts[0]) > 0) && ($parts[0][0] === '$')) {
+ $variableName = array_shift($parts);
+ array_shift($parts);
+
+ if (substr($variableName, 0, 1) === '$') {
+ $variableName = substr($variableName, 1);
+ }
+ }
+
+ $description = $descriptionFactory->create(implode('', $parts), $context);
+
+ return new static($variableName, $type, $description);
+ }
+
+ /**
+ * Returns the variable's name.
+ *
+ * @return string
+ */
+ public function getVariableName()
+ {
+ return $this->variableName;
+ }
+
+ /**
+ * Returns the variable's type or null if unknown.
+ *
+ * @return Type|null
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return ($this->type ? $this->type . ' ' : '')
+ . (empty($this->variableName) ? null : ('$' . $this->variableName))
+ . ($this->description ? ' ' . $this->description : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php
new file mode 100644
index 0000000..7bb0420
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * phpDocumentor
+ *
+ * PHP Version 5.3
+ *
+ * @author Vasil Rangelov <boen.robot@gmail.com>
+ * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use Webmozart\Assert\Assert;
+
+/**
+ * Reflection class for a {@}version tag in a Docblock.
+ */
+final class Version extends BaseTag implements Factory\StaticMethod
+{
+ protected $name = 'version';
+
+ /**
+ * PCRE regular expression matching a version vector.
+ * Assumes the "x" modifier.
+ */
+ const REGEX_VECTOR = '(?:
+ # Normal release vectors.
+ \d\S*
+ |
+ # VCS version vectors. Per PHPCS, they are expected to
+ # follow the form of the VCS name, followed by ":", followed
+ # by the version vector itself.
+ # By convention, popular VCSes like CVS, SVN and GIT use "$"
+ # around the actual version vector.
+ [^\s\:]+\:\s*\$[^\$]+\$
+ )';
+
+ /** @var string The version vector. */
+ private $version = '';
+
+ public function __construct($version = null, Description $description = null)
+ {
+ Assert::nullOrStringNotEmpty($version);
+
+ $this->version = $version;
+ $this->description = $description;
+ }
+
+ /**
+ * @return static
+ */
+ public static function create($body, DescriptionFactory $descriptionFactory = null, TypeContext $context = null)
+ {
+ Assert::nullOrString($body);
+ if (empty($body)) {
+ return new static();
+ }
+
+ $matches = [];
+ if (!preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) {
+ return null;
+ }
+
+ return new static(
+ $matches[1],
+ $descriptionFactory->create(isset($matches[2]) ? $matches[2] : '', $context)
+ );
+ }
+
+ /**
+ * Gets the version section of the tag.
+ *
+ * @return string
+ */
+ public function getVersion()
+ {
+ return $this->version;
+ }
+
+ /**
+ * Returns a string representation for this tag.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->version . ($this->description ? ' ' . $this->description->render() : '');
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactory.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactory.php
new file mode 100644
index 0000000..1bdb8f4
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactory.php
@@ -0,0 +1,277 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection;
+
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\StandardTagFactory;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\TagFactory;
+use Webmozart\Assert\Assert;
+
+final class DocBlockFactory implements DocBlockFactoryInterface
+{
+ /** @var DocBlock\DescriptionFactory */
+ private $descriptionFactory;
+
+ /** @var DocBlock\TagFactory */
+ private $tagFactory;
+
+ /**
+ * Initializes this factory with the required subcontractors.
+ *
+ * @param DescriptionFactory $descriptionFactory
+ * @param TagFactory $tagFactory
+ */
+ public function __construct(DescriptionFactory $descriptionFactory, TagFactory $tagFactory)
+ {
+ $this->descriptionFactory = $descriptionFactory;
+ $this->tagFactory = $tagFactory;
+ }
+
+ /**
+ * Factory method for easy instantiation.
+ *
+ * @param string[] $additionalTags
+ *
+ * @return DocBlockFactory
+ */
+ public static function createInstance(array $additionalTags = [])
+ {
+ $fqsenResolver = new FqsenResolver();
+ $tagFactory = new StandardTagFactory($fqsenResolver);
+ $descriptionFactory = new DescriptionFactory($tagFactory);
+
+ $tagFactory->addService($descriptionFactory);
+ $tagFactory->addService(new TypeResolver($fqsenResolver));
+
+ $docBlockFactory = new self($descriptionFactory, $tagFactory);
+ foreach ($additionalTags as $tagName => $tagHandler) {
+ $docBlockFactory->registerTagHandler($tagName, $tagHandler);
+ }
+
+ return $docBlockFactory;
+ }
+
+ /**
+ * @param object|string $docblock A string containing the DocBlock to parse or an object supporting the
+ * getDocComment method (such as a ReflectionClass object).
+ * @param Types\Context $context
+ * @param Location $location
+ *
+ * @return DocBlock
+ */
+ public function create($docblock, Types\Context $context = null, Location $location = null)
+ {
+ if (is_object($docblock)) {
+ if (!method_exists($docblock, 'getDocComment')) {
+ $exceptionMessage = 'Invalid object passed; the given object must support the getDocComment method';
+ throw new \InvalidArgumentException($exceptionMessage);
+ }
+
+ $docblock = $docblock->getDocComment();
+ }
+
+ Assert::stringNotEmpty($docblock);
+
+ if ($context === null) {
+ $context = new Types\Context('');
+ }
+
+ $parts = $this->splitDocBlock($this->stripDocComment($docblock));
+ list($templateMarker, $summary, $description, $tags) = $parts;
+
+ return new DocBlock(
+ $summary,
+ $description ? $this->descriptionFactory->create($description, $context) : null,
+ array_filter($this->parseTagBlock($tags, $context), function ($tag) {
+ return $tag instanceof Tag;
+ }),
+ $context,
+ $location,
+ $templateMarker === '#@+',
+ $templateMarker === '#@-'
+ );
+ }
+
+ public function registerTagHandler($tagName, $handler)
+ {
+ $this->tagFactory->registerTagHandler($tagName, $handler);
+ }
+
+ /**
+ * Strips the asterisks from the DocBlock comment.
+ *
+ * @param string $comment String containing the comment text.
+ *
+ * @return string
+ */
+ private function stripDocComment($comment)
+ {
+ $comment = trim(preg_replace('#[ \t]*(?:\/\*\*|\*\/|\*)?[ \t]{0,1}(.*)?#u', '$1', $comment));
+
+ // reg ex above is not able to remove */ from a single line docblock
+ if (substr($comment, -2) === '*/') {
+ $comment = trim(substr($comment, 0, -2));
+ }
+
+ return str_replace(["\r\n", "\r"], "\n", $comment);
+ }
+
+ /**
+ * Splits the DocBlock into a template marker, summary, description and block of tags.
+ *
+ * @param string $comment Comment to split into the sub-parts.
+ *
+ * @author Richard van Velzen (@_richardJ) Special thanks to Richard for the regex responsible for the split.
+ * @author Mike van Riel <me@mikevanriel.com> for extending the regex with template marker support.
+ *
+ * @return string[] containing the template marker (if any), summary, description and a string containing the tags.
+ */
+ private function splitDocBlock($comment)
+ {
+ // Performance improvement cheat: if the first character is an @ then only tags are in this DocBlock. This
+ // method does not split tags so we return this verbatim as the fourth result (tags). This saves us the
+ // performance impact of running a regular expression
+ if (strpos($comment, '@') === 0) {
+ return ['', '', '', $comment];
+ }
+
+ // clears all extra horizontal whitespace from the line endings to prevent parsing issues
+ $comment = preg_replace('/\h*$/Sum', '', $comment);
+
+ /*
+ * Splits the docblock into a template marker, summary, description and tags section.
+ *
+ * - The template marker is empty, #@+ or #@- if the DocBlock starts with either of those (a newline may
+ * occur after it and will be stripped).
+ * - The short description is started from the first character until a dot is encountered followed by a
+ * newline OR two consecutive newlines (horizontal whitespace is taken into account to consider spacing
+ * errors). This is optional.
+ * - The long description, any character until a new line is encountered followed by an @ and word
+ * characters (a tag). This is optional.
+ * - Tags; the remaining characters
+ *
+ * Big thanks to RichardJ for contributing this Regular Expression
+ */
+ preg_match(
+ '/
+ \A
+ # 1. Extract the template marker
+ (?:(\#\@\+|\#\@\-)\n?)?
+
+ # 2. Extract the summary
+ (?:
+ (?! @\pL ) # The summary may not start with an @
+ (
+ [^\n.]+
+ (?:
+ (?! \. \n | \n{2} ) # End summary upon a dot followed by newline or two newlines
+ [\n.] (?! [ \t]* @\pL ) # End summary when an @ is found as first character on a new line
+ [^\n.]+ # Include anything else
+ )*
+ \.?
+ )?
+ )
+
+ # 3. Extract the description
+ (?:
+ \s* # Some form of whitespace _must_ precede a description because a summary must be there
+ (?! @\pL ) # The description may not start with an @
+ (
+ [^\n]+
+ (?: \n+
+ (?! [ \t]* @\pL ) # End description when an @ is found as first character on a new line
+ [^\n]+ # Include anything else
+ )*
+ )
+ )?
+
+ # 4. Extract the tags (anything that follows)
+ (\s+ [\s\S]*)? # everything that follows
+ /ux',
+ $comment,
+ $matches
+ );
+ array_shift($matches);
+
+ while (count($matches) < 4) {
+ $matches[] = '';
+ }
+
+ return $matches;
+ }
+
+ /**
+ * Creates the tag objects.
+ *
+ * @param string $tags Tag block to parse.
+ * @param Types\Context $context Context of the parsed Tag
+ *
+ * @return DocBlock\Tag[]
+ */
+ private function parseTagBlock($tags, Types\Context $context)
+ {
+ $tags = $this->filterTagBlock($tags);
+ if (!$tags) {
+ return [];
+ }
+
+ $result = $this->splitTagBlockIntoTagLines($tags);
+ foreach ($result as $key => $tagLine) {
+ $result[$key] = $this->tagFactory->create(trim($tagLine), $context);
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param string $tags
+ *
+ * @return string[]
+ */
+ private function splitTagBlockIntoTagLines($tags)
+ {
+ $result = [];
+ foreach (explode("\n", $tags) as $tag_line) {
+ if (isset($tag_line[0]) && ($tag_line[0] === '@')) {
+ $result[] = $tag_line;
+ } else {
+ $result[count($result) - 1] .= "\n" . $tag_line;
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param $tags
+ * @return string
+ */
+ private function filterTagBlock($tags)
+ {
+ $tags = trim($tags);
+ if (!$tags) {
+ return null;
+ }
+
+ if ('@' !== $tags[0]) {
+ // @codeCoverageIgnoreStart
+ // Can't simulate this; this only happens if there is an error with the parsing of the DocBlock that
+ // we didn't foresee.
+ throw new \LogicException('A tag block started with text instead of an at-sign(@): ' . $tags);
+ // @codeCoverageIgnoreEnd
+ }
+
+ return $tags;
+ }
+}
diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php
new file mode 100644
index 0000000..b353342
--- /dev/null
+++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php
@@ -0,0 +1,23 @@
+<?php
+namespace phpDocumentor\Reflection;
+
+interface DocBlockFactoryInterface
+{
+ /**
+ * Factory method for easy instantiation.
+ *
+ * @param string[] $additionalTags
+ *
+ * @return DocBlockFactory
+ */
+ public static function createInstance(array $additionalTags = []);
+
+ /**
+ * @param string $docblock
+ * @param Types\Context $context
+ * @param Location $location
+ *
+ * @return DocBlock
+ */
+ public function create($docblock, Types\Context $context = null, Location $location = null);
+}
diff --git a/vendor/phpdocumentor/type-resolver/LICENSE b/vendor/phpdocumentor/type-resolver/LICENSE
new file mode 100644
index 0000000..792e404
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2010 Mike van Riel
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/phpdocumentor/type-resolver/README.md b/vendor/phpdocumentor/type-resolver/README.md
new file mode 100644
index 0000000..fad3400
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/README.md
@@ -0,0 +1,182 @@
+TypeResolver and FqsenResolver
+==============================
+
+The specification on types in DocBlocks (PSR-5) describes various keywords and special constructs
+but also how to statically resolve the partial name of a Class into a Fully Qualified Class Name (FQCN).
+
+PSR-5 also introduces an additional way to describe deeper elements than Classes, Interfaces and Traits
+called the Fully Qualified Structural Element Name (FQSEN). Using this it is possible to refer to methods,
+properties and class constants but also functions and global constants.
+
+This package provides two Resolvers that are capable of
+
+1. Returning a series of Value Object for given expression while resolving any partial class names, and
+2. Returning an FQSEN object after resolving any partial Structural Element Names into Fully Qualified Structural
+ Element names.
+
+## Installing
+
+The easiest way to install this library is with [Composer](https://getcomposer.org) using the following command:
+
+ $ composer require phpdocumentor/type-resolver
+
+## Examples
+
+Ready to dive in and don't want to read through all that text below? Just consult the [examples](examples) folder and
+check which type of action that your want to accomplish.
+
+## On Types and Element Names
+
+This component can be used in one of two ways
+
+1. To resolve a Type or
+2. To resolve a Fully Qualified Structural Element Name
+
+The big difference between these two is in the number of things it can resolve.
+
+The TypeResolver can resolve:
+
+- a php primitive or pseudo-primitive such as a string or void (`@var string` or `@return void`).
+- a composite such as an array of string (`@var string[]`).
+- a compound such as a string or integer (`@var string|integer`).
+- an object or interface such as the TypeResolver class (`@var TypeResolver`
+ or `@var \phpDocumentor\Reflection\TypeResolver`)
+
+ > please note that if you want to pass partial class names that additional steps are necessary, see the
+ > chapter `Resolving partial classes and FQSENs` for more information.
+
+Where the FqsenResolver can resolve:
+
+- Constant expressions (i.e. `@see \MyNamespace\MY_CONSTANT`)
+- Function expressions (i.e. `@see \MyNamespace\myFunction()`)
+- Class expressions (i.e. `@see \MyNamespace\MyClass`)
+- Interface expressions (i.e. `@see \MyNamespace\MyInterface`)
+- Trait expressions (i.e. `@see \MyNamespace\MyTrait`)
+- Class constant expressions (i.e. `@see \MyNamespace\MyClass::MY_CONSTANT`)
+- Property expressions (i.e. `@see \MyNamespace\MyClass::$myProperty`)
+- Method expressions (i.e. `@see \MyNamespace\MyClass::myMethod()`)
+
+## Resolving a type
+
+In order to resolve a type you will have to instantiate the class `\phpDocumentor\Reflection\TypeResolver`
+and call its `resolve` method like this:
+
+```php
+$typeResolver = new \phpDocumentor\Reflection\TypeResolver();
+$type = $typeResolver->resolve('string|integer');
+```
+
+In this example you will receive a Value Object of class `\phpDocumentor\Reflection\Types\Compound` that has two
+elements, one of type `\phpDocumentor\Reflection\Types\String_` and one of type
+`\phpDocumentor\Reflection\Types\Integer`.
+
+The real power of this resolver is in its capability to expand partial class names into fully qualified class names; but
+in order to do that we need an additional `\phpDocumentor\Reflection\Types\Context` class that will inform the resolver
+in which namespace the given expression occurs and which namespace aliases (or imports) apply.
+
+## Resolving an FQSEN
+
+A Fully Qualified Structural Element Name is a reference to another element in your code bases and can be resolved using
+the `\phpDocumentor\Reflection\FqsenResolver` class' `resolve` method, like this:
+
+```php
+$fqsenResolver = new \phpDocumentor\Reflection\FqsenResolver();
+$fqsen = $fqsenResolver->resolve('\phpDocumentor\Reflection\FqsenResolver::resolve()');
+```
+
+In this example we resolve a Fully Qualified Structural Element Name (meaning that it includes the full namespace, class
+name and element name) and receive a Value Object of type `\phpDocumentor\Reflection\Fqsen`.
+
+The real power of this resolver is in its capability to expand partial element names into Fully Qualified Structural
+Element Names; but in order to do that we need an additional `\phpDocumentor\Reflection\Types\Context` class that will
+inform the resolver in which namespace the given expression occurs and which namespace aliases (or imports) apply.
+
+## Resolving partial Classes and Structural Element Names
+
+Perhaps the best feature of this library is that it knows how to resolve partial class names into fully qualified class
+names.
+
+For example, you have this file:
+
+```php
+namespace My\Example;
+
+use phpDocumentor\Reflection\Types;
+
+class Classy
+{
+ /**
+ * @var Types\Context
+ * @see Classy::otherFunction()
+ */
+ public function __construct($context) {}
+
+ public function otherFunction(){}
+}
+```
+
+Suppose that you would want to resolve (and expand) the type in the `@var` tag and the element name in the `@see` tag.
+For the resolvers to know how to expand partial names you have to provide a bit of _Context_ for them by instantiating
+a new class named `\phpDocumentor\Reflection\Types\Context` with the name of the namespace and the aliases that are in
+play.
+
+### Creating a Context
+
+You can do this by manually creating a Context like this:
+
+```php
+$context = new \phpDocumentor\Reflection\Types\Context(
+ '\My\Example',
+ [ 'Types' => '\phpDocumentor\Reflection\Types']
+);
+```
+
+Or by using the `\phpDocumentor\Reflection\Types\ContextFactory` to instantiate a new context based on a Reflector
+object or by providing the namespace that you'd like to extract and the source code of the file in which the given
+type expression occurs.
+
+```php
+$contextFactory = new \phpDocumentor\Reflection\Types\ContextFactory();
+$context = $contextFactory->createFromReflector(new ReflectionMethod('\My\Example\Classy', '__construct'));
+```
+
+or
+
+```php
+$contextFactory = new \phpDocumentor\Reflection\Types\ContextFactory();
+$context = $contextFactory->createForNamespace('\My\Example', file_get_contents('My/Example/Classy.php'));
+```
+
+### Using the Context
+
+After you have obtained a Context it is just a matter of passing it along with the `resolve` method of either Resolver
+class as second argument and the Resolvers will take this into account when resolving partial names.
+
+To obtain the resolved class name for the `@var` tag in the example above you can do:
+
+```php
+$typeResolver = new \phpDocumentor\Reflection\TypeResolver();
+$type = $typeResolver->resolve('Types\Context', $context);
+```
+
+When you do this you will receive an object of class `\phpDocumentor\Reflection\Types\Object_` for which you can call
+the `getFqsen` method to receive a Value Object that represents the complete FQSEN. So that would be
+`phpDocumentor\Reflection\Types\Context`.
+
+> Why is the FQSEN wrapped in another object `Object_`?
+>
+> The resolve method of the TypeResolver only returns object with the interface `Type` and the FQSEN is a common
+> type that does not represent a Type. Also: in some cases a type can represent an "Untyped Object", meaning that it
+> is an object (signified by the `object` keyword) but does not refer to a specific element using an FQSEN.
+
+Another example is on how to resolve the FQSEN of a method as can be seen with the `@see` tag in the example above. To
+resolve that you can do the following:
+
+```php
+$fqsenResolver = new \phpDocumentor\Reflection\FqsenResolver();
+$type = $fqsenResolver->resolve('Classy::otherFunction()', $context);
+```
+
+Because Classy is a Class in the current namespace its FQSEN will have the `My\Example` namespace and by calling the
+`resolve` method of the FQSEN Resolver you will receive an `Fqsen` object that refers to
+`\My\Example\Classy::otherFunction()`.
diff --git a/vendor/phpdocumentor/type-resolver/composer.json b/vendor/phpdocumentor/type-resolver/composer.json
new file mode 100644
index 0000000..82ead15
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/composer.json
@@ -0,0 +1,27 @@
+{
+ "name": "phpdocumentor/type-resolver",
+ "type": "library",
+ "license": "MIT",
+ "authors": [
+ {"name": "Mike van Riel", "email": "me@mikevanriel.com"}
+ ],
+ "require": {
+ "php": "^5.5 || ^7.0",
+ "phpdocumentor/reflection-common": "^1.0"
+ },
+ "autoload": {
+ "psr-4": {"phpDocumentor\\Reflection\\": ["src/"]}
+ },
+ "autoload-dev": {
+ "psr-4": {"phpDocumentor\\Reflection\\": ["tests/unit"]}
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.2||^4.8.24",
+ "mockery/mockery": "^0.9.4"
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/FqsenResolver.php b/vendor/phpdocumentor/type-resolver/src/FqsenResolver.php
new file mode 100644
index 0000000..9aa6ba3
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/FqsenResolver.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection;
+
+use phpDocumentor\Reflection\Types\Context;
+
+class FqsenResolver
+{
+ /** @var string Definition of the NAMESPACE operator in PHP */
+ const OPERATOR_NAMESPACE = '\\';
+
+ public function resolve($fqsen, Context $context = null)
+ {
+ if ($context === null) {
+ $context = new Context('');
+ }
+
+ if ($this->isFqsen($fqsen)) {
+ return new Fqsen($fqsen);
+ }
+
+ return $this->resolvePartialStructuralElementName($fqsen, $context);
+ }
+
+ /**
+ * Tests whether the given type is a Fully Qualified Structural Element Name.
+ *
+ * @param string $type
+ *
+ * @return bool
+ */
+ private function isFqsen($type)
+ {
+ return strpos($type, self::OPERATOR_NAMESPACE) === 0;
+ }
+
+ /**
+ * Resolves a partial Structural Element Name (i.e. `Reflection\DocBlock`) to its FQSEN representation
+ * (i.e. `\phpDocumentor\Reflection\DocBlock`) based on the Namespace and aliases mentioned in the Context.
+ *
+ * @param string $type
+ * @param Context $context
+ *
+ * @return Fqsen
+ * @throws \InvalidArgumentException when type is not a valid FQSEN.
+ */
+ private function resolvePartialStructuralElementName($type, Context $context)
+ {
+ $typeParts = explode(self::OPERATOR_NAMESPACE, $type, 2);
+
+ $namespaceAliases = $context->getNamespaceAliases();
+
+ // if the first segment is not an alias; prepend namespace name and return
+ if (!isset($namespaceAliases[$typeParts[0]])) {
+ $namespace = $context->getNamespace();
+ if ('' !== $namespace) {
+ $namespace .= self::OPERATOR_NAMESPACE;
+ }
+
+ return new Fqsen(self::OPERATOR_NAMESPACE . $namespace . $type);
+ }
+
+ $typeParts[0] = $namespaceAliases[$typeParts[0]];
+
+ return new Fqsen(self::OPERATOR_NAMESPACE . implode(self::OPERATOR_NAMESPACE, $typeParts));
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Type.php b/vendor/phpdocumentor/type-resolver/src/Type.php
new file mode 100644
index 0000000..33ca559
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Type.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection;
+
+interface Type
+{
+ public function __toString();
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/TypeResolver.php b/vendor/phpdocumentor/type-resolver/src/TypeResolver.php
new file mode 100644
index 0000000..08b2a5f
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/TypeResolver.php
@@ -0,0 +1,298 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection;
+
+use phpDocumentor\Reflection\Types\Array_;
+use phpDocumentor\Reflection\Types\Compound;
+use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\Iterable_;
+use phpDocumentor\Reflection\Types\Nullable;
+use phpDocumentor\Reflection\Types\Object_;
+
+final class TypeResolver
+{
+ /** @var string Definition of the ARRAY operator for types */
+ const OPERATOR_ARRAY = '[]';
+
+ /** @var string Definition of the NAMESPACE operator in PHP */
+ const OPERATOR_NAMESPACE = '\\';
+
+ /** @var string[] List of recognized keywords and unto which Value Object they map */
+ private $keywords = array(
+ 'string' => Types\String_::class,
+ 'int' => Types\Integer::class,
+ 'integer' => Types\Integer::class,
+ 'bool' => Types\Boolean::class,
+ 'boolean' => Types\Boolean::class,
+ 'float' => Types\Float_::class,
+ 'double' => Types\Float_::class,
+ 'object' => Object_::class,
+ 'mixed' => Types\Mixed_::class,
+ 'array' => Array_::class,
+ 'resource' => Types\Resource_::class,
+ 'void' => Types\Void_::class,
+ 'null' => Types\Null_::class,
+ 'scalar' => Types\Scalar::class,
+ 'callback' => Types\Callable_::class,
+ 'callable' => Types\Callable_::class,
+ 'false' => Types\Boolean::class,
+ 'true' => Types\Boolean::class,
+ 'self' => Types\Self_::class,
+ '$this' => Types\This::class,
+ 'static' => Types\Static_::class,
+ 'parent' => Types\Parent_::class,
+ 'iterable' => Iterable_::class,
+ );
+
+ /** @var FqsenResolver */
+ private $fqsenResolver;
+
+ /**
+ * Initializes this TypeResolver with the means to create and resolve Fqsen objects.
+ *
+ * @param FqsenResolver $fqsenResolver
+ */
+ public function __construct(FqsenResolver $fqsenResolver = null)
+ {
+ $this->fqsenResolver = $fqsenResolver ?: new FqsenResolver();
+ }
+
+ /**
+ * Analyzes the given type and returns the FQCN variant.
+ *
+ * When a type is provided this method checks whether it is not a keyword or
+ * Fully Qualified Class Name. If so it will use the given namespace and
+ * aliases to expand the type to a FQCN representation.
+ *
+ * This method only works as expected if the namespace and aliases are set;
+ * no dynamic reflection is being performed here.
+ *
+ * @param string $type The relative or absolute type.
+ * @param Context $context
+ *
+ * @uses Context::getNamespace() to determine with what to prefix the type name.
+ * @uses Context::getNamespaceAliases() to check whether the first part of the relative type name should not be
+ * replaced with another namespace.
+ *
+ * @return Type|null
+ */
+ public function resolve($type, Context $context = null)
+ {
+ if (!is_string($type)) {
+ throw new \InvalidArgumentException(
+ 'Attempted to resolve type but it appeared not to be a string, received: ' . var_export($type, true)
+ );
+ }
+
+ $type = trim($type);
+ if (!$type) {
+ throw new \InvalidArgumentException('Attempted to resolve "' . $type . '" but it appears to be empty');
+ }
+
+ if ($context === null) {
+ $context = new Context('');
+ }
+
+ switch (true) {
+ case $this->isNullableType($type):
+ return $this->resolveNullableType($type, $context);
+ case $this->isKeyword($type):
+ return $this->resolveKeyword($type);
+ case ($this->isCompoundType($type)):
+ return $this->resolveCompoundType($type, $context);
+ case $this->isTypedArray($type):
+ return $this->resolveTypedArray($type, $context);
+ case $this->isFqsen($type):
+ return $this->resolveTypedObject($type);
+ case $this->isPartialStructuralElementName($type):
+ return $this->resolveTypedObject($type, $context);
+ // @codeCoverageIgnoreStart
+ default:
+ // I haven't got the foggiest how the logic would come here but added this as a defense.
+ throw new \RuntimeException(
+ 'Unable to resolve type "' . $type . '", there is no known method to resolve it'
+ );
+ }
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * Adds a keyword to the list of Keywords and associates it with a specific Value Object.
+ *
+ * @param string $keyword
+ * @param string $typeClassName
+ *
+ * @return void
+ */
+ public function addKeyword($keyword, $typeClassName)
+ {
+ if (!class_exists($typeClassName)) {
+ throw new \InvalidArgumentException(
+ 'The Value Object that needs to be created with a keyword "' . $keyword . '" must be an existing class'
+ . ' but we could not find the class ' . $typeClassName
+ );
+ }
+
+ if (!in_array(Type::class, class_implements($typeClassName))) {
+ throw new \InvalidArgumentException(
+ 'The class "' . $typeClassName . '" must implement the interface "phpDocumentor\Reflection\Type"'
+ );
+ }
+
+ $this->keywords[$keyword] = $typeClassName;
+ }
+
+ /**
+ * Detects whether the given type represents an array.
+ *
+ * @param string $type A relative or absolute type as defined in the phpDocumentor documentation.
+ *
+ * @return bool
+ */
+ private function isTypedArray($type)
+ {
+ return substr($type, -2) === self::OPERATOR_ARRAY;
+ }
+
+ /**
+ * Detects whether the given type represents a PHPDoc keyword.
+ *
+ * @param string $type A relative or absolute type as defined in the phpDocumentor documentation.
+ *
+ * @return bool
+ */
+ private function isKeyword($type)
+ {
+ return in_array(strtolower($type), array_keys($this->keywords), true);
+ }
+
+ /**
+ * Detects whether the given type represents a relative structural element name.
+ *
+ * @param string $type A relative or absolute type as defined in the phpDocumentor documentation.
+ *
+ * @return bool
+ */
+ private function isPartialStructuralElementName($type)
+ {
+ return ($type[0] !== self::OPERATOR_NAMESPACE) && !$this->isKeyword($type);
+ }
+
+ /**
+ * Tests whether the given type is a Fully Qualified Structural Element Name.
+ *
+ * @param string $type
+ *
+ * @return bool
+ */
+ private function isFqsen($type)
+ {
+ return strpos($type, self::OPERATOR_NAMESPACE) === 0;
+ }
+
+ /**
+ * Tests whether the given type is a compound type (i.e. `string|int`).
+ *
+ * @param string $type
+ *
+ * @return bool
+ */
+ private function isCompoundType($type)
+ {
+ return strpos($type, '|') !== false;
+ }
+
+ /**
+ * Test whether the given type is a nullable type (i.e. `?string`)
+ *
+ * @param string $type
+ *
+ * @return bool
+ */
+ private function isNullableType($type)
+ {
+ return $type[0] === '?';
+ }
+
+ /**
+ * Resolves the given typed array string (i.e. `string[]`) into an Array object with the right types set.
+ *
+ * @param string $type
+ * @param Context $context
+ *
+ * @return Array_
+ */
+ private function resolveTypedArray($type, Context $context)
+ {
+ return new Array_($this->resolve(substr($type, 0, -2), $context));
+ }
+
+ /**
+ * Resolves the given keyword (such as `string`) into a Type object representing that keyword.
+ *
+ * @param string $type
+ *
+ * @return Type
+ */
+ private function resolveKeyword($type)
+ {
+ $className = $this->keywords[strtolower($type)];
+
+ return new $className();
+ }
+
+ /**
+ * Resolves the given FQSEN string into an FQSEN object.
+ *
+ * @param string $type
+ * @param Context|null $context
+ *
+ * @return Object_
+ */
+ private function resolveTypedObject($type, Context $context = null)
+ {
+ return new Object_($this->fqsenResolver->resolve($type, $context));
+ }
+
+ /**
+ * Resolves a compound type (i.e. `string|int`) into the appropriate Type objects or FQSEN.
+ *
+ * @param string $type
+ * @param Context $context
+ *
+ * @return Compound
+ */
+ private function resolveCompoundType($type, Context $context)
+ {
+ $types = [];
+
+ foreach (explode('|', $type) as $part) {
+ $types[] = $this->resolve($part, $context);
+ }
+
+ return new Compound($types);
+ }
+
+ /**
+ * Resolve nullable types (i.e. `?string`) into a Nullable type wrapper
+ *
+ * @param string $type
+ * @param Context $context
+ *
+ * @return Nullable
+ */
+ private function resolveNullableType($type, Context $context)
+ {
+ return new Nullable($this->resolve(ltrim($type, '?'), $context));
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Array_.php b/vendor/phpdocumentor/type-resolver/src/Types/Array_.php
new file mode 100644
index 0000000..49b7c6e
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Array_.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Represents an array type as described in the PSR-5, the PHPDoc Standard.
+ *
+ * An array can be represented in two forms:
+ *
+ * 1. Untyped (`array`), where the key and value type is unknown and hence classified as 'Mixed_'.
+ * 2. Types (`string[]`), where the value type is provided by preceding an opening and closing square bracket with a
+ * type name.
+ */
+final class Array_ implements Type
+{
+ /** @var Type */
+ private $valueType;
+
+ /** @var Type */
+ private $keyType;
+
+ /**
+ * Initializes this representation of an array with the given Type or Fqsen.
+ *
+ * @param Type $valueType
+ * @param Type $keyType
+ */
+ public function __construct(Type $valueType = null, Type $keyType = null)
+ {
+ if ($keyType === null) {
+ $keyType = new Compound([ new String_(), new Integer() ]);
+ }
+ if ($valueType === null) {
+ $valueType = new Mixed_();
+ }
+
+ $this->valueType = $valueType;
+ $this->keyType = $keyType;
+ }
+
+ /**
+ * Returns the type for the keys of this array.
+ *
+ * @return Type
+ */
+ public function getKeyType()
+ {
+ return $this->keyType;
+ }
+
+ /**
+ * Returns the value for the keys of this array.
+ *
+ * @return Type
+ */
+ public function getValueType()
+ {
+ return $this->valueType;
+ }
+
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ if ($this->valueType instanceof Mixed_) {
+ return 'array';
+ }
+
+ return $this->valueType . '[]';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Boolean.php b/vendor/phpdocumentor/type-resolver/src/Types/Boolean.php
new file mode 100644
index 0000000..f82b19e
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Boolean.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing a Boolean type.
+ */
+final class Boolean implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'bool';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Callable_.php b/vendor/phpdocumentor/type-resolver/src/Types/Callable_.php
new file mode 100644
index 0000000..68ebfbd
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Callable_.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing a Callable type.
+ */
+final class Callable_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'callable';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Compound.php b/vendor/phpdocumentor/type-resolver/src/Types/Compound.php
new file mode 100644
index 0000000..be986c3
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Compound.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use ArrayIterator;
+use IteratorAggregate;
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing a Compound Type.
+ *
+ * A Compound Type is not so much a special keyword or object reference but is a series of Types that are separated
+ * using an OR operator (`|`). This combination of types signifies that whatever is associated with this compound type
+ * may contain a value with any of the given types.
+ */
+final class Compound implements Type, IteratorAggregate
+{
+ /** @var Type[] */
+ private $types;
+
+ /**
+ * Initializes a compound type (i.e. `string|int`) and tests if the provided types all implement the Type interface.
+ *
+ * @param Type[] $types
+ * @throws \InvalidArgumentException when types are not all instance of Type
+ */
+ public function __construct(array $types)
+ {
+ foreach ($types as $type) {
+ if (!$type instanceof Type) {
+ throw new \InvalidArgumentException('A compound type can only have other types as elements');
+ }
+ }
+
+ $this->types = $types;
+ }
+
+ /**
+ * Returns the type at the given index.
+ *
+ * @param integer $index
+ *
+ * @return Type|null
+ */
+ public function get($index)
+ {
+ if (!$this->has($index)) {
+ return null;
+ }
+
+ return $this->types[$index];
+ }
+
+ /**
+ * Tests if this compound type has a type with the given index.
+ *
+ * @param integer $index
+ *
+ * @return bool
+ */
+ public function has($index)
+ {
+ return isset($this->types[$index]);
+ }
+
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return implode('|', $this->types);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getIterator()
+ {
+ return new ArrayIterator($this->types);
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Context.php b/vendor/phpdocumentor/type-resolver/src/Types/Context.php
new file mode 100644
index 0000000..4e9ce5a
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Context.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+/**
+ * Provides information about the Context in which the DocBlock occurs that receives this context.
+ *
+ * A DocBlock does not know of its own accord in which namespace it occurs and which namespace aliases are applicable
+ * for the block of code in which it is in. This information is however necessary to resolve Class names in tags since
+ * you can provide a short form or make use of namespace aliases.
+ *
+ * The phpDocumentor Reflection component knows how to create this class but if you use the DocBlock parser from your
+ * own application it is possible to generate a Context class using the ContextFactory; this will analyze the file in
+ * which an associated class resides for its namespace and imports.
+ *
+ * @see ContextFactory::createFromClassReflector()
+ * @see ContextFactory::createForNamespace()
+ */
+final class Context
+{
+ /** @var string The current namespace. */
+ private $namespace;
+
+ /** @var array List of namespace aliases => Fully Qualified Namespace. */
+ private $namespaceAliases;
+
+ /**
+ * Initializes the new context and normalizes all passed namespaces to be in Qualified Namespace Name (QNN)
+ * format (without a preceding `\`).
+ *
+ * @param string $namespace The namespace where this DocBlock resides in.
+ * @param array $namespaceAliases List of namespace aliases => Fully Qualified Namespace.
+ */
+ public function __construct($namespace, array $namespaceAliases = [])
+ {
+ $this->namespace = ('global' !== $namespace && 'default' !== $namespace)
+ ? trim((string)$namespace, '\\')
+ : '';
+
+ foreach ($namespaceAliases as $alias => $fqnn) {
+ if ($fqnn[0] === '\\') {
+ $fqnn = substr($fqnn, 1);
+ }
+ if ($fqnn[strlen($fqnn) - 1] === '\\') {
+ $fqnn = substr($fqnn, 0, -1);
+ }
+
+ $namespaceAliases[$alias] = $fqnn;
+ }
+
+ $this->namespaceAliases = $namespaceAliases;
+ }
+
+ /**
+ * Returns the Qualified Namespace Name (thus without `\` in front) where the associated element is in.
+ *
+ * @return string
+ */
+ public function getNamespace()
+ {
+ return $this->namespace;
+ }
+
+ /**
+ * Returns a list of Qualified Namespace Names (thus without `\` in front) that are imported, the keys represent
+ * the alias for the imported Namespace.
+ *
+ * @return string[]
+ */
+ public function getNamespaceAliases()
+ {
+ return $this->namespaceAliases;
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/ContextFactory.php b/vendor/phpdocumentor/type-resolver/src/Types/ContextFactory.php
new file mode 100644
index 0000000..30936a3
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/ContextFactory.php
@@ -0,0 +1,210 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+/**
+ * Convenience class to create a Context for DocBlocks when not using the Reflection Component of phpDocumentor.
+ *
+ * For a DocBlock to be able to resolve types that use partial namespace names or rely on namespace imports we need to
+ * provide a bit of context so that the DocBlock can read that and based on it decide how to resolve the types to
+ * Fully Qualified names.
+ *
+ * @see Context for more information.
+ */
+final class ContextFactory
+{
+ /** The literal used at the end of a use statement. */
+ const T_LITERAL_END_OF_USE = ';';
+
+ /** The literal used between sets of use statements */
+ const T_LITERAL_USE_SEPARATOR = ',';
+
+ /**
+ * Build a Context given a Class Reflection.
+ *
+ * @param \Reflector $reflector
+ *
+ * @see Context for more information on Contexts.
+ *
+ * @return Context
+ */
+ public function createFromReflector(\Reflector $reflector)
+ {
+ if (method_exists($reflector, 'getDeclaringClass')) {
+ $reflector = $reflector->getDeclaringClass();
+ }
+
+ $fileName = $reflector->getFileName();
+ $namespace = $reflector->getNamespaceName();
+
+ if (file_exists($fileName)) {
+ return $this->createForNamespace($namespace, file_get_contents($fileName));
+ }
+
+ return new Context($namespace, []);
+ }
+
+ /**
+ * Build a Context for a namespace in the provided file contents.
+ *
+ * @param string $namespace It does not matter if a `\` precedes the namespace name, this method first normalizes.
+ * @param string $fileContents the file's contents to retrieve the aliases from with the given namespace.
+ *
+ * @see Context for more information on Contexts.
+ *
+ * @return Context
+ */
+ public function createForNamespace($namespace, $fileContents)
+ {
+ $namespace = trim($namespace, '\\');
+ $useStatements = [];
+ $currentNamespace = '';
+ $tokens = new \ArrayIterator(token_get_all($fileContents));
+
+ while ($tokens->valid()) {
+ switch ($tokens->current()[0]) {
+ case T_NAMESPACE:
+ $currentNamespace = $this->parseNamespace($tokens);
+ break;
+ case T_CLASS:
+ // Fast-forward the iterator through the class so that any
+ // T_USE tokens found within are skipped - these are not
+ // valid namespace use statements so should be ignored.
+ $braceLevel = 0;
+ $firstBraceFound = false;
+ while ($tokens->valid() && ($braceLevel > 0 || !$firstBraceFound)) {
+ if ($tokens->current() === '{'
+ || $tokens->current()[0] === T_CURLY_OPEN
+ || $tokens->current()[0] === T_DOLLAR_OPEN_CURLY_BRACES) {
+ if (!$firstBraceFound) {
+ $firstBraceFound = true;
+ }
+ $braceLevel++;
+ }
+
+ if ($tokens->current() === '}') {
+ $braceLevel--;
+ }
+ $tokens->next();
+ }
+ break;
+ case T_USE:
+ if ($currentNamespace === $namespace) {
+ $useStatements = array_merge($useStatements, $this->parseUseStatement($tokens));
+ }
+ break;
+ }
+ $tokens->next();
+ }
+
+ return new Context($namespace, $useStatements);
+ }
+
+ /**
+ * Deduce the name from tokens when we are at the T_NAMESPACE token.
+ *
+ * @param \ArrayIterator $tokens
+ *
+ * @return string
+ */
+ private function parseNamespace(\ArrayIterator $tokens)
+ {
+ // skip to the first string or namespace separator
+ $this->skipToNextStringOrNamespaceSeparator($tokens);
+
+ $name = '';
+ while ($tokens->valid() && ($tokens->current()[0] === T_STRING || $tokens->current()[0] === T_NS_SEPARATOR)
+ ) {
+ $name .= $tokens->current()[1];
+ $tokens->next();
+ }
+
+ return $name;
+ }
+
+ /**
+ * Deduce the names of all imports when we are at the T_USE token.
+ *
+ * @param \ArrayIterator $tokens
+ *
+ * @return string[]
+ */
+ private function parseUseStatement(\ArrayIterator $tokens)
+ {
+ $uses = [];
+ $continue = true;
+
+ while ($continue) {
+ $this->skipToNextStringOrNamespaceSeparator($tokens);
+
+ list($alias, $fqnn) = $this->extractUseStatement($tokens);
+ $uses[$alias] = $fqnn;
+ if ($tokens->current()[0] === self::T_LITERAL_END_OF_USE) {
+ $continue = false;
+ }
+ }
+
+ return $uses;
+ }
+
+ /**
+ * Fast-forwards the iterator as longs as we don't encounter a T_STRING or T_NS_SEPARATOR token.
+ *
+ * @param \ArrayIterator $tokens
+ *
+ * @return void
+ */
+ private function skipToNextStringOrNamespaceSeparator(\ArrayIterator $tokens)
+ {
+ while ($tokens->valid() && ($tokens->current()[0] !== T_STRING) && ($tokens->current()[0] !== T_NS_SEPARATOR)) {
+ $tokens->next();
+ }
+ }
+
+ /**
+ * Deduce the namespace name and alias of an import when we are at the T_USE token or have not reached the end of
+ * a USE statement yet.
+ *
+ * @param \ArrayIterator $tokens
+ *
+ * @return string
+ */
+ private function extractUseStatement(\ArrayIterator $tokens)
+ {
+ $result = [''];
+ while ($tokens->valid()
+ && ($tokens->current()[0] !== self::T_LITERAL_USE_SEPARATOR)
+ && ($tokens->current()[0] !== self::T_LITERAL_END_OF_USE)
+ ) {
+ if ($tokens->current()[0] === T_AS) {
+ $result[] = '';
+ }
+ if ($tokens->current()[0] === T_STRING || $tokens->current()[0] === T_NS_SEPARATOR) {
+ $result[count($result) - 1] .= $tokens->current()[1];
+ }
+ $tokens->next();
+ }
+
+ if (count($result) == 1) {
+ $backslashPos = strrpos($result[0], '\\');
+
+ if (false !== $backslashPos) {
+ $result[] = substr($result[0], $backslashPos + 1);
+ } else {
+ $result[] = $result[0];
+ }
+ }
+
+ return array_reverse($result);
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Float_.php b/vendor/phpdocumentor/type-resolver/src/Types/Float_.php
new file mode 100644
index 0000000..e58d896
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Float_.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing a Float.
+ */
+final class Float_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'float';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Integer.php b/vendor/phpdocumentor/type-resolver/src/Types/Integer.php
new file mode 100644
index 0000000..be4555e
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Integer.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+final class Integer implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'int';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Iterable_.php b/vendor/phpdocumentor/type-resolver/src/Types/Iterable_.php
new file mode 100644
index 0000000..0cbf48f
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Iterable_.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2017 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing iterable type
+ */
+final class Iterable_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'iterable';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Mixed_.php b/vendor/phpdocumentor/type-resolver/src/Types/Mixed_.php
new file mode 100644
index 0000000..c1c165f
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Mixed_.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing an unknown, or mixed, type.
+ */
+final class Mixed_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'mixed';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Null_.php b/vendor/phpdocumentor/type-resolver/src/Types/Null_.php
new file mode 100644
index 0000000..203b422
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Null_.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing a null value or type.
+ */
+final class Null_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'null';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Nullable.php b/vendor/phpdocumentor/type-resolver/src/Types/Nullable.php
new file mode 100644
index 0000000..3c6d1b1
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Nullable.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2017 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing a nullable type. The real type is wrapped.
+ */
+final class Nullable implements Type
+{
+ /**
+ * @var Type
+ */
+ private $realType;
+
+ /**
+ * Initialises this nullable type using the real type embedded
+ *
+ * @param Type $realType
+ */
+ public function __construct(Type $realType)
+ {
+ $this->realType = $realType;
+ }
+
+ /**
+ * Provide access to the actual type directly, if needed.
+ *
+ * @return Type
+ */
+ public function getActualType()
+ {
+ return $this->realType;
+ }
+
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '?' . $this->realType->__toString();
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Object_.php b/vendor/phpdocumentor/type-resolver/src/Types/Object_.php
new file mode 100644
index 0000000..389f7c7
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Object_.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Fqsen;
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing an object.
+ *
+ * An object can be either typed or untyped. When an object is typed it means that it has an identifier, the FQSEN,
+ * pointing to an element in PHP. Object types that are untyped do not refer to a specific class but represent objects
+ * in general.
+ */
+final class Object_ implements Type
+{
+ /** @var Fqsen|null */
+ private $fqsen;
+
+ /**
+ * Initializes this object with an optional FQSEN, if not provided this object is considered 'untyped'.
+ *
+ * @param Fqsen $fqsen
+ * @throws \InvalidArgumentException when provided $fqsen is not a valid type.
+ */
+ public function __construct(Fqsen $fqsen = null)
+ {
+ if (strpos((string)$fqsen, '::') !== false || strpos((string)$fqsen, '()') !== false) {
+ throw new \InvalidArgumentException(
+ 'Object types can only refer to a class, interface or trait but a method, function, constant or '
+ . 'property was received: ' . (string)$fqsen
+ );
+ }
+
+ $this->fqsen = $fqsen;
+ }
+
+ /**
+ * Returns the FQSEN associated with this object.
+ *
+ * @return Fqsen|null
+ */
+ public function getFqsen()
+ {
+ return $this->fqsen;
+ }
+
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ if ($this->fqsen) {
+ return (string)$this->fqsen;
+ }
+
+ return 'object';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Parent_.php b/vendor/phpdocumentor/type-resolver/src/Types/Parent_.php
new file mode 100644
index 0000000..aabdbfb
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Parent_.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing the 'parent' type.
+ *
+ * Parent, as a Type, represents the parent class of class in which the associated element was defined.
+ */
+final class Parent_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'parent';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Resource_.php b/vendor/phpdocumentor/type-resolver/src/Types/Resource_.php
new file mode 100644
index 0000000..a1b613d
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Resource_.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing the 'resource' Type.
+ */
+final class Resource_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'resource';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Scalar.php b/vendor/phpdocumentor/type-resolver/src/Types/Scalar.php
new file mode 100644
index 0000000..1e2a660
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Scalar.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing the 'scalar' pseudo-type, which is either a string, integer, float or boolean.
+ */
+final class Scalar implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'scalar';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Self_.php b/vendor/phpdocumentor/type-resolver/src/Types/Self_.php
new file mode 100644
index 0000000..1ba3fc5
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Self_.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing the 'self' type.
+ *
+ * Self, as a Type, represents the class in which the associated element was defined.
+ */
+final class Self_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'self';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Static_.php b/vendor/phpdocumentor/type-resolver/src/Types/Static_.php
new file mode 100644
index 0000000..9eb6729
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Static_.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing the 'static' type.
+ *
+ * Self, as a Type, represents the class in which the associated element was called. This differs from self as self does
+ * not take inheritance into account but static means that the return type is always that of the class of the called
+ * element.
+ *
+ * See the documentation on late static binding in the PHP Documentation for more information on the difference between
+ * static and self.
+ */
+final class Static_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'static';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/String_.php b/vendor/phpdocumentor/type-resolver/src/Types/String_.php
new file mode 100644
index 0000000..8db5968
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/String_.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing the type 'string'.
+ */
+final class String_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'string';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/This.php b/vendor/phpdocumentor/type-resolver/src/Types/This.php
new file mode 100644
index 0000000..c098a93
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/This.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing the '$this' pseudo-type.
+ *
+ * $this, as a Type, represents the instance of the class associated with the element as it was called. $this is
+ * commonly used when documenting fluent interfaces since it represents that the same object is returned.
+ */
+final class This implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '$this';
+ }
+}
diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Void_.php b/vendor/phpdocumentor/type-resolver/src/Types/Void_.php
new file mode 100644
index 0000000..3d1be27
--- /dev/null
+++ b/vendor/phpdocumentor/type-resolver/src/Types/Void_.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\Types;
+
+use phpDocumentor\Reflection\Type;
+
+/**
+ * Value Object representing the pseudo-type 'void'.
+ *
+ * Void is generally only used when working with return types as it signifies that the method intentionally does not
+ * return any value.
+ */
+final class Void_ implements Type
+{
+ /**
+ * Returns a rendered output of the Type as it would be used in a DocBlock.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'void';
+ }
+}
diff --git a/vendor/phpspec/prophecy/CHANGES.md b/vendor/phpspec/prophecy/CHANGES.md
new file mode 100644
index 0000000..fddfc41
--- /dev/null
+++ b/vendor/phpspec/prophecy/CHANGES.md
@@ -0,0 +1,213 @@
+1.8.0 / 2018/08/05
+==================
+
+* Support for void return types without explicit will (@crellbar)
+* Clearer error message for unexpected method calls (@meridius)
+* Clearer error message for aggregate exceptions (@meridius)
+* More verbose `shouldBeCalledOnce` expectation (@olvlvl)
+* Ability to double Throwable, or methods that extend it (@ciaranmcnulty)
+* [fixed] Doubling methods where class has additional arguments to interface (@webimpress)
+* [fixed] Doubling methods where arguments are nullable but default is not null (@webimpress)
+* [fixed] Doubling magic methods on parent class (@dsnopek)
+* [fixed] Check method predictions only once (@dontub)
+* [fixed] Argument::containingString throwing error when called with non-string (@dcabrejas)
+
+1.7.6 / 2018/04/18
+==================
+
+* Allow sebastian/comparator ^3.0 (@sebastianbergmann)
+
+1.7.5 / 2018/02/11
+==================
+
+* Support for object return type hints (thanks @greg0ire)
+
+1.7.4 / 2018/02/11
+==================
+
+* Fix issues with PHP 7.2 (thanks @greg0ire)
+* Support object type hints in PHP 7.2 (thanks @@jansvoboda11)
+
+1.7.3 / 2017/11/24
+==================
+
+* Fix SplInfo ClassPatch to work with Symfony 4 (Thanks @gnugat)
+
+1.7.2 / 2017-10-04
+==================
+
+* Reverted "check method predictions only once" due to it breaking Spies
+
+1.7.1 / 2017-10-03
+==================
+
+* Allow PHP5 keywords methods generation on PHP7 (thanks @bycosta)
+* Allow reflection-docblock v4 (thanks @GrahamCampbell)
+* Check method predictions only once (thanks @dontub)
+* Escape file path sent to \SplFileObjectConstructor when running on Windows (thanks @danmartin-epiphany)
+
+1.7.0 / 2017-03-02
+==================
+
+* Add full PHP 7.1 Support (thanks @prolic)
+* Allow `sebastian/comparator ^2.0` (thanks @sebastianbergmann)
+* Allow `sebastian/recursion-context ^3.0` (thanks @sebastianbergmann)
+* Allow `\Error` instances in `ThrowPromise` (thanks @jameshalsall)
+* Support `phpspec/phpspect ^3.2` (thanks @Sam-Burns)
+* Fix failing builds (thanks @Sam-Burns)
+
+1.6.2 / 2016-11-21
+==================
+
+* Added support for detecting @method on interfaces that the class itself implements, or when the stubbed class is an interface itself (thanks @Seldaek)
+* Added support for sebastian/recursion-context 2 (thanks @sebastianbergmann)
+* Added testing on PHP 7.1 on Travis (thanks @danizord)
+* Fixed the usage of the phpunit comparator (thanks @Anyqax)
+
+1.6.1 / 2016-06-07
+==================
+
+ * Ignored empty method names in invalid `@method` phpdoc
+ * Fixed the mocking of SplFileObject
+ * Added compatibility with phpdocumentor/reflection-docblock 3
+
+1.6.0 / 2016-02-15
+==================
+
+ * Add Variadics support (thanks @pamil)
+ * Add ProphecyComparator for comparing objects that need revealing (thanks @jon-acker)
+ * Add ApproximateValueToken (thanks @dantleech)
+ * Add support for 'self' and 'parent' return type (thanks @bendavies)
+ * Add __invoke to allowed reflectable methods list (thanks @ftrrtf)
+ * Updated ExportUtil to reflect the latest changes by Sebastian (thanks @jakari)
+ * Specify the required php version for composer (thanks @jakzal)
+ * Exclude 'args' in the generated backtrace (thanks @oradwell)
+ * Fix code generation for scalar parameters (thanks @trowski)
+ * Fix missing sprintf in InvalidArgumentException __construct call (thanks @emmanuelballery)
+ * Fix phpdoc for magic methods (thanks @Tobion)
+ * Fix PhpDoc for interfaces usage (thanks @ImmRanneft)
+ * Prevent final methods from being manually extended (thanks @kamioftea)
+ * Enhance exception for invalid argument to ThrowPromise (thanks @Tobion)
+
+1.5.0 / 2015-04-27
+==================
+
+ * Add support for PHP7 scalar type hints (thanks @trowski)
+ * Add support for PHP7 return types (thanks @trowski)
+ * Update internal test suite to support PHP7
+
+1.4.1 / 2015-04-27
+==================
+
+ * Fixed bug in closure-based argument tokens (#181)
+
+1.4.0 / 2015-03-27
+==================
+
+ * Fixed errors in return type phpdocs (thanks @sobit)
+ * Fixed stringifying of hash containing one value (thanks @avant1)
+ * Improved clarity of method call expectation exception (thanks @dantleech)
+ * Add ability to specify which argument is returned in willReturnArgument (thanks @coderbyheart)
+ * Add more information to MethodNotFound exceptions (thanks @ciaranmcnulty)
+ * Support for mocking classes with methods that return references (thanks @edsonmedina)
+ * Improved object comparison (thanks @whatthejeff)
+ * Adopted '^' in composer dependencies (thanks @GrahamCampbell)
+ * Fixed non-typehinted arguments being treated as optional (thanks @whatthejeff)
+ * Magic methods are now filtered for keywords (thanks @seagoj)
+ * More readable errors for failure when expecting single calls (thanks @dantleech)
+
+1.3.1 / 2014-11-17
+==================
+
+ * Fix the edge case when failed predictions weren't recorded for `getCheckedPredictions()`
+
+1.3.0 / 2014-11-14
+==================
+
+ * Add a way to get checked predictions with `MethodProphecy::getCheckedPredictions()`
+ * Fix HHVM compatibility
+ * Remove dead code (thanks @stof)
+ * Add support for DirectoryIterators (thanks @shanethehat)
+
+1.2.0 / 2014-07-18
+==================
+
+ * Added support for doubling magic methods documented in the class phpdoc (thanks @armetiz)
+ * Fixed a segfault appearing in some cases (thanks @dmoreaulf)
+ * Fixed the doubling of methods with typehints on non-existent classes (thanks @gquemener)
+ * Added support for internal classes using keywords as method names (thanks @milan)
+ * Added IdenticalValueToken and Argument::is (thanks @florianv)
+ * Removed the usage of scalar typehints in HHVM as HHVM 3 does not support them anymore in PHP code (thanks @whatthejeff)
+
+1.1.2 / 2014-01-24
+==================
+
+ * Spy automatically promotes spied method call to an expected one
+
+1.1.1 / 2014-01-15
+==================
+
+ * Added support for HHVM
+
+1.1.0 / 2014-01-01
+==================
+
+ * Changed the generated class names to use a static counter instead of a random number
+ * Added a clss patch for ReflectionClass::newInstance to make its argument optional consistently (thanks @docteurklein)
+ * Fixed mirroring of classes with typehints on non-existent classes (thanks @docteurklein)
+ * Fixed the support of array callables in CallbackPromise and CallbackPrediction (thanks @ciaranmcnulty)
+ * Added support for properties in ObjectStateToken (thanks @adrienbrault)
+ * Added support for mocking classes with a final constructor (thanks @ciaranmcnulty)
+ * Added ArrayEveryEntryToken and Argument::withEveryEntry() (thanks @adrienbrault)
+ * Added an exception when trying to prophesize on a final method instead of ignoring silently (thanks @docteurklein)
+ * Added StringContainToken and Argument::containingString() (thanks @peterjmit)
+ * Added ``shouldNotHaveBeenCalled`` on the MethodProphecy (thanks @ciaranmcnulty)
+ * Fixed the comparison of objects in ExactValuetoken (thanks @sstok)
+ * Deprecated ``shouldNotBeenCalled`` in favor of ``shouldNotHaveBeenCalled``
+
+1.0.4 / 2013-08-10
+==================
+
+ * Better randomness for generated class names (thanks @sstok)
+ * Add support for interfaces into TypeToken and Argument::type() (thanks @sstok)
+ * Add support for old-style (method name === class name) constructors (thanks @l310 for report)
+
+1.0.3 / 2013-07-04
+==================
+
+ * Support callable typehints (thanks @stof)
+ * Do not attempt to autoload arrays when generating code (thanks @MarcoDeBortoli)
+ * New ArrayEntryToken (thanks @kagux)
+
+1.0.2 / 2013-05-19
+==================
+
+ * Logical `AND` token added (thanks @kagux)
+ * Logical `NOT` token added (thanks @kagux)
+ * Add support for setting custom constructor arguments
+ * Properly stringify hashes
+ * Record calls that throw exceptions
+ * Migrate spec suite to PhpSpec 2.0
+
+1.0.1 / 2013-04-30
+==================
+
+ * Fix broken UnexpectedCallException message
+ * Trim AggregateException message
+
+1.0.0 / 2013-04-29
+==================
+
+ * Improve exception messages
+
+1.0.0-BETA2 / 2013-04-03
+========================
+
+ * Add more debug information to CallTimes and Call prediction exception messages
+ * Fix MethodNotFoundException wrong namespace (thanks @gunnarlium)
+ * Fix some typos in the exception messages (thanks @pborreli)
+
+1.0.0-BETA1 / 2013-03-25
+========================
+
+ * Initial release
diff --git a/vendor/phpspec/prophecy/LICENSE b/vendor/phpspec/prophecy/LICENSE
new file mode 100644
index 0000000..c8b3647
--- /dev/null
+++ b/vendor/phpspec/prophecy/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2013 Konstantin Kudryashov <ever.zet@gmail.com>
+ Marcello Duarte <marcello.duarte@gmail.com>
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/phpspec/prophecy/README.md b/vendor/phpspec/prophecy/README.md
new file mode 100644
index 0000000..b190d43
--- /dev/null
+++ b/vendor/phpspec/prophecy/README.md
@@ -0,0 +1,391 @@
+# Prophecy
+
+[![Stable release](https://poser.pugx.org/phpspec/prophecy/version.svg)](https://packagist.org/packages/phpspec/prophecy)
+[![Build Status](https://travis-ci.org/phpspec/prophecy.svg?branch=master)](https://travis-ci.org/phpspec/prophecy)
+
+Prophecy is a highly opinionated yet very powerful and flexible PHP object mocking
+framework. Though initially it was created to fulfil phpspec2 needs, it is flexible
+enough to be used inside any testing framework out there with minimal effort.
+
+## A simple example
+
+```php
+<?php
+
+class UserTest extends PHPUnit_Framework_TestCase
+{
+ private $prophet;
+
+ public function testPasswordHashing()
+ {
+ $hasher = $this->prophet->prophesize('App\Security\Hasher');
+ $user = new App\Entity\User($hasher->reveal());
+
+ $hasher->generateHash($user, 'qwerty')->willReturn('hashed_pass');
+
+ $user->setPassword('qwerty');
+
+ $this->assertEquals('hashed_pass', $user->getPassword());
+ }
+
+ protected function setup()
+ {
+ $this->prophet = new \Prophecy\Prophet;
+ }
+
+ protected function tearDown()
+ {
+ $this->prophet->checkPredictions();
+ }
+}
+```
+
+## Installation
+
+### Prerequisites
+
+Prophecy requires PHP 5.3.3 or greater.
+
+### Setup through composer
+
+First, add Prophecy to the list of dependencies inside your `composer.json`:
+
+```json
+{
+ "require-dev": {
+ "phpspec/prophecy": "~1.0"
+ }
+}
+```
+
+Then simply install it with composer:
+
+```bash
+$> composer install --prefer-dist
+```
+
+You can read more about Composer on its [official webpage](http://getcomposer.org).
+
+## How to use it
+
+First of all, in Prophecy every word has a logical meaning, even the name of the library
+itself (Prophecy). When you start feeling that, you'll become very fluid with this
+tool.
+
+For example, Prophecy has been named that way because it concentrates on describing the future
+behavior of objects with very limited knowledge about them. But as with any other prophecy,
+those object prophecies can't create themselves - there should be a Prophet:
+
+```php
+$prophet = new Prophecy\Prophet;
+```
+
+The Prophet creates prophecies by *prophesizing* them:
+
+```php
+$prophecy = $prophet->prophesize();
+```
+
+The result of the `prophesize()` method call is a new object of class `ObjectProphecy`. Yes,
+that's your specific object prophecy, which describes how your object would behave
+in the near future. But first, you need to specify which object you're talking about,
+right?
+
+```php
+$prophecy->willExtend('stdClass');
+$prophecy->willImplement('SessionHandlerInterface');
+```
+
+There are 2 interesting calls - `willExtend` and `willImplement`. The first one tells
+object prophecy that our object should extend specific class, the second one says that
+it should implement some interface. Obviously, objects in PHP can implement multiple
+interfaces, but extend only one parent class.
+
+### Dummies
+
+Ok, now we have our object prophecy. What can we do with it? First of all, we can get
+our object *dummy* by revealing its prophecy:
+
+```php
+$dummy = $prophecy->reveal();
+```
+
+The `$dummy` variable now holds a special dummy object. Dummy objects are objects that extend
+and/or implement preset classes/interfaces by overriding all their public methods. The key
+point about dummies is that they do not hold any logic - they just do nothing. Any method
+of the dummy will always return `null` and the dummy will never throw any exceptions.
+Dummy is your friend if you don't care about the actual behavior of this double and just need
+a token object to satisfy a method typehint.
+
+You need to understand one thing - a dummy is not a prophecy. Your object prophecy is still
+assigned to `$prophecy` variable and in order to manipulate with your expectations, you
+should work with it. `$dummy` is a dummy - a simple php object that tries to fulfil your
+prophecy.
+
+### Stubs
+
+Ok, now we know how to create basic prophecies and reveal dummies from them. That's
+awesome if we don't care about our _doubles_ (objects that reflect originals)
+interactions. If we do, we need to use *stubs* or *mocks*.
+
+A stub is an object double, which doesn't have any expectations about the object behavior,
+but when put in specific environment, behaves in specific way. Ok, I know, it's cryptic,
+but bear with me for a minute. Simply put, a stub is a dummy, which depending on the called
+method signature does different things (has logic). To create stubs in Prophecy:
+
+```php
+$prophecy->read('123')->willReturn('value');
+```
+
+Oh wow. We've just made an arbitrary call on the object prophecy? Yes, we did. And this
+call returned us a new object instance of class `MethodProphecy`. Yep, that's a specific
+method with arguments prophecy. Method prophecies give you the ability to create method
+promises or predictions. We'll talk about method predictions later in the _Mocks_ section.
+
+#### Promises
+
+Promises are logical blocks, that represent your fictional methods in prophecy terms
+and they are handled by the `MethodProphecy::will(PromiseInterface $promise)` method.
+As a matter of fact, the call that we made earlier (`willReturn('value')`) is a simple
+shortcut to:
+
+```php
+$prophecy->read('123')->will(new Prophecy\Promise\ReturnPromise(array('value')));
+```
+
+This promise will cause any call to our double's `read()` method with exactly one
+argument - `'123'` to always return `'value'`. But that's only for this
+promise, there's plenty others you can use:
+
+- `ReturnPromise` or `->willReturn(1)` - returns a value from a method call
+- `ReturnArgumentPromise` or `->willReturnArgument($index)` - returns the nth method argument from call
+- `ThrowPromise` or `->willThrow($exception)` - causes the method to throw specific exception
+- `CallbackPromise` or `->will($callback)` - gives you a quick way to define your own custom logic
+
+Keep in mind, that you can always add even more promises by implementing
+`Prophecy\Promise\PromiseInterface`.
+
+#### Method prophecies idempotency
+
+Prophecy enforces same method prophecies and, as a consequence, same promises and
+predictions for the same method calls with the same arguments. This means:
+
+```php
+$methodProphecy1 = $prophecy->read('123');
+$methodProphecy2 = $prophecy->read('123');
+$methodProphecy3 = $prophecy->read('321');
+
+$methodProphecy1 === $methodProphecy2;
+$methodProphecy1 !== $methodProphecy3;
+```
+
+That's interesting, right? Now you might ask me how would you define more complex
+behaviors where some method call changes behavior of others. In PHPUnit or Mockery
+you do that by predicting how many times your method will be called. In Prophecy,
+you'll use promises for that:
+
+```php
+$user->getName()->willReturn(null);
+
+// For PHP 5.4
+$user->setName('everzet')->will(function () {
+ $this->getName()->willReturn('everzet');
+});
+
+// For PHP 5.3
+$user->setName('everzet')->will(function ($args, $user) {
+ $user->getName()->willReturn('everzet');
+});
+
+// Or
+$user->setName('everzet')->will(function ($args) use ($user) {
+ $user->getName()->willReturn('everzet');
+});
+```
+
+And now it doesn't matter how many times or in which order your methods are called.
+What matters is their behaviors and how well you faked it.
+
+#### Arguments wildcarding
+
+The previous example is awesome (at least I hope it is for you), but that's not
+optimal enough. We hardcoded `'everzet'` in our expectation. Isn't there a better
+way? In fact there is, but it involves understanding what this `'everzet'`
+actually is.
+
+You see, even if method arguments used during method prophecy creation look
+like simple method arguments, in reality they are not. They are argument token
+wildcards. As a matter of fact, `->setName('everzet')` looks like a simple call just
+because Prophecy automatically transforms it under the hood into:
+
+```php
+$user->setName(new Prophecy\Argument\Token\ExactValueToken('everzet'));
+```
+
+Those argument tokens are simple PHP classes, that implement
+`Prophecy\Argument\Token\TokenInterface` and tell Prophecy how to compare real arguments
+with your expectations. And yes, those classnames are damn big. That's why there's a
+shortcut class `Prophecy\Argument`, which you can use to create tokens like that:
+
+```php
+use Prophecy\Argument;
+
+$user->setName(Argument::exact('everzet'));
+```
+
+`ExactValueToken` is not very useful in our case as it forced us to hardcode the username.
+That's why Prophecy comes bundled with a bunch of other tokens:
+
+- `IdenticalValueToken` or `Argument::is($value)` - checks that the argument is identical to a specific value
+- `ExactValueToken` or `Argument::exact($value)` - checks that the argument matches a specific value
+- `TypeToken` or `Argument::type($typeOrClass)` - checks that the argument matches a specific type or
+ classname
+- `ObjectStateToken` or `Argument::which($method, $value)` - checks that the argument method returns
+ a specific value
+- `CallbackToken` or `Argument::that(callback)` - checks that the argument matches a custom callback
+- `AnyValueToken` or `Argument::any()` - matches any argument
+- `AnyValuesToken` or `Argument::cetera()` - matches any arguments to the rest of the signature
+- `StringContainsToken` or `Argument::containingString($value)` - checks that the argument contains a specific string value
+
+And you can add even more by implementing `TokenInterface` with your own custom classes.
+
+So, let's refactor our initial `{set,get}Name()` logic with argument tokens:
+
+```php
+use Prophecy\Argument;
+
+$user->getName()->willReturn(null);
+
+// For PHP 5.4
+$user->setName(Argument::type('string'))->will(function ($args) {
+ $this->getName()->willReturn($args[0]);
+});
+
+// For PHP 5.3
+$user->setName(Argument::type('string'))->will(function ($args, $user) {
+ $user->getName()->willReturn($args[0]);
+});
+
+// Or
+$user->setName(Argument::type('string'))->will(function ($args) use ($user) {
+ $user->getName()->willReturn($args[0]);
+});
+```
+
+That's it. Now our `{set,get}Name()` prophecy will work with any string argument provided to it.
+We've just described how our stub object should behave, even though the original object could have
+no behavior whatsoever.
+
+One last bit about arguments now. You might ask, what happens in case of:
+
+```php
+use Prophecy\Argument;
+
+$user->getName()->willReturn(null);
+
+// For PHP 5.4
+$user->setName(Argument::type('string'))->will(function ($args) {
+ $this->getName()->willReturn($args[0]);
+});
+
+// For PHP 5.3
+$user->setName(Argument::type('string'))->will(function ($args, $user) {
+ $user->getName()->willReturn($args[0]);
+});
+
+// Or
+$user->setName(Argument::type('string'))->will(function ($args) use ($user) {
+ $user->getName()->willReturn($args[0]);
+});
+
+$user->setName(Argument::any())->will(function () {
+});
+```
+
+Nothing. Your stub will continue behaving the way it did before. That's because of how
+arguments wildcarding works. Every argument token type has a different score level, which
+wildcard then uses to calculate the final arguments match score and use the method prophecy
+promise that has the highest score. In this case, `Argument::type()` in case of success
+scores `5` and `Argument::any()` scores `3`. So the type token wins, as does the first
+`setName()` method prophecy and its promise. The simple rule of thumb - more precise token
+always wins.
+
+#### Getting stub objects
+
+Ok, now we know how to define our prophecy method promises, let's get our stub from
+it:
+
+```php
+$stub = $prophecy->reveal();
+```
+
+As you might see, the only difference between how we get dummies and stubs is that with
+stubs we describe every object conversation instead of just agreeing with `null` returns
+(object being *dummy*). As a matter of fact, after you define your first promise
+(method call), Prophecy will force you to define all the communications - it throws
+the `UnexpectedCallException` for any call you didn't describe with object prophecy before
+calling it on a stub.
+
+### Mocks
+
+Now we know how to define doubles without behavior (dummies) and doubles with behavior, but
+no expectations (stubs). What's left is doubles for which we have some expectations. These
+are called mocks and in Prophecy they look almost exactly the same as stubs, except that
+they define *predictions* instead of *promises* on method prophecies:
+
+```php
+$entityManager->flush()->shouldBeCalled();
+```
+
+#### Predictions
+
+The `shouldBeCalled()` method here assigns `CallPrediction` to our method prophecy.
+Predictions are a delayed behavior check for your prophecies. You see, during the entire lifetime
+of your doubles, Prophecy records every single call you're making against it inside your
+code. After that, Prophecy can use this collected information to check if it matches defined
+predictions. You can assign predictions to method prophecies using the
+`MethodProphecy::should(PredictionInterface $prediction)` method. As a matter of fact,
+the `shouldBeCalled()` method we used earlier is just a shortcut to:
+
+```php
+$entityManager->flush()->should(new Prophecy\Prediction\CallPrediction());
+```
+
+It checks if your method of interest (that matches both the method name and the arguments wildcard)
+was called 1 or more times. If the prediction failed then it throws an exception. When does this
+check happen? Whenever you call `checkPredictions()` on the main Prophet object:
+
+```php
+$prophet->checkPredictions();
+```
+
+In PHPUnit, you would want to put this call into the `tearDown()` method. If no predictions
+are defined, it would do nothing. So it won't harm to call it after every test.
+
+There are plenty more predictions you can play with:
+
+- `CallPrediction` or `shouldBeCalled()` - checks that the method has been called 1 or more times
+- `NoCallsPrediction` or `shouldNotBeCalled()` - checks that the method has not been called
+- `CallTimesPrediction` or `shouldBeCalledTimes($count)` - checks that the method has been called
+ `$count` times
+- `CallbackPrediction` or `should($callback)` - checks the method against your own custom callback
+
+Of course, you can always create your own custom prediction any time by implementing
+`PredictionInterface`.
+
+### Spies
+
+The last bit of awesomeness in Prophecy is out-of-the-box spies support. As I said in the previous
+section, Prophecy records every call made during the double's entire lifetime. This means
+you don't need to record predictions in order to check them. You can also do it
+manually by using the `MethodProphecy::shouldHave(PredictionInterface $prediction)` method:
+
+```php
+$em = $prophet->prophesize('Doctrine\ORM\EntityManager');
+
+$controller->createUser($em->reveal());
+
+$em->flush()->shouldHaveBeenCalled();
+```
+
+Such manipulation with doubles is called spying. And with Prophecy it just works.
diff --git a/vendor/phpspec/prophecy/composer.json b/vendor/phpspec/prophecy/composer.json
new file mode 100644
index 0000000..816f147
--- /dev/null
+++ b/vendor/phpspec/prophecy/composer.json
@@ -0,0 +1,50 @@
+{
+ "name": "phpspec/prophecy",
+ "description": "Highly opinionated mocking framework for PHP 5.3+",
+ "keywords": ["Mock", "Stub", "Dummy", "Double", "Fake", "Spy"],
+ "homepage": "https://github.com/phpspec/prophecy",
+ "type": "library",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com",
+ "homepage": "http://everzet.com"
+ },
+ {
+ "name": "Marcello Duarte",
+ "email": "marcello.duarte@gmail.com"
+ }
+ ],
+
+ "require": {
+ "php": "^5.3|^7.0",
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
+ "sebastian/comparator": "^1.1|^2.0|^3.0",
+ "doctrine/instantiator": "^1.0.2",
+ "sebastian/recursion-context": "^1.0|^2.0|^3.0"
+ },
+
+ "require-dev": {
+ "phpspec/phpspec": "^2.5|^3.2",
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
+ },
+
+ "autoload": {
+ "psr-0": {
+ "Prophecy\\": "src/"
+ }
+ },
+
+ "autoload-dev": {
+ "psr-4": {
+ "Fixtures\\Prophecy\\": "fixtures"
+ }
+ },
+
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.8.x-dev"
+ }
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument.php b/vendor/phpspec/prophecy/src/Prophecy/Argument.php
new file mode 100644
index 0000000..fde6aa9
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument.php
@@ -0,0 +1,212 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy;
+
+use Prophecy\Argument\Token;
+
+/**
+ * Argument tokens shortcuts.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class Argument
+{
+ /**
+ * Checks that argument is exact value or object.
+ *
+ * @param mixed $value
+ *
+ * @return Token\ExactValueToken
+ */
+ public static function exact($value)
+ {
+ return new Token\ExactValueToken($value);
+ }
+
+ /**
+ * Checks that argument is of specific type or instance of specific class.
+ *
+ * @param string $type Type name (`integer`, `string`) or full class name
+ *
+ * @return Token\TypeToken
+ */
+ public static function type($type)
+ {
+ return new Token\TypeToken($type);
+ }
+
+ /**
+ * Checks that argument object has specific state.
+ *
+ * @param string $methodName
+ * @param mixed $value
+ *
+ * @return Token\ObjectStateToken
+ */
+ public static function which($methodName, $value)
+ {
+ return new Token\ObjectStateToken($methodName, $value);
+ }
+
+ /**
+ * Checks that argument matches provided callback.
+ *
+ * @param callable $callback
+ *
+ * @return Token\CallbackToken
+ */
+ public static function that($callback)
+ {
+ return new Token\CallbackToken($callback);
+ }
+
+ /**
+ * Matches any single value.
+ *
+ * @return Token\AnyValueToken
+ */
+ public static function any()
+ {
+ return new Token\AnyValueToken;
+ }
+
+ /**
+ * Matches all values to the rest of the signature.
+ *
+ * @return Token\AnyValuesToken
+ */
+ public static function cetera()
+ {
+ return new Token\AnyValuesToken;
+ }
+
+ /**
+ * Checks that argument matches all tokens
+ *
+ * @param mixed ... a list of tokens
+ *
+ * @return Token\LogicalAndToken
+ */
+ public static function allOf()
+ {
+ return new Token\LogicalAndToken(func_get_args());
+ }
+
+ /**
+ * Checks that argument array or countable object has exact number of elements.
+ *
+ * @param integer $value array elements count
+ *
+ * @return Token\ArrayCountToken
+ */
+ public static function size($value)
+ {
+ return new Token\ArrayCountToken($value);
+ }
+
+ /**
+ * Checks that argument array contains (key, value) pair
+ *
+ * @param mixed $key exact value or token
+ * @param mixed $value exact value or token
+ *
+ * @return Token\ArrayEntryToken
+ */
+ public static function withEntry($key, $value)
+ {
+ return new Token\ArrayEntryToken($key, $value);
+ }
+
+ /**
+ * Checks that arguments array entries all match value
+ *
+ * @param mixed $value
+ *
+ * @return Token\ArrayEveryEntryToken
+ */
+ public static function withEveryEntry($value)
+ {
+ return new Token\ArrayEveryEntryToken($value);
+ }
+
+ /**
+ * Checks that argument array contains value
+ *
+ * @param mixed $value
+ *
+ * @return Token\ArrayEntryToken
+ */
+ public static function containing($value)
+ {
+ return new Token\ArrayEntryToken(self::any(), $value);
+ }
+
+ /**
+ * Checks that argument array has key
+ *
+ * @param mixed $key exact value or token
+ *
+ * @return Token\ArrayEntryToken
+ */
+ public static function withKey($key)
+ {
+ return new Token\ArrayEntryToken($key, self::any());
+ }
+
+ /**
+ * Checks that argument does not match the value|token.
+ *
+ * @param mixed $value either exact value or argument token
+ *
+ * @return Token\LogicalNotToken
+ */
+ public static function not($value)
+ {
+ return new Token\LogicalNotToken($value);
+ }
+
+ /**
+ * @param string $value
+ *
+ * @return Token\StringContainsToken
+ */
+ public static function containingString($value)
+ {
+ return new Token\StringContainsToken($value);
+ }
+
+ /**
+ * Checks that argument is identical value.
+ *
+ * @param mixed $value
+ *
+ * @return Token\IdenticalValueToken
+ */
+ public static function is($value)
+ {
+ return new Token\IdenticalValueToken($value);
+ }
+
+ /**
+ * Check that argument is same value when rounding to the
+ * given precision.
+ *
+ * @param float $value
+ * @param float $precision
+ *
+ * @return Token\ApproximateValueToken
+ */
+ public static function approximate($value, $precision = 0)
+ {
+ return new Token\ApproximateValueToken($value, $precision);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php
new file mode 100644
index 0000000..a088f21
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php
@@ -0,0 +1,101 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument;
+
+/**
+ * Arguments wildcarding.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ArgumentsWildcard
+{
+ /**
+ * @var Token\TokenInterface[]
+ */
+ private $tokens = array();
+ private $string;
+
+ /**
+ * Initializes wildcard.
+ *
+ * @param array $arguments Array of argument tokens or values
+ */
+ public function __construct(array $arguments)
+ {
+ foreach ($arguments as $argument) {
+ if (!$argument instanceof Token\TokenInterface) {
+ $argument = new Token\ExactValueToken($argument);
+ }
+
+ $this->tokens[] = $argument;
+ }
+ }
+
+ /**
+ * Calculates wildcard match score for provided arguments.
+ *
+ * @param array $arguments
+ *
+ * @return false|int False OR integer score (higher - better)
+ */
+ public function scoreArguments(array $arguments)
+ {
+ if (0 == count($arguments) && 0 == count($this->tokens)) {
+ return 1;
+ }
+
+ $arguments = array_values($arguments);
+ $totalScore = 0;
+ foreach ($this->tokens as $i => $token) {
+ $argument = isset($arguments[$i]) ? $arguments[$i] : null;
+ if (1 >= $score = $token->scoreArgument($argument)) {
+ return false;
+ }
+
+ $totalScore += $score;
+
+ if (true === $token->isLast()) {
+ return $totalScore;
+ }
+ }
+
+ if (count($arguments) > count($this->tokens)) {
+ return false;
+ }
+
+ return $totalScore;
+ }
+
+ /**
+ * Returns string representation for wildcard.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ if (null === $this->string) {
+ $this->string = implode(', ', array_map(function ($token) {
+ return (string) $token;
+ }, $this->tokens));
+ }
+
+ return $this->string;
+ }
+
+ /**
+ * @return array
+ */
+ public function getTokens()
+ {
+ return $this->tokens;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php
new file mode 100644
index 0000000..5098811
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+/**
+ * Any single value token.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class AnyValueToken implements TokenInterface
+{
+ /**
+ * Always scores 3 for any argument.
+ *
+ * @param $argument
+ *
+ * @return int
+ */
+ public function scoreArgument($argument)
+ {
+ return 3;
+ }
+
+ /**
+ * Returns false.
+ *
+ * @return bool
+ */
+ public function isLast()
+ {
+ return false;
+ }
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '*';
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php
new file mode 100644
index 0000000..f76b17b
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+/**
+ * Any values token.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class AnyValuesToken implements TokenInterface
+{
+ /**
+ * Always scores 2 for any argument.
+ *
+ * @param $argument
+ *
+ * @return int
+ */
+ public function scoreArgument($argument)
+ {
+ return 2;
+ }
+
+ /**
+ * Returns true to stop wildcard from processing other tokens.
+ *
+ * @return bool
+ */
+ public function isLast()
+ {
+ return true;
+ }
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '* [, ...]';
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ApproximateValueToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ApproximateValueToken.php
new file mode 100644
index 0000000..d4918b1
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ApproximateValueToken.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+/**
+ * Approximate value token
+ *
+ * @author Daniel Leech <daniel@dantleech.com>
+ */
+class ApproximateValueToken implements TokenInterface
+{
+ private $value;
+ private $precision;
+
+ public function __construct($value, $precision = 0)
+ {
+ $this->value = $value;
+ $this->precision = $precision;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function scoreArgument($argument)
+ {
+ return round($argument, $this->precision) === round($this->value, $this->precision) ? 10 : false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isLast()
+ {
+ return false;
+ }
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return sprintf('≅%s', round($this->value, $this->precision));
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php
new file mode 100644
index 0000000..96b4bef
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php
@@ -0,0 +1,86 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+/**
+ * Array elements count token.
+ *
+ * @author Boris Mikhaylov <kaguxmail@gmail.com>
+ */
+
+class ArrayCountToken implements TokenInterface
+{
+ private $count;
+
+ /**
+ * @param integer $value
+ */
+ public function __construct($value)
+ {
+ $this->count = $value;
+ }
+
+ /**
+ * Scores 6 when argument has preset number of elements.
+ *
+ * @param $argument
+ *
+ * @return bool|int
+ */
+ public function scoreArgument($argument)
+ {
+ return $this->isCountable($argument) && $this->hasProperCount($argument) ? 6 : false;
+ }
+
+ /**
+ * Returns false.
+ *
+ * @return boolean
+ */
+ public function isLast()
+ {
+ return false;
+ }
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return sprintf('count(%s)', $this->count);
+ }
+
+ /**
+ * Returns true if object is either array or instance of \Countable
+ *
+ * @param $argument
+ * @return bool
+ */
+ private function isCountable($argument)
+ {
+ return (is_array($argument) || $argument instanceof \Countable);
+ }
+
+ /**
+ * Returns true if $argument has expected number of elements
+ *
+ * @param array|\Countable $argument
+ *
+ * @return bool
+ */
+ private function hasProperCount($argument)
+ {
+ return $this->count === count($argument);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php
new file mode 100644
index 0000000..0305fc7
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php
@@ -0,0 +1,143 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+use Prophecy\Exception\InvalidArgumentException;
+
+/**
+ * Array entry token.
+ *
+ * @author Boris Mikhaylov <kaguxmail@gmail.com>
+ */
+class ArrayEntryToken implements TokenInterface
+{
+ /** @var \Prophecy\Argument\Token\TokenInterface */
+ private $key;
+ /** @var \Prophecy\Argument\Token\TokenInterface */
+ private $value;
+
+ /**
+ * @param mixed $key exact value or token
+ * @param mixed $value exact value or token
+ */
+ public function __construct($key, $value)
+ {
+ $this->key = $this->wrapIntoExactValueToken($key);
+ $this->value = $this->wrapIntoExactValueToken($value);
+ }
+
+ /**
+ * Scores half of combined scores from key and value tokens for same entry. Capped at 8.
+ * If argument implements \ArrayAccess without \Traversable, then key token is restricted to ExactValueToken.
+ *
+ * @param array|\ArrayAccess|\Traversable $argument
+ *
+ * @throws \Prophecy\Exception\InvalidArgumentException
+ * @return bool|int
+ */
+ public function scoreArgument($argument)
+ {
+ if ($argument instanceof \Traversable) {
+ $argument = iterator_to_array($argument);
+ }
+
+ if ($argument instanceof \ArrayAccess) {
+ $argument = $this->convertArrayAccessToEntry($argument);
+ }
+
+ if (!is_array($argument) || empty($argument)) {
+ return false;
+ }
+
+ $keyScores = array_map(array($this->key,'scoreArgument'), array_keys($argument));
+ $valueScores = array_map(array($this->value,'scoreArgument'), $argument);
+ $scoreEntry = function ($value, $key) {
+ return $value && $key ? min(8, ($key + $value) / 2) : false;
+ };
+
+ return max(array_map($scoreEntry, $valueScores, $keyScores));
+ }
+
+ /**
+ * Returns false.
+ *
+ * @return boolean
+ */
+ public function isLast()
+ {
+ return false;
+ }
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return sprintf('[..., %s => %s, ...]', $this->key, $this->value);
+ }
+
+ /**
+ * Returns key
+ *
+ * @return TokenInterface
+ */
+ public function getKey()
+ {
+ return $this->key;
+ }
+
+ /**
+ * Returns value
+ *
+ * @return TokenInterface
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /**
+ * Wraps non token $value into ExactValueToken
+ *
+ * @param $value
+ * @return TokenInterface
+ */
+ private function wrapIntoExactValueToken($value)
+ {
+ return $value instanceof TokenInterface ? $value : new ExactValueToken($value);
+ }
+
+ /**
+ * Converts instance of \ArrayAccess to key => value array entry
+ *
+ * @param \ArrayAccess $object
+ *
+ * @return array|null
+ * @throws \Prophecy\Exception\InvalidArgumentException
+ */
+ private function convertArrayAccessToEntry(\ArrayAccess $object)
+ {
+ if (!$this->key instanceof ExactValueToken) {
+ throw new InvalidArgumentException(sprintf(
+ 'You can only use exact value tokens to match key of ArrayAccess object'.PHP_EOL.
+ 'But you used `%s`.',
+ $this->key
+ ));
+ }
+
+ $key = $this->key->getValue();
+
+ return $object->offsetExists($key) ? array($key => $object[$key]) : array();
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php
new file mode 100644
index 0000000..5d41fa4
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+/**
+ * Array every entry token.
+ *
+ * @author Adrien Brault <adrien.brault@gmail.com>
+ */
+class ArrayEveryEntryToken implements TokenInterface
+{
+ /**
+ * @var TokenInterface
+ */
+ private $value;
+
+ /**
+ * @param mixed $value exact value or token
+ */
+ public function __construct($value)
+ {
+ if (!$value instanceof TokenInterface) {
+ $value = new ExactValueToken($value);
+ }
+
+ $this->value = $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function scoreArgument($argument)
+ {
+ if (!$argument instanceof \Traversable && !is_array($argument)) {
+ return false;
+ }
+
+ $scores = array();
+ foreach ($argument as $key => $argumentEntry) {
+ $scores[] = $this->value->scoreArgument($argumentEntry);
+ }
+
+ if (empty($scores) || in_array(false, $scores, true)) {
+ return false;
+ }
+
+ return array_sum($scores) / count($scores);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isLast()
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __toString()
+ {
+ return sprintf('[%s, ..., %s]', $this->value, $this->value);
+ }
+
+ /**
+ * @return TokenInterface
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php
new file mode 100644
index 0000000..f45ba20
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php
@@ -0,0 +1,75 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+use Prophecy\Exception\InvalidArgumentException;
+
+/**
+ * Callback-verified token.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class CallbackToken implements TokenInterface
+{
+ private $callback;
+
+ /**
+ * Initializes token.
+ *
+ * @param callable $callback
+ *
+ * @throws \Prophecy\Exception\InvalidArgumentException
+ */
+ public function __construct($callback)
+ {
+ if (!is_callable($callback)) {
+ throw new InvalidArgumentException(sprintf(
+ 'Callable expected as an argument to CallbackToken, but got %s.',
+ gettype($callback)
+ ));
+ }
+
+ $this->callback = $callback;
+ }
+
+ /**
+ * Scores 7 if callback returns true, false otherwise.
+ *
+ * @param $argument
+ *
+ * @return bool|int
+ */
+ public function scoreArgument($argument)
+ {
+ return call_user_func($this->callback, $argument) ? 7 : false;
+ }
+
+ /**
+ * Returns false.
+ *
+ * @return bool
+ */
+ public function isLast()
+ {
+ return false;
+ }
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return 'callback()';
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php
new file mode 100644
index 0000000..aa960f3
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php
@@ -0,0 +1,116 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+use SebastianBergmann\Comparator\ComparisonFailure;
+use Prophecy\Comparator\Factory as ComparatorFactory;
+use Prophecy\Util\StringUtil;
+
+/**
+ * Exact value token.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ExactValueToken implements TokenInterface
+{
+ private $value;
+ private $string;
+ private $util;
+ private $comparatorFactory;
+
+ /**
+ * Initializes token.
+ *
+ * @param mixed $value
+ * @param StringUtil $util
+ * @param ComparatorFactory $comparatorFactory
+ */
+ public function __construct($value, StringUtil $util = null, ComparatorFactory $comparatorFactory = null)
+ {
+ $this->value = $value;
+ $this->util = $util ?: new StringUtil();
+
+ $this->comparatorFactory = $comparatorFactory ?: ComparatorFactory::getInstance();
+ }
+
+ /**
+ * Scores 10 if argument matches preset value.
+ *
+ * @param $argument
+ *
+ * @return bool|int
+ */
+ public function scoreArgument($argument)
+ {
+ if (is_object($argument) && is_object($this->value)) {
+ $comparator = $this->comparatorFactory->getComparatorFor(
+ $argument, $this->value
+ );
+
+ try {
+ $comparator->assertEquals($argument, $this->value);
+ return 10;
+ } catch (ComparisonFailure $failure) {}
+ }
+
+ // If either one is an object it should be castable to a string
+ if (is_object($argument) xor is_object($this->value)) {
+ if (is_object($argument) && !method_exists($argument, '__toString')) {
+ return false;
+ }
+
+ if (is_object($this->value) && !method_exists($this->value, '__toString')) {
+ return false;
+ }
+ } elseif (is_numeric($argument) && is_numeric($this->value)) {
+ // noop
+ } elseif (gettype($argument) !== gettype($this->value)) {
+ return false;
+ }
+
+ return $argument == $this->value ? 10 : false;
+ }
+
+ /**
+ * Returns preset value against which token checks arguments.
+ *
+ * @return mixed
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /**
+ * Returns false.
+ *
+ * @return bool
+ */
+ public function isLast()
+ {
+ return false;
+ }
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ if (null === $this->string) {
+ $this->string = sprintf('exact(%s)', $this->util->stringify($this->value));
+ }
+
+ return $this->string;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php
new file mode 100644
index 0000000..0b6d23a
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php
@@ -0,0 +1,74 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+use Prophecy\Util\StringUtil;
+
+/**
+ * Identical value token.
+ *
+ * @author Florian Voutzinos <florian@voutzinos.com>
+ */
+class IdenticalValueToken implements TokenInterface
+{
+ private $value;
+ private $string;
+ private $util;
+
+ /**
+ * Initializes token.
+ *
+ * @param mixed $value
+ * @param StringUtil $util
+ */
+ public function __construct($value, StringUtil $util = null)
+ {
+ $this->value = $value;
+ $this->util = $util ?: new StringUtil();
+ }
+
+ /**
+ * Scores 11 if argument matches preset value.
+ *
+ * @param $argument
+ *
+ * @return bool|int
+ */
+ public function scoreArgument($argument)
+ {
+ return $argument === $this->value ? 11 : false;
+ }
+
+ /**
+ * Returns false.
+ *
+ * @return bool
+ */
+ public function isLast()
+ {
+ return false;
+ }
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ if (null === $this->string) {
+ $this->string = sprintf('identical(%s)', $this->util->stringify($this->value));
+ }
+
+ return $this->string;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php
new file mode 100644
index 0000000..4ee1b25
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+/**
+ * Logical AND token.
+ *
+ * @author Boris Mikhaylov <kaguxmail@gmail.com>
+ */
+class LogicalAndToken implements TokenInterface
+{
+ private $tokens = array();
+
+ /**
+ * @param array $arguments exact values or tokens
+ */
+ public function __construct(array $arguments)
+ {
+ foreach ($arguments as $argument) {
+ if (!$argument instanceof TokenInterface) {
+ $argument = new ExactValueToken($argument);
+ }
+ $this->tokens[] = $argument;
+ }
+ }
+
+ /**
+ * Scores maximum score from scores returned by tokens for this argument if all of them score.
+ *
+ * @param $argument
+ *
+ * @return bool|int
+ */
+ public function scoreArgument($argument)
+ {
+ if (0 === count($this->tokens)) {
+ return false;
+ }
+
+ $maxScore = 0;
+ foreach ($this->tokens as $token) {
+ $score = $token->scoreArgument($argument);
+ if (false === $score) {
+ return false;
+ }
+ $maxScore = max($score, $maxScore);
+ }
+
+ return $maxScore;
+ }
+
+ /**
+ * Returns false.
+ *
+ * @return boolean
+ */
+ public function isLast()
+ {
+ return false;
+ }
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return sprintf('bool(%s)', implode(' AND ', $this->tokens));
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php
new file mode 100644
index 0000000..623efa5
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+/**
+ * Logical NOT token.
+ *
+ * @author Boris Mikhaylov <kaguxmail@gmail.com>
+ */
+class LogicalNotToken implements TokenInterface
+{
+ /** @var \Prophecy\Argument\Token\TokenInterface */
+ private $token;
+
+ /**
+ * @param mixed $value exact value or token
+ */
+ public function __construct($value)
+ {
+ $this->token = $value instanceof TokenInterface? $value : new ExactValueToken($value);
+ }
+
+ /**
+ * Scores 4 when preset token does not match the argument.
+ *
+ * @param $argument
+ *
+ * @return bool|int
+ */
+ public function scoreArgument($argument)
+ {
+ return false === $this->token->scoreArgument($argument) ? 4 : false;
+ }
+
+ /**
+ * Returns true if preset token is last.
+ *
+ * @return bool|int
+ */
+ public function isLast()
+ {
+ return $this->token->isLast();
+ }
+
+ /**
+ * Returns originating token.
+ *
+ * @return TokenInterface
+ */
+ public function getOriginatingToken()
+ {
+ return $this->token;
+ }
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return sprintf('not(%s)', $this->token);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php
new file mode 100644
index 0000000..d771077
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php
@@ -0,0 +1,104 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+use SebastianBergmann\Comparator\ComparisonFailure;
+use Prophecy\Comparator\Factory as ComparatorFactory;
+use Prophecy\Util\StringUtil;
+
+/**
+ * Object state-checker token.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ObjectStateToken implements TokenInterface
+{
+ private $name;
+ private $value;
+ private $util;
+ private $comparatorFactory;
+
+ /**
+ * Initializes token.
+ *
+ * @param string $methodName
+ * @param mixed $value Expected return value
+ * @param null|StringUtil $util
+ * @param ComparatorFactory $comparatorFactory
+ */
+ public function __construct(
+ $methodName,
+ $value,
+ StringUtil $util = null,
+ ComparatorFactory $comparatorFactory = null
+ ) {
+ $this->name = $methodName;
+ $this->value = $value;
+ $this->util = $util ?: new StringUtil;
+
+ $this->comparatorFactory = $comparatorFactory ?: ComparatorFactory::getInstance();
+ }
+
+ /**
+ * Scores 8 if argument is an object, which method returns expected value.
+ *
+ * @param mixed $argument
+ *
+ * @return bool|int
+ */
+ public function scoreArgument($argument)
+ {
+ if (is_object($argument) && method_exists($argument, $this->name)) {
+ $actual = call_user_func(array($argument, $this->name));
+
+ $comparator = $this->comparatorFactory->getComparatorFor(
+ $this->value, $actual
+ );
+
+ try {
+ $comparator->assertEquals($this->value, $actual);
+ return 8;
+ } catch (ComparisonFailure $failure) {
+ return false;
+ }
+ }
+
+ if (is_object($argument) && property_exists($argument, $this->name)) {
+ return $argument->{$this->name} === $this->value ? 8 : false;
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns false.
+ *
+ * @return bool
+ */
+ public function isLast()
+ {
+ return false;
+ }
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return sprintf('state(%s(), %s)',
+ $this->name,
+ $this->util->stringify($this->value)
+ );
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php
new file mode 100644
index 0000000..bd8d423
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+/**
+ * String contains token.
+ *
+ * @author Peter Mitchell <pete@peterjmit.com>
+ */
+class StringContainsToken implements TokenInterface
+{
+ private $value;
+
+ /**
+ * Initializes token.
+ *
+ * @param string $value
+ */
+ public function __construct($value)
+ {
+ $this->value = $value;
+ }
+
+ public function scoreArgument($argument)
+ {
+ return is_string($argument) && strpos($argument, $this->value) !== false ? 6 : false;
+ }
+
+ /**
+ * Returns preset value against which token checks arguments.
+ *
+ * @return mixed
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /**
+ * Returns false.
+ *
+ * @return bool
+ */
+ public function isLast()
+ {
+ return false;
+ }
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return sprintf('contains("%s")', $this->value);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php
new file mode 100644
index 0000000..625d3ba
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+/**
+ * Argument token interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface TokenInterface
+{
+ /**
+ * Calculates token match score for provided argument.
+ *
+ * @param $argument
+ *
+ * @return bool|int
+ */
+ public function scoreArgument($argument);
+
+ /**
+ * Returns true if this token prevents check of other tokens (is last one).
+ *
+ * @return bool|int
+ */
+ public function isLast();
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString();
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php
new file mode 100644
index 0000000..cb65132
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Argument\Token;
+
+use Prophecy\Exception\InvalidArgumentException;
+
+/**
+ * Value type token.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class TypeToken implements TokenInterface
+{
+ private $type;
+
+ /**
+ * @param string $type
+ */
+ public function __construct($type)
+ {
+ $checker = "is_{$type}";
+ if (!function_exists($checker) && !interface_exists($type) && !class_exists($type)) {
+ throw new InvalidArgumentException(sprintf(
+ 'Type or class name expected as an argument to TypeToken, but got %s.', $type
+ ));
+ }
+
+ $this->type = $type;
+ }
+
+ /**
+ * Scores 5 if argument has the same type this token was constructed with.
+ *
+ * @param $argument
+ *
+ * @return bool|int
+ */
+ public function scoreArgument($argument)
+ {
+ $checker = "is_{$this->type}";
+ if (function_exists($checker)) {
+ return call_user_func($checker, $argument) ? 5 : false;
+ }
+
+ return $argument instanceof $this->type ? 5 : false;
+ }
+
+ /**
+ * Returns false.
+ *
+ * @return bool
+ */
+ public function isLast()
+ {
+ return false;
+ }
+
+ /**
+ * Returns string representation for token.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return sprintf('type(%s)', $this->type);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Call/Call.php b/vendor/phpspec/prophecy/src/Prophecy/Call/Call.php
new file mode 100644
index 0000000..2652235
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Call/Call.php
@@ -0,0 +1,162 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Call;
+
+use Exception;
+use Prophecy\Argument\ArgumentsWildcard;
+
+/**
+ * Call object.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class Call
+{
+ private $methodName;
+ private $arguments;
+ private $returnValue;
+ private $exception;
+ private $file;
+ private $line;
+ private $scores;
+
+ /**
+ * Initializes call.
+ *
+ * @param string $methodName
+ * @param array $arguments
+ * @param mixed $returnValue
+ * @param Exception $exception
+ * @param null|string $file
+ * @param null|int $line
+ */
+ public function __construct($methodName, array $arguments, $returnValue,
+ Exception $exception = null, $file, $line)
+ {
+ $this->methodName = $methodName;
+ $this->arguments = $arguments;
+ $this->returnValue = $returnValue;
+ $this->exception = $exception;
+ $this->scores = new \SplObjectStorage();
+
+ if ($file) {
+ $this->file = $file;
+ $this->line = intval($line);
+ }
+ }
+
+ /**
+ * Returns called method name.
+ *
+ * @return string
+ */
+ public function getMethodName()
+ {
+ return $this->methodName;
+ }
+
+ /**
+ * Returns called method arguments.
+ *
+ * @return array
+ */
+ public function getArguments()
+ {
+ return $this->arguments;
+ }
+
+ /**
+ * Returns called method return value.
+ *
+ * @return null|mixed
+ */
+ public function getReturnValue()
+ {
+ return $this->returnValue;
+ }
+
+ /**
+ * Returns exception that call thrown.
+ *
+ * @return null|Exception
+ */
+ public function getException()
+ {
+ return $this->exception;
+ }
+
+ /**
+ * Returns callee filename.
+ *
+ * @return string
+ */
+ public function getFile()
+ {
+ return $this->file;
+ }
+
+ /**
+ * Returns callee line number.
+ *
+ * @return int
+ */
+ public function getLine()
+ {
+ return $this->line;
+ }
+
+ /**
+ * Returns short notation for callee place.
+ *
+ * @return string
+ */
+ public function getCallPlace()
+ {
+ if (null === $this->file) {
+ return 'unknown';
+ }
+
+ return sprintf('%s:%d', $this->file, $this->line);
+ }
+
+ /**
+ * Adds the wildcard match score for the provided wildcard.
+ *
+ * @param ArgumentsWildcard $wildcard
+ * @param false|int $score
+ *
+ * @return $this
+ */
+ public function addScore(ArgumentsWildcard $wildcard, $score)
+ {
+ $this->scores[$wildcard] = $score;
+
+ return $this;
+ }
+
+ /**
+ * Returns wildcard match score for the provided wildcard. The score is
+ * calculated if not already done.
+ *
+ * @param ArgumentsWildcard $wildcard
+ *
+ * @return false|int False OR integer score (higher - better)
+ */
+ public function getScore(ArgumentsWildcard $wildcard)
+ {
+ if (isset($this->scores[$wildcard])) {
+ return $this->scores[$wildcard];
+ }
+
+ return $this->scores[$wildcard] = $wildcard->scoreArguments($this->getArguments());
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Call/CallCenter.php b/vendor/phpspec/prophecy/src/Prophecy/Call/CallCenter.php
new file mode 100644
index 0000000..bc936c8
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Call/CallCenter.php
@@ -0,0 +1,229 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Call;
+
+use Prophecy\Exception\Prophecy\MethodProphecyException;
+use Prophecy\Prophecy\MethodProphecy;
+use Prophecy\Prophecy\ObjectProphecy;
+use Prophecy\Argument\ArgumentsWildcard;
+use Prophecy\Util\StringUtil;
+use Prophecy\Exception\Call\UnexpectedCallException;
+
+/**
+ * Calls receiver & manager.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class CallCenter
+{
+ private $util;
+
+ /**
+ * @var Call[]
+ */
+ private $recordedCalls = array();
+
+ /**
+ * Initializes call center.
+ *
+ * @param StringUtil $util
+ */
+ public function __construct(StringUtil $util = null)
+ {
+ $this->util = $util ?: new StringUtil;
+ }
+
+ /**
+ * Makes and records specific method call for object prophecy.
+ *
+ * @param ObjectProphecy $prophecy
+ * @param string $methodName
+ * @param array $arguments
+ *
+ * @return mixed Returns null if no promise for prophecy found or promise return value.
+ *
+ * @throws \Prophecy\Exception\Call\UnexpectedCallException If no appropriate method prophecy found
+ */
+ public function makeCall(ObjectProphecy $prophecy, $methodName, array $arguments)
+ {
+ // For efficiency exclude 'args' from the generated backtrace
+ if (PHP_VERSION_ID >= 50400) {
+ // Limit backtrace to last 3 calls as we don't use the rest
+ // Limit argument was introduced in PHP 5.4.0
+ $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
+ } elseif (defined('DEBUG_BACKTRACE_IGNORE_ARGS')) {
+ // DEBUG_BACKTRACE_IGNORE_ARGS was introduced in PHP 5.3.6
+ $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+ } else {
+ $backtrace = debug_backtrace();
+ }
+
+ $file = $line = null;
+ if (isset($backtrace[2]) && isset($backtrace[2]['file'])) {
+ $file = $backtrace[2]['file'];
+ $line = $backtrace[2]['line'];
+ }
+
+ // If no method prophecies defined, then it's a dummy, so we'll just return null
+ if ('__destruct' === $methodName || 0 == count($prophecy->getMethodProphecies())) {
+ $this->recordedCalls[] = new Call($methodName, $arguments, null, null, $file, $line);
+
+ return null;
+ }
+
+ // There are method prophecies, so it's a fake/stub. Searching prophecy for this call
+ $matches = array();
+ foreach ($prophecy->getMethodProphecies($methodName) as $methodProphecy) {
+ if (0 < $score = $methodProphecy->getArgumentsWildcard()->scoreArguments($arguments)) {
+ $matches[] = array($score, $methodProphecy);
+ }
+ }
+
+ // If fake/stub doesn't have method prophecy for this call - throw exception
+ if (!count($matches)) {
+ throw $this->createUnexpectedCallException($prophecy, $methodName, $arguments);
+ }
+
+ // Sort matches by their score value
+ @usort($matches, function ($match1, $match2) { return $match2[0] - $match1[0]; });
+
+ $score = $matches[0][0];
+ // If Highest rated method prophecy has a promise - execute it or return null instead
+ $methodProphecy = $matches[0][1];
+ $returnValue = null;
+ $exception = null;
+ if ($promise = $methodProphecy->getPromise()) {
+ try {
+ $returnValue = $promise->execute($arguments, $prophecy, $methodProphecy);
+ } catch (\Exception $e) {
+ $exception = $e;
+ }
+ }
+
+ if ($methodProphecy->hasReturnVoid() && $returnValue !== null) {
+ throw new MethodProphecyException(
+ "The method \"$methodName\" has a void return type, but the promise returned a value",
+ $methodProphecy
+ );
+ }
+
+ $this->recordedCalls[] = $call = new Call(
+ $methodName, $arguments, $returnValue, $exception, $file, $line
+ );
+ $call->addScore($methodProphecy->getArgumentsWildcard(), $score);
+
+ if (null !== $exception) {
+ throw $exception;
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * Searches for calls by method name & arguments wildcard.
+ *
+ * @param string $methodName
+ * @param ArgumentsWildcard $wildcard
+ *
+ * @return Call[]
+ */
+ public function findCalls($methodName, ArgumentsWildcard $wildcard)
+ {
+ return array_values(
+ array_filter($this->recordedCalls, function (Call $call) use ($methodName, $wildcard) {
+ return $methodName === $call->getMethodName()
+ && 0 < $call->getScore($wildcard)
+ ;
+ })
+ );
+ }
+
+ private function createUnexpectedCallException(ObjectProphecy $prophecy, $methodName,
+ array $arguments)
+ {
+ $classname = get_class($prophecy->reveal());
+ $indentationLength = 8; // looks good
+ $argstring = implode(
+ ",\n",
+ $this->indentArguments(
+ array_map(array($this->util, 'stringify'), $arguments),
+ $indentationLength
+ )
+ );
+
+ $expected = array();
+
+ foreach (call_user_func_array('array_merge', $prophecy->getMethodProphecies()) as $methodProphecy) {
+ $expected[] = sprintf(
+ " - %s(\n" .
+ "%s\n" .
+ " )",
+ $methodProphecy->getMethodName(),
+ implode(
+ ",\n",
+ $this->indentArguments(
+ array_map('strval', $methodProphecy->getArgumentsWildcard()->getTokens()),
+ $indentationLength
+ )
+ )
+ );
+ }
+
+ return new UnexpectedCallException(
+ sprintf(
+ "Unexpected method call on %s:\n".
+ " - %s(\n".
+ "%s\n".
+ " )\n".
+ "expected calls were:\n".
+ "%s",
+
+ $classname, $methodName, $argstring, implode("\n", $expected)
+ ),
+ $prophecy, $methodName, $arguments
+
+ );
+ }
+
+ private function formatExceptionMessage(MethodProphecy $methodProphecy)
+ {
+ return sprintf(
+ " - %s(\n".
+ "%s\n".
+ " )",
+ $methodProphecy->getMethodName(),
+ implode(
+ ",\n",
+ $this->indentArguments(
+ array_map(
+ function ($token) {
+ return (string) $token;
+ },
+ $methodProphecy->getArgumentsWildcard()->getTokens()
+ ),
+ $indentationLength
+ )
+ )
+ );
+ }
+
+ private function indentArguments(array $arguments, $indentationLength)
+ {
+ return preg_replace_callback(
+ '/^/m',
+ function () use ($indentationLength) {
+ return str_repeat(' ', $indentationLength);
+ },
+ $arguments
+ );
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php b/vendor/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php
new file mode 100644
index 0000000..874e474
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Comparator;
+
+use SebastianBergmann\Comparator\Comparator;
+use SebastianBergmann\Comparator\ComparisonFailure;
+
+/**
+ * Closure comparator.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class ClosureComparator extends Comparator
+{
+ public function accepts($expected, $actual)
+ {
+ return is_object($expected) && $expected instanceof \Closure
+ && is_object($actual) && $actual instanceof \Closure;
+ }
+
+ public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
+ {
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ // we don't need a diff
+ '',
+ '',
+ false,
+ 'all closures are born different'
+ );
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Comparator/Factory.php b/vendor/phpspec/prophecy/src/Prophecy/Comparator/Factory.php
new file mode 100644
index 0000000..2070db1
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Comparator/Factory.php
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Comparator;
+
+use SebastianBergmann\Comparator\Factory as BaseFactory;
+
+/**
+ * Prophecy comparator factory.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class Factory extends BaseFactory
+{
+ /**
+ * @var Factory
+ */
+ private static $instance;
+
+ public function __construct()
+ {
+ parent::__construct();
+
+ $this->register(new ClosureComparator());
+ $this->register(new ProphecyComparator());
+ }
+
+ /**
+ * @return Factory
+ */
+ public static function getInstance()
+ {
+ if (self::$instance === null) {
+ self::$instance = new Factory;
+ }
+
+ return self::$instance;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Comparator/ProphecyComparator.php b/vendor/phpspec/prophecy/src/Prophecy/Comparator/ProphecyComparator.php
new file mode 100644
index 0000000..298a8e3
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Comparator/ProphecyComparator.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Comparator;
+
+use Prophecy\Prophecy\ProphecyInterface;
+use SebastianBergmann\Comparator\ObjectComparator;
+
+class ProphecyComparator extends ObjectComparator
+{
+ public function accepts($expected, $actual)
+ {
+ return is_object($expected) && is_object($actual) && $actual instanceof ProphecyInterface;
+ }
+
+ public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array())
+ {
+ parent::assertEquals($expected, $actual->reveal(), $delta, $canonicalize, $ignoreCase, $processed);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php
new file mode 100644
index 0000000..d6b6b1a
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler;
+
+use ReflectionClass;
+
+/**
+ * Cached class doubler.
+ * Prevents mirroring/creation of the same structure twice.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class CachedDoubler extends Doubler
+{
+ private $classes = array();
+
+ /**
+ * {@inheritdoc}
+ */
+ public function registerClassPatch(ClassPatch\ClassPatchInterface $patch)
+ {
+ $this->classes[] = array();
+
+ parent::registerClassPatch($patch);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function createDoubleClass(ReflectionClass $class = null, array $interfaces)
+ {
+ $classId = $this->generateClassId($class, $interfaces);
+ if (isset($this->classes[$classId])) {
+ return $this->classes[$classId];
+ }
+
+ return $this->classes[$classId] = parent::createDoubleClass($class, $interfaces);
+ }
+
+ /**
+ * @param ReflectionClass $class
+ * @param ReflectionClass[] $interfaces
+ *
+ * @return string
+ */
+ private function generateClassId(ReflectionClass $class = null, array $interfaces)
+ {
+ $parts = array();
+ if (null !== $class) {
+ $parts[] = $class->getName();
+ }
+ foreach ($interfaces as $interface) {
+ $parts[] = $interface->getName();
+ }
+ sort($parts);
+
+ return md5(implode('', $parts));
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php
new file mode 100644
index 0000000..d6d1968
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler\ClassPatch;
+
+use Prophecy\Doubler\Generator\Node\ClassNode;
+
+/**
+ * Class patch interface.
+ * Class patches extend doubles functionality or help
+ * Prophecy to avoid some internal PHP bugs.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ClassPatchInterface
+{
+ /**
+ * Checks if patch supports specific class node.
+ *
+ * @param ClassNode $node
+ *
+ * @return bool
+ */
+ public function supports(ClassNode $node);
+
+ /**
+ * Applies patch to the specific class node.
+ *
+ * @param ClassNode $node
+ * @return void
+ */
+ public function apply(ClassNode $node);
+
+ /**
+ * Returns patch priority, which determines when patch will be applied.
+ *
+ * @return int Priority number (higher - earlier)
+ */
+ public function getPriority();
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php
new file mode 100644
index 0000000..61998fc
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler\ClassPatch;
+
+use Prophecy\Doubler\Generator\Node\ClassNode;
+use Prophecy\Doubler\Generator\Node\MethodNode;
+
+/**
+ * Disable constructor.
+ * Makes all constructor arguments optional.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class DisableConstructorPatch implements ClassPatchInterface
+{
+ /**
+ * Checks if class has `__construct` method.
+ *
+ * @param ClassNode $node
+ *
+ * @return bool
+ */
+ public function supports(ClassNode $node)
+ {
+ return true;
+ }
+
+ /**
+ * Makes all class constructor arguments optional.
+ *
+ * @param ClassNode $node
+ */
+ public function apply(ClassNode $node)
+ {
+ if (!$node->hasMethod('__construct')) {
+ $node->addMethod(new MethodNode('__construct', ''));
+
+ return;
+ }
+
+ $constructor = $node->getMethod('__construct');
+ foreach ($constructor->getArguments() as $argument) {
+ $argument->setDefault(null);
+ }
+
+ $constructor->setCode(<<<PHP
+if (0 < func_num_args()) {
+ call_user_func_array(array('parent', '__construct'), func_get_args());
+}
+PHP
+ );
+ }
+
+ /**
+ * Returns patch priority, which determines when patch will be applied.
+ *
+ * @return int Priority number (higher - earlier)
+ */
+ public function getPriority()
+ {
+ return 100;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/HhvmExceptionPatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/HhvmExceptionPatch.php
new file mode 100644
index 0000000..fa38fc0
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/HhvmExceptionPatch.php
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler\ClassPatch;
+
+use Prophecy\Doubler\Generator\Node\ClassNode;
+
+/**
+ * Exception patch for HHVM to remove the stubs from special methods
+ *
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+class HhvmExceptionPatch implements ClassPatchInterface
+{
+ /**
+ * Supports exceptions on HHVM.
+ *
+ * @param ClassNode $node
+ *
+ * @return bool
+ */
+ public function supports(ClassNode $node)
+ {
+ if (!defined('HHVM_VERSION')) {
+ return false;
+ }
+
+ return 'Exception' === $node->getParentClass() || is_subclass_of($node->getParentClass(), 'Exception');
+ }
+
+ /**
+ * Removes special exception static methods from the doubled methods.
+ *
+ * @param ClassNode $node
+ *
+ * @return void
+ */
+ public function apply(ClassNode $node)
+ {
+ if ($node->hasMethod('setTraceOptions')) {
+ $node->getMethod('setTraceOptions')->useParentCode();
+ }
+ if ($node->hasMethod('getTraceOptions')) {
+ $node->getMethod('getTraceOptions')->useParentCode();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPriority()
+ {
+ return -50;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php
new file mode 100644
index 0000000..41ea2fc
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php
@@ -0,0 +1,140 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler\ClassPatch;
+
+use Prophecy\Doubler\Generator\Node\ClassNode;
+
+/**
+ * Remove method functionality from the double which will clash with php keywords.
+ *
+ * @author Milan Magudia <milan@magudia.com>
+ */
+class KeywordPatch implements ClassPatchInterface
+{
+ /**
+ * Support any class
+ *
+ * @param ClassNode $node
+ *
+ * @return boolean
+ */
+ public function supports(ClassNode $node)
+ {
+ return true;
+ }
+
+ /**
+ * Remove methods that clash with php keywords
+ *
+ * @param ClassNode $node
+ */
+ public function apply(ClassNode $node)
+ {
+ $methodNames = array_keys($node->getMethods());
+ $methodsToRemove = array_intersect($methodNames, $this->getKeywords());
+ foreach ($methodsToRemove as $methodName) {
+ $node->removeMethod($methodName);
+ }
+ }
+
+ /**
+ * Returns patch priority, which determines when patch will be applied.
+ *
+ * @return int Priority number (higher - earlier)
+ */
+ public function getPriority()
+ {
+ return 49;
+ }
+
+ /**
+ * Returns array of php keywords.
+ *
+ * @return array
+ */
+ private function getKeywords()
+ {
+ if (\PHP_VERSION_ID >= 70000) {
+ return array('__halt_compiler');
+ }
+
+ return array(
+ '__halt_compiler',
+ 'abstract',
+ 'and',
+ 'array',
+ 'as',
+ 'break',
+ 'callable',
+ 'case',
+ 'catch',
+ 'class',
+ 'clone',
+ 'const',
+ 'continue',
+ 'declare',
+ 'default',
+ 'die',
+ 'do',
+ 'echo',
+ 'else',
+ 'elseif',
+ 'empty',
+ 'enddeclare',
+ 'endfor',
+ 'endforeach',
+ 'endif',
+ 'endswitch',
+ 'endwhile',
+ 'eval',
+ 'exit',
+ 'extends',
+ 'final',
+ 'finally',
+ 'for',
+ 'foreach',
+ 'function',
+ 'global',
+ 'goto',
+ 'if',
+ 'implements',
+ 'include',
+ 'include_once',
+ 'instanceof',
+ 'insteadof',
+ 'interface',
+ 'isset',
+ 'list',
+ 'namespace',
+ 'new',
+ 'or',
+ 'print',
+ 'private',
+ 'protected',
+ 'public',
+ 'require',
+ 'require_once',
+ 'return',
+ 'static',
+ 'switch',
+ 'throw',
+ 'trait',
+ 'try',
+ 'unset',
+ 'use',
+ 'var',
+ 'while',
+ 'xor',
+ 'yield',
+ );
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php
new file mode 100644
index 0000000..9ff49cd
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php
@@ -0,0 +1,94 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler\ClassPatch;
+
+use Prophecy\Doubler\Generator\Node\ClassNode;
+use Prophecy\Doubler\Generator\Node\MethodNode;
+use Prophecy\PhpDocumentor\ClassAndInterfaceTagRetriever;
+use Prophecy\PhpDocumentor\MethodTagRetrieverInterface;
+
+/**
+ * Discover Magical API using "@method" PHPDoc format.
+ *
+ * @author Thomas Tourlourat <thomas@tourlourat.com>
+ * @author Kévin Dunglas <dunglas@gmail.com>
+ * @author Théo FIDRY <theo.fidry@gmail.com>
+ */
+class MagicCallPatch implements ClassPatchInterface
+{
+ private $tagRetriever;
+
+ public function __construct(MethodTagRetrieverInterface $tagRetriever = null)
+ {
+ $this->tagRetriever = null === $tagRetriever ? new ClassAndInterfaceTagRetriever() : $tagRetriever;
+ }
+
+ /**
+ * Support any class
+ *
+ * @param ClassNode $node
+ *
+ * @return boolean
+ */
+ public function supports(ClassNode $node)
+ {
+ return true;
+ }
+
+ /**
+ * Discover Magical API
+ *
+ * @param ClassNode $node
+ */
+ public function apply(ClassNode $node)
+ {
+ $types = array_filter($node->getInterfaces(), function ($interface) {
+ return 0 !== strpos($interface, 'Prophecy\\');
+ });
+ $types[] = $node->getParentClass();
+
+ foreach ($types as $type) {
+ $reflectionClass = new \ReflectionClass($type);
+
+ while ($reflectionClass) {
+ $tagList = $this->tagRetriever->getTagList($reflectionClass);
+
+ foreach ($tagList as $tag) {
+ $methodName = $tag->getMethodName();
+
+ if (empty($methodName)) {
+ continue;
+ }
+
+ if (!$reflectionClass->hasMethod($methodName)) {
+ $methodNode = new MethodNode($methodName);
+ $methodNode->setStatic($tag->isStatic());
+ $node->addMethod($methodNode);
+ }
+ }
+
+ $reflectionClass = $reflectionClass->getParentClass();
+ }
+ }
+ }
+
+ /**
+ * Returns patch priority, which determines when patch will be applied.
+ *
+ * @return integer Priority number (higher - earlier)
+ */
+ public function getPriority()
+ {
+ return 50;
+ }
+}
+
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php
new file mode 100644
index 0000000..081dea8
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php
@@ -0,0 +1,104 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler\ClassPatch;
+
+use Prophecy\Doubler\Generator\Node\ClassNode;
+use Prophecy\Doubler\Generator\Node\MethodNode;
+use Prophecy\Doubler\Generator\Node\ArgumentNode;
+
+/**
+ * Add Prophecy functionality to the double.
+ * This is a core class patch for Prophecy.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ProphecySubjectPatch implements ClassPatchInterface
+{
+ /**
+ * Always returns true.
+ *
+ * @param ClassNode $node
+ *
+ * @return bool
+ */
+ public function supports(ClassNode $node)
+ {
+ return true;
+ }
+
+ /**
+ * Apply Prophecy functionality to class node.
+ *
+ * @param ClassNode $node
+ */
+ public function apply(ClassNode $node)
+ {
+ $node->addInterface('Prophecy\Prophecy\ProphecySubjectInterface');
+ $node->addProperty('objectProphecy', 'private');
+
+ foreach ($node->getMethods() as $name => $method) {
+ if ('__construct' === strtolower($name)) {
+ continue;
+ }
+
+ if ($method->getReturnType() === 'void') {
+ $method->setCode(
+ '$this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());'
+ );
+ } else {
+ $method->setCode(
+ 'return $this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());'
+ );
+ }
+ }
+
+ $prophecySetter = new MethodNode('setProphecy');
+ $prophecyArgument = new ArgumentNode('prophecy');
+ $prophecyArgument->setTypeHint('Prophecy\Prophecy\ProphecyInterface');
+ $prophecySetter->addArgument($prophecyArgument);
+ $prophecySetter->setCode('$this->objectProphecy = $prophecy;');
+
+ $prophecyGetter = new MethodNode('getProphecy');
+ $prophecyGetter->setCode('return $this->objectProphecy;');
+
+ if ($node->hasMethod('__call')) {
+ $__call = $node->getMethod('__call');
+ } else {
+ $__call = new MethodNode('__call');
+ $__call->addArgument(new ArgumentNode('name'));
+ $__call->addArgument(new ArgumentNode('arguments'));
+
+ $node->addMethod($__call, true);
+ }
+
+ $__call->setCode(<<<PHP
+throw new \Prophecy\Exception\Doubler\MethodNotFoundException(
+ sprintf('Method `%s::%s()` not found.', get_class(\$this), func_get_arg(0)),
+ \$this->getProphecy(), func_get_arg(0)
+);
+PHP
+ );
+
+ $node->addMethod($prophecySetter, true);
+ $node->addMethod($prophecyGetter, true);
+ }
+
+ /**
+ * Returns patch priority, which determines when patch will be applied.
+ *
+ * @return int Priority number (higher - earlier)
+ */
+ public function getPriority()
+ {
+ return 0;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php
new file mode 100644
index 0000000..9166aee
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler\ClassPatch;
+
+use Prophecy\Doubler\Generator\Node\ClassNode;
+
+/**
+ * ReflectionClass::newInstance patch.
+ * Makes first argument of newInstance optional, since it works but signature is misleading
+ *
+ * @author Florian Klein <florian.klein@free.fr>
+ */
+class ReflectionClassNewInstancePatch implements ClassPatchInterface
+{
+ /**
+ * Supports ReflectionClass
+ *
+ * @param ClassNode $node
+ *
+ * @return bool
+ */
+ public function supports(ClassNode $node)
+ {
+ return 'ReflectionClass' === $node->getParentClass();
+ }
+
+ /**
+ * Updates newInstance's first argument to make it optional
+ *
+ * @param ClassNode $node
+ */
+ public function apply(ClassNode $node)
+ {
+ foreach ($node->getMethod('newInstance')->getArguments() as $argument) {
+ $argument->setDefault(null);
+ }
+ }
+
+ /**
+ * Returns patch priority, which determines when patch will be applied.
+ *
+ * @return int Priority number (higher = earlier)
+ */
+ public function getPriority()
+ {
+ return 50;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php
new file mode 100644
index 0000000..ceee94a
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php
@@ -0,0 +1,123 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler\ClassPatch;
+
+use Prophecy\Doubler\Generator\Node\ClassNode;
+use Prophecy\Doubler\Generator\Node\MethodNode;
+
+/**
+ * SplFileInfo patch.
+ * Makes SplFileInfo and derivative classes usable with Prophecy.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class SplFileInfoPatch implements ClassPatchInterface
+{
+ /**
+ * Supports everything that extends SplFileInfo.
+ *
+ * @param ClassNode $node
+ *
+ * @return bool
+ */
+ public function supports(ClassNode $node)
+ {
+ if (null === $node->getParentClass()) {
+ return false;
+ }
+ return 'SplFileInfo' === $node->getParentClass()
+ || is_subclass_of($node->getParentClass(), 'SplFileInfo')
+ ;
+ }
+
+ /**
+ * Updated constructor code to call parent one with dummy file argument.
+ *
+ * @param ClassNode $node
+ */
+ public function apply(ClassNode $node)
+ {
+ if ($node->hasMethod('__construct')) {
+ $constructor = $node->getMethod('__construct');
+ } else {
+ $constructor = new MethodNode('__construct');
+ $node->addMethod($constructor);
+ }
+
+ if ($this->nodeIsDirectoryIterator($node)) {
+ $constructor->setCode('return parent::__construct("' . __DIR__ . '");');
+
+ return;
+ }
+
+ if ($this->nodeIsSplFileObject($node)) {
+ $filePath = str_replace('\\','\\\\',__FILE__);
+ $constructor->setCode('return parent::__construct("' . $filePath .'");');
+
+ return;
+ }
+
+ if ($this->nodeIsSymfonySplFileInfo($node)) {
+ $filePath = str_replace('\\','\\\\',__FILE__);
+ $constructor->setCode('return parent::__construct("' . $filePath .'", "", "");');
+
+ return;
+ }
+
+ $constructor->useParentCode();
+ }
+
+ /**
+ * Returns patch priority, which determines when patch will be applied.
+ *
+ * @return int Priority number (higher - earlier)
+ */
+ public function getPriority()
+ {
+ return 50;
+ }
+
+ /**
+ * @param ClassNode $node
+ * @return boolean
+ */
+ private function nodeIsDirectoryIterator(ClassNode $node)
+ {
+ $parent = $node->getParentClass();
+
+ return 'DirectoryIterator' === $parent
+ || is_subclass_of($parent, 'DirectoryIterator');
+ }
+
+ /**
+ * @param ClassNode $node
+ * @return boolean
+ */
+ private function nodeIsSplFileObject(ClassNode $node)
+ {
+ $parent = $node->getParentClass();
+
+ return 'SplFileObject' === $parent
+ || is_subclass_of($parent, 'SplFileObject');
+ }
+
+ /**
+ * @param ClassNode $node
+ * @return boolean
+ */
+ private function nodeIsSymfonySplFileInfo(ClassNode $node)
+ {
+ $parent = $node->getParentClass();
+
+ return 'Symfony\\Component\\Finder\\SplFileInfo' === $parent;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ThrowablePatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ThrowablePatch.php
new file mode 100644
index 0000000..b98e943
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ThrowablePatch.php
@@ -0,0 +1,95 @@
+<?php
+
+namespace Prophecy\Doubler\ClassPatch;
+
+use Prophecy\Doubler\Generator\Node\ClassNode;
+use Prophecy\Exception\Doubler\ClassCreatorException;
+
+class ThrowablePatch implements ClassPatchInterface
+{
+ /**
+ * Checks if patch supports specific class node.
+ *
+ * @param ClassNode $node
+ * @return bool
+ */
+ public function supports(ClassNode $node)
+ {
+ return $this->implementsAThrowableInterface($node) && $this->doesNotExtendAThrowableClass($node);
+ }
+
+ /**
+ * @param ClassNode $node
+ * @return bool
+ */
+ private function implementsAThrowableInterface(ClassNode $node)
+ {
+ foreach ($node->getInterfaces() as $type) {
+ if (is_a($type, 'Throwable', true)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @param ClassNode $node
+ * @return bool
+ */
+ private function doesNotExtendAThrowableClass(ClassNode $node)
+ {
+ return !is_a($node->getParentClass(), 'Throwable', true);
+ }
+
+ /**
+ * Applies patch to the specific class node.
+ *
+ * @param ClassNode $node
+ *
+ * @return void
+ */
+ public function apply(ClassNode $node)
+ {
+ $this->checkItCanBeDoubled($node);
+ $this->setParentClassToException($node);
+ }
+
+ private function checkItCanBeDoubled(ClassNode $node)
+ {
+ $className = $node->getParentClass();
+ if ($className !== 'stdClass') {
+ throw new ClassCreatorException(
+ sprintf(
+ 'Cannot double concrete class %s as well as implement Traversable',
+ $className
+ ),
+ $node
+ );
+ }
+ }
+
+ private function setParentClassToException(ClassNode $node)
+ {
+ $node->setParentClass('Exception');
+
+ $node->removeMethod('getMessage');
+ $node->removeMethod('getCode');
+ $node->removeMethod('getFile');
+ $node->removeMethod('getLine');
+ $node->removeMethod('getTrace');
+ $node->removeMethod('getPrevious');
+ $node->removeMethod('getNext');
+ $node->removeMethod('getTraceAsString');
+ }
+
+ /**
+ * Returns patch priority, which determines when patch will be applied.
+ *
+ * @return int Priority number (higher - earlier)
+ */
+ public function getPriority()
+ {
+ return 100;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php
new file mode 100644
index 0000000..eea0202
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler\ClassPatch;
+
+use Prophecy\Doubler\Generator\Node\ClassNode;
+use Prophecy\Doubler\Generator\Node\MethodNode;
+
+/**
+ * Traversable interface patch.
+ * Forces classes that implement interfaces, that extend Traversable to also implement Iterator.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class TraversablePatch implements ClassPatchInterface
+{
+ /**
+ * Supports nodetree, that implement Traversable, but not Iterator or IteratorAggregate.
+ *
+ * @param ClassNode $node
+ *
+ * @return bool
+ */
+ public function supports(ClassNode $node)
+ {
+ if (in_array('Iterator', $node->getInterfaces())) {
+ return false;
+ }
+ if (in_array('IteratorAggregate', $node->getInterfaces())) {
+ return false;
+ }
+
+ foreach ($node->getInterfaces() as $interface) {
+ if ('Traversable' !== $interface && !is_subclass_of($interface, 'Traversable')) {
+ continue;
+ }
+ if ('Iterator' === $interface || is_subclass_of($interface, 'Iterator')) {
+ continue;
+ }
+ if ('IteratorAggregate' === $interface || is_subclass_of($interface, 'IteratorAggregate')) {
+ continue;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Forces class to implement Iterator interface.
+ *
+ * @param ClassNode $node
+ */
+ public function apply(ClassNode $node)
+ {
+ $node->addInterface('Iterator');
+
+ $node->addMethod(new MethodNode('current'));
+ $node->addMethod(new MethodNode('key'));
+ $node->addMethod(new MethodNode('next'));
+ $node->addMethod(new MethodNode('rewind'));
+ $node->addMethod(new MethodNode('valid'));
+ }
+
+ /**
+ * Returns patch priority, which determines when patch will be applied.
+ *
+ * @return int Priority number (higher - earlier)
+ */
+ public function getPriority()
+ {
+ return 100;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php
new file mode 100644
index 0000000..699be3a
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler;
+
+/**
+ * Core double interface.
+ * All doubled classes will implement this one.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface DoubleInterface
+{
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php
new file mode 100644
index 0000000..a378ae2
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php
@@ -0,0 +1,146 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler;
+
+use Doctrine\Instantiator\Instantiator;
+use Prophecy\Doubler\ClassPatch\ClassPatchInterface;
+use Prophecy\Doubler\Generator\ClassMirror;
+use Prophecy\Doubler\Generator\ClassCreator;
+use Prophecy\Exception\InvalidArgumentException;
+use ReflectionClass;
+
+/**
+ * Cached class doubler.
+ * Prevents mirroring/creation of the same structure twice.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class Doubler
+{
+ private $mirror;
+ private $creator;
+ private $namer;
+
+ /**
+ * @var ClassPatchInterface[]
+ */
+ private $patches = array();
+
+ /**
+ * @var \Doctrine\Instantiator\Instantiator
+ */
+ private $instantiator;
+
+ /**
+ * Initializes doubler.
+ *
+ * @param ClassMirror $mirror
+ * @param ClassCreator $creator
+ * @param NameGenerator $namer
+ */
+ public function __construct(ClassMirror $mirror = null, ClassCreator $creator = null,
+ NameGenerator $namer = null)
+ {
+ $this->mirror = $mirror ?: new ClassMirror;
+ $this->creator = $creator ?: new ClassCreator;
+ $this->namer = $namer ?: new NameGenerator;
+ }
+
+ /**
+ * Returns list of registered class patches.
+ *
+ * @return ClassPatchInterface[]
+ */
+ public function getClassPatches()
+ {
+ return $this->patches;
+ }
+
+ /**
+ * Registers new class patch.
+ *
+ * @param ClassPatchInterface $patch
+ */
+ public function registerClassPatch(ClassPatchInterface $patch)
+ {
+ $this->patches[] = $patch;
+
+ @usort($this->patches, function (ClassPatchInterface $patch1, ClassPatchInterface $patch2) {
+ return $patch2->getPriority() - $patch1->getPriority();
+ });
+ }
+
+ /**
+ * Creates double from specific class or/and list of interfaces.
+ *
+ * @param ReflectionClass $class
+ * @param ReflectionClass[] $interfaces Array of ReflectionClass instances
+ * @param array $args Constructor arguments
+ *
+ * @return DoubleInterface
+ *
+ * @throws \Prophecy\Exception\InvalidArgumentException
+ */
+ public function double(ReflectionClass $class = null, array $interfaces, array $args = null)
+ {
+ foreach ($interfaces as $interface) {
+ if (!$interface instanceof ReflectionClass) {
+ throw new InvalidArgumentException(sprintf(
+ "[ReflectionClass \$interface1 [, ReflectionClass \$interface2]] array expected as\n".
+ "a second argument to `Doubler::double(...)`, but got %s.",
+ is_object($interface) ? get_class($interface).' class' : gettype($interface)
+ ));
+ }
+ }
+
+ $classname = $this->createDoubleClass($class, $interfaces);
+ $reflection = new ReflectionClass($classname);
+
+ if (null !== $args) {
+ return $reflection->newInstanceArgs($args);
+ }
+ if ((null === $constructor = $reflection->getConstructor())
+ || ($constructor->isPublic() && !$constructor->isFinal())) {
+ return $reflection->newInstance();
+ }
+
+ if (!$this->instantiator) {
+ $this->instantiator = new Instantiator();
+ }
+
+ return $this->instantiator->instantiate($classname);
+ }
+
+ /**
+ * Creates double class and returns its FQN.
+ *
+ * @param ReflectionClass $class
+ * @param ReflectionClass[] $interfaces
+ *
+ * @return string
+ */
+ protected function createDoubleClass(ReflectionClass $class = null, array $interfaces)
+ {
+ $name = $this->namer->name($class, $interfaces);
+ $node = $this->mirror->reflect($class, $interfaces);
+
+ foreach ($this->patches as $patch) {
+ if ($patch->supports($node)) {
+ $patch->apply($node);
+ }
+ }
+
+ $this->creator->create($name, $node);
+
+ return $name;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php
new file mode 100644
index 0000000..891faa8
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php
@@ -0,0 +1,129 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler\Generator;
+
+/**
+ * Class code creator.
+ * Generates PHP code for specific class node tree.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ClassCodeGenerator
+{
+ /**
+ * @var TypeHintReference
+ */
+ private $typeHintReference;
+
+ public function __construct(TypeHintReference $typeHintReference = null)
+ {
+ $this->typeHintReference = $typeHintReference ?: new TypeHintReference();
+ }
+
+ /**
+ * Generates PHP code for class node.
+ *
+ * @param string $classname
+ * @param Node\ClassNode $class
+ *
+ * @return string
+ */
+ public function generate($classname, Node\ClassNode $class)
+ {
+ $parts = explode('\\', $classname);
+ $classname = array_pop($parts);
+ $namespace = implode('\\', $parts);
+
+ $code = sprintf("class %s extends \%s implements %s {\n",
+ $classname, $class->getParentClass(), implode(', ',
+ array_map(function ($interface) {return '\\'.$interface;}, $class->getInterfaces())
+ )
+ );
+
+ foreach ($class->getProperties() as $name => $visibility) {
+ $code .= sprintf("%s \$%s;\n", $visibility, $name);
+ }
+ $code .= "\n";
+
+ foreach ($class->getMethods() as $method) {
+ $code .= $this->generateMethod($method)."\n";
+ }
+ $code .= "\n}";
+
+ return sprintf("namespace %s {\n%s\n}", $namespace, $code);
+ }
+
+ private function generateMethod(Node\MethodNode $method)
+ {
+ $php = sprintf("%s %s function %s%s(%s)%s {\n",
+ $method->getVisibility(),
+ $method->isStatic() ? 'static' : '',
+ $method->returnsReference() ? '&':'',
+ $method->getName(),
+ implode(', ', $this->generateArguments($method->getArguments())),
+ $this->getReturnType($method)
+ );
+ $php .= $method->getCode()."\n";
+
+ return $php.'}';
+ }
+
+ /**
+ * @return string
+ */
+ private function getReturnType(Node\MethodNode $method)
+ {
+ if (version_compare(PHP_VERSION, '7.1', '>=')) {
+ if ($method->hasReturnType()) {
+ return $method->hasNullableReturnType()
+ ? sprintf(': ?%s', $method->getReturnType())
+ : sprintf(': %s', $method->getReturnType());
+ }
+ }
+
+ if (version_compare(PHP_VERSION, '7.0', '>=')) {
+ return $method->hasReturnType() && $method->getReturnType() !== 'void'
+ ? sprintf(': %s', $method->getReturnType())
+ : '';
+ }
+
+ return '';
+ }
+
+ private function generateArguments(array $arguments)
+ {
+ $typeHintReference = $this->typeHintReference;
+ return array_map(function (Node\ArgumentNode $argument) use ($typeHintReference) {
+ $php = '';
+
+ if (version_compare(PHP_VERSION, '7.1', '>=')) {
+ $php .= $argument->isNullable() ? '?' : '';
+ }
+
+ if ($hint = $argument->getTypeHint()) {
+ $php .= $typeHintReference->isBuiltInParamTypeHint($hint) ? $hint : '\\'.$hint;
+ }
+
+ $php .= ' '.($argument->isPassedByReference() ? '&' : '');
+
+ $php .= $argument->isVariadic() ? '...' : '';
+
+ $php .= '$'.$argument->getName();
+
+ if ($argument->isOptional() && !$argument->isVariadic()) {
+ $php .= ' = '.var_export($argument->getDefault(), true);
+ }
+
+ return $php;
+ }, $arguments);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php
new file mode 100644
index 0000000..882a4a4
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler\Generator;
+
+use Prophecy\Exception\Doubler\ClassCreatorException;
+
+/**
+ * Class creator.
+ * Creates specific class in current environment.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ClassCreator
+{
+ private $generator;
+
+ /**
+ * Initializes creator.
+ *
+ * @param ClassCodeGenerator $generator
+ */
+ public function __construct(ClassCodeGenerator $generator = null)
+ {
+ $this->generator = $generator ?: new ClassCodeGenerator;
+ }
+
+ /**
+ * Creates class.
+ *
+ * @param string $classname
+ * @param Node\ClassNode $class
+ *
+ * @return mixed
+ *
+ * @throws \Prophecy\Exception\Doubler\ClassCreatorException
+ */
+ public function create($classname, Node\ClassNode $class)
+ {
+ $code = $this->generator->generate($classname, $class);
+ $return = eval($code);
+
+ if (!class_exists($classname, false)) {
+ if (count($class->getInterfaces())) {
+ throw new ClassCreatorException(sprintf(
+ 'Could not double `%s` and implement interfaces: [%s].',
+ $class->getParentClass(), implode(', ', $class->getInterfaces())
+ ), $class);
+ }
+
+ throw new ClassCreatorException(
+ sprintf('Could not double `%s`.', $class->getParentClass()),
+ $class
+ );
+ }
+
+ return $return;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php
new file mode 100644
index 0000000..c5f9a5c
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php
@@ -0,0 +1,260 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler\Generator;
+
+use Prophecy\Exception\InvalidArgumentException;
+use Prophecy\Exception\Doubler\ClassMirrorException;
+use ReflectionClass;
+use ReflectionMethod;
+use ReflectionParameter;
+
+/**
+ * Class mirror.
+ * Core doubler class. Mirrors specific class and/or interfaces into class node tree.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ClassMirror
+{
+ private static $reflectableMethods = array(
+ '__construct',
+ '__destruct',
+ '__sleep',
+ '__wakeup',
+ '__toString',
+ '__call',
+ '__invoke'
+ );
+
+ /**
+ * Reflects provided arguments into class node.
+ *
+ * @param ReflectionClass $class
+ * @param ReflectionClass[] $interfaces
+ *
+ * @return Node\ClassNode
+ *
+ * @throws \Prophecy\Exception\InvalidArgumentException
+ */
+ public function reflect(ReflectionClass $class = null, array $interfaces)
+ {
+ $node = new Node\ClassNode;
+
+ if (null !== $class) {
+ if (true === $class->isInterface()) {
+ throw new InvalidArgumentException(sprintf(
+ "Could not reflect %s as a class, because it\n".
+ "is interface - use the second argument instead.",
+ $class->getName()
+ ));
+ }
+
+ $this->reflectClassToNode($class, $node);
+ }
+
+ foreach ($interfaces as $interface) {
+ if (!$interface instanceof ReflectionClass) {
+ throw new InvalidArgumentException(sprintf(
+ "[ReflectionClass \$interface1 [, ReflectionClass \$interface2]] array expected as\n".
+ "a second argument to `ClassMirror::reflect(...)`, but got %s.",
+ is_object($interface) ? get_class($interface).' class' : gettype($interface)
+ ));
+ }
+ if (false === $interface->isInterface()) {
+ throw new InvalidArgumentException(sprintf(
+ "Could not reflect %s as an interface, because it\n".
+ "is class - use the first argument instead.",
+ $interface->getName()
+ ));
+ }
+
+ $this->reflectInterfaceToNode($interface, $node);
+ }
+
+ $node->addInterface('Prophecy\Doubler\Generator\ReflectionInterface');
+
+ return $node;
+ }
+
+ private function reflectClassToNode(ReflectionClass $class, Node\ClassNode $node)
+ {
+ if (true === $class->isFinal()) {
+ throw new ClassMirrorException(sprintf(
+ 'Could not reflect class %s as it is marked final.', $class->getName()
+ ), $class);
+ }
+
+ $node->setParentClass($class->getName());
+
+ foreach ($class->getMethods(ReflectionMethod::IS_ABSTRACT) as $method) {
+ if (false === $method->isProtected()) {
+ continue;
+ }
+
+ $this->reflectMethodToNode($method, $node);
+ }
+
+ foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
+ if (0 === strpos($method->getName(), '_')
+ && !in_array($method->getName(), self::$reflectableMethods)) {
+ continue;
+ }
+
+ if (true === $method->isFinal()) {
+ $node->addUnextendableMethod($method->getName());
+ continue;
+ }
+
+ $this->reflectMethodToNode($method, $node);
+ }
+ }
+
+ private function reflectInterfaceToNode(ReflectionClass $interface, Node\ClassNode $node)
+ {
+ $node->addInterface($interface->getName());
+
+ foreach ($interface->getMethods() as $method) {
+ $this->reflectMethodToNode($method, $node);
+ }
+ }
+
+ private function reflectMethodToNode(ReflectionMethod $method, Node\ClassNode $classNode)
+ {
+ $node = new Node\MethodNode($method->getName());
+
+ if (true === $method->isProtected()) {
+ $node->setVisibility('protected');
+ }
+
+ if (true === $method->isStatic()) {
+ $node->setStatic();
+ }
+
+ if (true === $method->returnsReference()) {
+ $node->setReturnsReference();
+ }
+
+ if (version_compare(PHP_VERSION, '7.0', '>=') && $method->hasReturnType()) {
+ $returnType = (string) $method->getReturnType();
+ $returnTypeLower = strtolower($returnType);
+
+ if ('self' === $returnTypeLower) {
+ $returnType = $method->getDeclaringClass()->getName();
+ }
+ if ('parent' === $returnTypeLower) {
+ $returnType = $method->getDeclaringClass()->getParentClass()->getName();
+ }
+
+ $node->setReturnType($returnType);
+
+ if (version_compare(PHP_VERSION, '7.1', '>=') && $method->getReturnType()->allowsNull()) {
+ $node->setNullableReturnType(true);
+ }
+ }
+
+ if (is_array($params = $method->getParameters()) && count($params)) {
+ foreach ($params as $param) {
+ $this->reflectArgumentToNode($param, $node);
+ }
+ }
+
+ $classNode->addMethod($node);
+ }
+
+ private function reflectArgumentToNode(ReflectionParameter $parameter, Node\MethodNode $methodNode)
+ {
+ $name = $parameter->getName() == '...' ? '__dot_dot_dot__' : $parameter->getName();
+ $node = new Node\ArgumentNode($name);
+
+ $node->setTypeHint($this->getTypeHint($parameter));
+
+ if ($this->isVariadic($parameter)) {
+ $node->setAsVariadic();
+ }
+
+ if ($this->hasDefaultValue($parameter)) {
+ $node->setDefault($this->getDefaultValue($parameter));
+ }
+
+ if ($parameter->isPassedByReference()) {
+ $node->setAsPassedByReference();
+ }
+
+ $node->setAsNullable($this->isNullable($parameter));
+
+ $methodNode->addArgument($node);
+ }
+
+ private function hasDefaultValue(ReflectionParameter $parameter)
+ {
+ if ($this->isVariadic($parameter)) {
+ return false;
+ }
+
+ if ($parameter->isDefaultValueAvailable()) {
+ return true;
+ }
+
+ return $parameter->isOptional() || $this->isNullable($parameter);
+ }
+
+ private function getDefaultValue(ReflectionParameter $parameter)
+ {
+ if (!$parameter->isDefaultValueAvailable()) {
+ return null;
+ }
+
+ return $parameter->getDefaultValue();
+ }
+
+ private function getTypeHint(ReflectionParameter $parameter)
+ {
+ if (null !== $className = $this->getParameterClassName($parameter)) {
+ return $className;
+ }
+
+ if (true === $parameter->isArray()) {
+ return 'array';
+ }
+
+ if (version_compare(PHP_VERSION, '5.4', '>=') && true === $parameter->isCallable()) {
+ return 'callable';
+ }
+
+ if (version_compare(PHP_VERSION, '7.0', '>=') && true === $parameter->hasType()) {
+ return (string) $parameter->getType();
+ }
+
+ return null;
+ }
+
+ private function isVariadic(ReflectionParameter $parameter)
+ {
+ return PHP_VERSION_ID >= 50600 && $parameter->isVariadic();
+ }
+
+ private function isNullable(ReflectionParameter $parameter)
+ {
+ return $parameter->allowsNull() && null !== $this->getTypeHint($parameter);
+ }
+
+ private function getParameterClassName(ReflectionParameter $parameter)
+ {
+ try {
+ return $parameter->getClass() ? $parameter->getClass()->getName() : null;
+ } catch (\ReflectionException $e) {
+ preg_match('/\[\s\<\w+?>\s([\w,\\\]+)/s', $parameter, $matches);
+
+ return isset($matches[1]) ? $matches[1] : null;
+ }
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php
new file mode 100644
index 0000000..dd29b68
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php
@@ -0,0 +1,102 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler\Generator\Node;
+
+/**
+ * Argument node.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ArgumentNode
+{
+ private $name;
+ private $typeHint;
+ private $default;
+ private $optional = false;
+ private $byReference = false;
+ private $isVariadic = false;
+ private $isNullable = false;
+
+ /**
+ * @param string $name
+ */
+ public function __construct($name)
+ {
+ $this->name = $name;
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function getTypeHint()
+ {
+ return $this->typeHint;
+ }
+
+ public function setTypeHint($typeHint = null)
+ {
+ $this->typeHint = $typeHint;
+ }
+
+ public function hasDefault()
+ {
+ return $this->isOptional() && !$this->isVariadic();
+ }
+
+ public function getDefault()
+ {
+ return $this->default;
+ }
+
+ public function setDefault($default = null)
+ {
+ $this->optional = true;
+ $this->default = $default;
+ }
+
+ public function isOptional()
+ {
+ return $this->optional;
+ }
+
+ public function setAsPassedByReference($byReference = true)
+ {
+ $this->byReference = $byReference;
+ }
+
+ public function isPassedByReference()
+ {
+ return $this->byReference;
+ }
+
+ public function setAsVariadic($isVariadic = true)
+ {
+ $this->isVariadic = $isVariadic;
+ }
+
+ public function isVariadic()
+ {
+ return $this->isVariadic;
+ }
+
+ public function isNullable()
+ {
+ return $this->isNullable;
+ }
+
+ public function setAsNullable($isNullable = true)
+ {
+ $this->isNullable = $isNullable;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ClassNode.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ClassNode.php
new file mode 100644
index 0000000..f7bd285
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ClassNode.php
@@ -0,0 +1,169 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler\Generator\Node;
+
+use Prophecy\Exception\Doubler\MethodNotExtendableException;
+use Prophecy\Exception\InvalidArgumentException;
+
+/**
+ * Class node.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ClassNode
+{
+ private $parentClass = 'stdClass';
+ private $interfaces = array();
+ private $properties = array();
+ private $unextendableMethods = array();
+
+ /**
+ * @var MethodNode[]
+ */
+ private $methods = array();
+
+ public function getParentClass()
+ {
+ return $this->parentClass;
+ }
+
+ /**
+ * @param string $class
+ */
+ public function setParentClass($class)
+ {
+ $this->parentClass = $class ?: 'stdClass';
+ }
+
+ /**
+ * @return string[]
+ */
+ public function getInterfaces()
+ {
+ return $this->interfaces;
+ }
+
+ /**
+ * @param string $interface
+ */
+ public function addInterface($interface)
+ {
+ if ($this->hasInterface($interface)) {
+ return;
+ }
+
+ array_unshift($this->interfaces, $interface);
+ }
+
+ /**
+ * @param string $interface
+ *
+ * @return bool
+ */
+ public function hasInterface($interface)
+ {
+ return in_array($interface, $this->interfaces);
+ }
+
+ public function getProperties()
+ {
+ return $this->properties;
+ }
+
+ public function addProperty($name, $visibility = 'public')
+ {
+ $visibility = strtolower($visibility);
+
+ if (!in_array($visibility, array('public', 'private', 'protected'))) {
+ throw new InvalidArgumentException(sprintf(
+ '`%s` property visibility is not supported.', $visibility
+ ));
+ }
+
+ $this->properties[$name] = $visibility;
+ }
+
+ /**
+ * @return MethodNode[]
+ */
+ public function getMethods()
+ {
+ return $this->methods;
+ }
+
+ public function addMethod(MethodNode $method, $force = false)
+ {
+ if (!$this->isExtendable($method->getName())){
+ $message = sprintf(
+ 'Method `%s` is not extendable, so can not be added.', $method->getName()
+ );
+ throw new MethodNotExtendableException($message, $this->getParentClass(), $method->getName());
+ }
+
+ if ($force || !isset($this->methods[$method->getName()])) {
+ $this->methods[$method->getName()] = $method;
+ }
+ }
+
+ public function removeMethod($name)
+ {
+ unset($this->methods[$name]);
+ }
+
+ /**
+ * @param string $name
+ *
+ * @return MethodNode|null
+ */
+ public function getMethod($name)
+ {
+ return $this->hasMethod($name) ? $this->methods[$name] : null;
+ }
+
+ /**
+ * @param string $name
+ *
+ * @return bool
+ */
+ public function hasMethod($name)
+ {
+ return isset($this->methods[$name]);
+ }
+
+ /**
+ * @return string[]
+ */
+ public function getUnextendableMethods()
+ {
+ return $this->unextendableMethods;
+ }
+
+ /**
+ * @param string $unextendableMethod
+ */
+ public function addUnextendableMethod($unextendableMethod)
+ {
+ if (!$this->isExtendable($unextendableMethod)){
+ return;
+ }
+ $this->unextendableMethods[] = $unextendableMethod;
+ }
+
+ /**
+ * @param string $method
+ * @return bool
+ */
+ public function isExtendable($method)
+ {
+ return !in_array($method, $this->unextendableMethods);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php
new file mode 100644
index 0000000..c74b483
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php
@@ -0,0 +1,198 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler\Generator\Node;
+
+use Prophecy\Doubler\Generator\TypeHintReference;
+use Prophecy\Exception\InvalidArgumentException;
+
+/**
+ * Method node.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class MethodNode
+{
+ private $name;
+ private $code;
+ private $visibility = 'public';
+ private $static = false;
+ private $returnsReference = false;
+ private $returnType;
+ private $nullableReturnType = false;
+
+ /**
+ * @var ArgumentNode[]
+ */
+ private $arguments = array();
+
+ /**
+ * @var TypeHintReference
+ */
+ private $typeHintReference;
+
+ /**
+ * @param string $name
+ * @param string $code
+ */
+ public function __construct($name, $code = null, TypeHintReference $typeHintReference = null)
+ {
+ $this->name = $name;
+ $this->code = $code;
+ $this->typeHintReference = $typeHintReference ?: new TypeHintReference();
+ }
+
+ public function getVisibility()
+ {
+ return $this->visibility;
+ }
+
+ /**
+ * @param string $visibility
+ */
+ public function setVisibility($visibility)
+ {
+ $visibility = strtolower($visibility);
+
+ if (!in_array($visibility, array('public', 'private', 'protected'))) {
+ throw new InvalidArgumentException(sprintf(
+ '`%s` method visibility is not supported.', $visibility
+ ));
+ }
+
+ $this->visibility = $visibility;
+ }
+
+ public function isStatic()
+ {
+ return $this->static;
+ }
+
+ public function setStatic($static = true)
+ {
+ $this->static = (bool) $static;
+ }
+
+ public function returnsReference()
+ {
+ return $this->returnsReference;
+ }
+
+ public function setReturnsReference()
+ {
+ $this->returnsReference = true;
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function addArgument(ArgumentNode $argument)
+ {
+ $this->arguments[] = $argument;
+ }
+
+ /**
+ * @return ArgumentNode[]
+ */
+ public function getArguments()
+ {
+ return $this->arguments;
+ }
+
+ public function hasReturnType()
+ {
+ return null !== $this->returnType;
+ }
+
+ /**
+ * @param string $type
+ */
+ public function setReturnType($type = null)
+ {
+ if ($type === '' || $type === null) {
+ $this->returnType = null;
+ return;
+ }
+ $typeMap = array(
+ 'double' => 'float',
+ 'real' => 'float',
+ 'boolean' => 'bool',
+ 'integer' => 'int',
+ );
+ if (isset($typeMap[$type])) {
+ $type = $typeMap[$type];
+ }
+ $this->returnType = $this->typeHintReference->isBuiltInReturnTypeHint($type) ?
+ $type :
+ '\\' . ltrim($type, '\\');
+ }
+
+ public function getReturnType()
+ {
+ return $this->returnType;
+ }
+
+ /**
+ * @param bool $bool
+ */
+ public function setNullableReturnType($bool = true)
+ {
+ $this->nullableReturnType = (bool) $bool;
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasNullableReturnType()
+ {
+ return $this->nullableReturnType;
+ }
+
+ /**
+ * @param string $code
+ */
+ public function setCode($code)
+ {
+ $this->code = $code;
+ }
+
+ public function getCode()
+ {
+ if ($this->returnsReference)
+ {
+ return "throw new \Prophecy\Exception\Doubler\ReturnByReferenceException('Returning by reference not supported', get_class(\$this), '{$this->name}');";
+ }
+
+ return (string) $this->code;
+ }
+
+ public function useParentCode()
+ {
+ $this->code = sprintf(
+ 'return parent::%s(%s);', $this->getName(), implode(', ',
+ array_map(array($this, 'generateArgument'), $this->arguments)
+ )
+ );
+ }
+
+ private function generateArgument(ArgumentNode $arg)
+ {
+ $argument = '$'.$arg->getName();
+
+ if ($arg->isVariadic()) {
+ $argument = '...'.$argument;
+ }
+
+ return $argument;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php
new file mode 100644
index 0000000..d720b15
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler\Generator;
+
+/**
+ * Reflection interface.
+ * All reflected classes implement this interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ReflectionInterface
+{
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/TypeHintReference.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/TypeHintReference.php
new file mode 100644
index 0000000..ce95202
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/TypeHintReference.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Prophecy\Doubler\Generator;
+
+/**
+ * Tells whether a keyword refers to a class or to a built-in type for the
+ * current version of php
+ */
+final class TypeHintReference
+{
+ public function isBuiltInParamTypeHint($type)
+ {
+ switch ($type) {
+ case 'self':
+ case 'array':
+ return true;
+
+ case 'callable':
+ return PHP_VERSION_ID >= 50400;
+
+ case 'bool':
+ case 'float':
+ case 'int':
+ case 'string':
+ return PHP_VERSION_ID >= 70000;
+
+ case 'iterable':
+ return PHP_VERSION_ID >= 70100;
+
+ case 'object':
+ return PHP_VERSION_ID >= 70200;
+
+ default:
+ return false;
+ }
+ }
+
+ public function isBuiltInReturnTypeHint($type)
+ {
+ if ($type === 'void') {
+ return PHP_VERSION_ID >= 70100;
+ }
+
+ return $this->isBuiltInParamTypeHint($type);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php
new file mode 100644
index 0000000..8a99c4c
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php
@@ -0,0 +1,127 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler;
+
+use Prophecy\Exception\Doubler\DoubleException;
+use Prophecy\Exception\Doubler\ClassNotFoundException;
+use Prophecy\Exception\Doubler\InterfaceNotFoundException;
+use ReflectionClass;
+
+/**
+ * Lazy double.
+ * Gives simple interface to describe double before creating it.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class LazyDouble
+{
+ private $doubler;
+ private $class;
+ private $interfaces = array();
+ private $arguments = null;
+ private $double;
+
+ /**
+ * Initializes lazy double.
+ *
+ * @param Doubler $doubler
+ */
+ public function __construct(Doubler $doubler)
+ {
+ $this->doubler = $doubler;
+ }
+
+ /**
+ * Tells doubler to use specific class as parent one for double.
+ *
+ * @param string|ReflectionClass $class
+ *
+ * @throws \Prophecy\Exception\Doubler\ClassNotFoundException
+ * @throws \Prophecy\Exception\Doubler\DoubleException
+ */
+ public function setParentClass($class)
+ {
+ if (null !== $this->double) {
+ throw new DoubleException('Can not extend class with already instantiated double.');
+ }
+
+ if (!$class instanceof ReflectionClass) {
+ if (!class_exists($class)) {
+ throw new ClassNotFoundException(sprintf('Class %s not found.', $class), $class);
+ }
+
+ $class = new ReflectionClass($class);
+ }
+
+ $this->class = $class;
+ }
+
+ /**
+ * Tells doubler to implement specific interface with double.
+ *
+ * @param string|ReflectionClass $interface
+ *
+ * @throws \Prophecy\Exception\Doubler\InterfaceNotFoundException
+ * @throws \Prophecy\Exception\Doubler\DoubleException
+ */
+ public function addInterface($interface)
+ {
+ if (null !== $this->double) {
+ throw new DoubleException(
+ 'Can not implement interface with already instantiated double.'
+ );
+ }
+
+ if (!$interface instanceof ReflectionClass) {
+ if (!interface_exists($interface)) {
+ throw new InterfaceNotFoundException(
+ sprintf('Interface %s not found.', $interface),
+ $interface
+ );
+ }
+
+ $interface = new ReflectionClass($interface);
+ }
+
+ $this->interfaces[] = $interface;
+ }
+
+ /**
+ * Sets constructor arguments.
+ *
+ * @param array $arguments
+ */
+ public function setArguments(array $arguments = null)
+ {
+ $this->arguments = $arguments;
+ }
+
+ /**
+ * Creates double instance or returns already created one.
+ *
+ * @return DoubleInterface
+ */
+ public function getInstance()
+ {
+ if (null === $this->double) {
+ if (null !== $this->arguments) {
+ return $this->double = $this->doubler->double(
+ $this->class, $this->interfaces, $this->arguments
+ );
+ }
+
+ $this->double = $this->doubler->double($this->class, $this->interfaces);
+ }
+
+ return $this->double;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php
new file mode 100644
index 0000000..d67ec6a
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Doubler;
+
+use ReflectionClass;
+
+/**
+ * Name generator.
+ * Generates classname for double.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class NameGenerator
+{
+ private static $counter = 1;
+
+ /**
+ * Generates name.
+ *
+ * @param ReflectionClass $class
+ * @param ReflectionClass[] $interfaces
+ *
+ * @return string
+ */
+ public function name(ReflectionClass $class = null, array $interfaces)
+ {
+ $parts = array();
+
+ if (null !== $class) {
+ $parts[] = $class->getName();
+ } else {
+ foreach ($interfaces as $interface) {
+ $parts[] = $interface->getShortName();
+ }
+ }
+
+ if (!count($parts)) {
+ $parts[] = 'stdClass';
+ }
+
+ return sprintf('Double\%s\P%d', implode('\\', $parts), self::$counter++);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php
new file mode 100644
index 0000000..48ed225
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception\Call;
+
+use Prophecy\Exception\Prophecy\ObjectProphecyException;
+use Prophecy\Prophecy\ObjectProphecy;
+
+class UnexpectedCallException extends ObjectProphecyException
+{
+ private $methodName;
+ private $arguments;
+
+ public function __construct($message, ObjectProphecy $objectProphecy,
+ $methodName, array $arguments)
+ {
+ parent::__construct($message, $objectProphecy);
+
+ $this->methodName = $methodName;
+ $this->arguments = $arguments;
+ }
+
+ public function getMethodName()
+ {
+ return $this->methodName;
+ }
+
+ public function getArguments()
+ {
+ return $this->arguments;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php
new file mode 100644
index 0000000..822918a
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception\Doubler;
+
+use Prophecy\Doubler\Generator\Node\ClassNode;
+
+class ClassCreatorException extends \RuntimeException implements DoublerException
+{
+ private $node;
+
+ public function __construct($message, ClassNode $node)
+ {
+ parent::__construct($message);
+
+ $this->node = $node;
+ }
+
+ public function getClassNode()
+ {
+ return $this->node;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php
new file mode 100644
index 0000000..8fc53b8
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception\Doubler;
+
+use ReflectionClass;
+
+class ClassMirrorException extends \RuntimeException implements DoublerException
+{
+ private $class;
+
+ public function __construct($message, ReflectionClass $class)
+ {
+ parent::__construct($message);
+
+ $this->class = $class;
+ }
+
+ public function getReflectedClass()
+ {
+ return $this->class;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php
new file mode 100644
index 0000000..5bc826d
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception\Doubler;
+
+class ClassNotFoundException extends DoubleException
+{
+ private $classname;
+
+ /**
+ * @param string $message
+ * @param string $classname
+ */
+ public function __construct($message, $classname)
+ {
+ parent::__construct($message);
+
+ $this->classname = $classname;
+ }
+
+ public function getClassname()
+ {
+ return $this->classname;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php
new file mode 100644
index 0000000..6642a58
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception\Doubler;
+
+use RuntimeException;
+
+class DoubleException extends RuntimeException implements DoublerException
+{
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php
new file mode 100644
index 0000000..9d6be17
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception\Doubler;
+
+use Prophecy\Exception\Exception;
+
+interface DoublerException extends Exception
+{
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php
new file mode 100644
index 0000000..e344dea
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php
@@ -0,0 +1,20 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception\Doubler;
+
+class InterfaceNotFoundException extends ClassNotFoundException
+{
+ public function getInterfaceName()
+ {
+ return $this->getClassname();
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotExtendableException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotExtendableException.php
new file mode 100644
index 0000000..56f47b1
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotExtendableException.php
@@ -0,0 +1,41 @@
+<?php
+
+ namespace Prophecy\Exception\Doubler;
+
+ class MethodNotExtendableException extends DoubleException
+ {
+ private $methodName;
+
+ private $className;
+
+ /**
+ * @param string $message
+ * @param string $className
+ * @param string $methodName
+ */
+ public function __construct($message, $className, $methodName)
+ {
+ parent::__construct($message);
+
+ $this->methodName = $methodName;
+ $this->className = $className;
+ }
+
+
+ /**
+ * @return string
+ */
+ public function getMethodName()
+ {
+ return $this->methodName;
+ }
+
+ /**
+ * @return string
+ */
+ public function getClassName()
+ {
+ return $this->className;
+ }
+
+ }
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php
new file mode 100644
index 0000000..a538349
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception\Doubler;
+
+class MethodNotFoundException extends DoubleException
+{
+ /**
+ * @var string|object
+ */
+ private $classname;
+
+ /**
+ * @var string
+ */
+ private $methodName;
+
+ /**
+ * @var array
+ */
+ private $arguments;
+
+ /**
+ * @param string $message
+ * @param string|object $classname
+ * @param string $methodName
+ * @param null|Argument\ArgumentsWildcard|array $arguments
+ */
+ public function __construct($message, $classname, $methodName, $arguments = null)
+ {
+ parent::__construct($message);
+
+ $this->classname = $classname;
+ $this->methodName = $methodName;
+ $this->arguments = $arguments;
+ }
+
+ public function getClassname()
+ {
+ return $this->classname;
+ }
+
+ public function getMethodName()
+ {
+ return $this->methodName;
+ }
+
+ public function getArguments()
+ {
+ return $this->arguments;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php
new file mode 100644
index 0000000..6303049
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception\Doubler;
+
+class ReturnByReferenceException extends DoubleException
+{
+ private $classname;
+ private $methodName;
+
+ /**
+ * @param string $message
+ * @param string $classname
+ * @param string $methodName
+ */
+ public function __construct($message, $classname, $methodName)
+ {
+ parent::__construct($message);
+
+ $this->classname = $classname;
+ $this->methodName = $methodName;
+ }
+
+ public function getClassname()
+ {
+ return $this->classname;
+ }
+
+ public function getMethodName()
+ {
+ return $this->methodName;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Exception.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Exception.php
new file mode 100644
index 0000000..ac9fe4d
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Exception.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception;
+
+/**
+ * Core Prophecy exception interface.
+ * All Prophecy exceptions implement it.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface Exception
+{
+ /**
+ * @return string
+ */
+ public function getMessage();
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php
new file mode 100644
index 0000000..bc91c69
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php
@@ -0,0 +1,16 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception;
+
+class InvalidArgumentException extends \InvalidArgumentException implements Exception
+{
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php
new file mode 100644
index 0000000..a00dfb0
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php
@@ -0,0 +1,51 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception\Prediction;
+
+use Prophecy\Prophecy\ObjectProphecy;
+
+class AggregateException extends \RuntimeException implements PredictionException
+{
+ private $exceptions = array();
+ private $objectProphecy;
+
+ public function append(PredictionException $exception)
+ {
+ $message = $exception->getMessage();
+ $message = strtr($message, array("\n" => "\n "))."\n";
+ $message = empty($this->exceptions) ? $message : "\n" . $message;
+
+ $this->message = rtrim($this->message.$message);
+ $this->exceptions[] = $exception;
+ }
+
+ /**
+ * @return PredictionException[]
+ */
+ public function getExceptions()
+ {
+ return $this->exceptions;
+ }
+
+ public function setObjectProphecy(ObjectProphecy $objectProphecy)
+ {
+ $this->objectProphecy = $objectProphecy;
+ }
+
+ /**
+ * @return ObjectProphecy
+ */
+ public function getObjectProphecy()
+ {
+ return $this->objectProphecy;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php
new file mode 100644
index 0000000..bbbbc3d
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception\Prediction;
+
+use RuntimeException;
+
+/**
+ * Basic failed prediction exception.
+ * Use it for custom prediction failures.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class FailedPredictionException extends RuntimeException implements PredictionException
+{
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php
new file mode 100644
index 0000000..05ea4aa
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception\Prediction;
+
+use Prophecy\Exception\Prophecy\MethodProphecyException;
+
+class NoCallsException extends MethodProphecyException implements PredictionException
+{
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php
new file mode 100644
index 0000000..2596b1e
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception\Prediction;
+
+use Prophecy\Exception\Exception;
+
+interface PredictionException extends Exception
+{
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php
new file mode 100644
index 0000000..9d90543
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception\Prediction;
+
+use Prophecy\Prophecy\MethodProphecy;
+
+class UnexpectedCallsCountException extends UnexpectedCallsException
+{
+ private $expectedCount;
+
+ public function __construct($message, MethodProphecy $methodProphecy, $count, array $calls)
+ {
+ parent::__construct($message, $methodProphecy, $calls);
+
+ $this->expectedCount = intval($count);
+ }
+
+ public function getExpectedCount()
+ {
+ return $this->expectedCount;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php
new file mode 100644
index 0000000..7a99c2d
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception\Prediction;
+
+use Prophecy\Prophecy\MethodProphecy;
+use Prophecy\Exception\Prophecy\MethodProphecyException;
+
+class UnexpectedCallsException extends MethodProphecyException implements PredictionException
+{
+ private $calls = array();
+
+ public function __construct($message, MethodProphecy $methodProphecy, array $calls)
+ {
+ parent::__construct($message, $methodProphecy);
+
+ $this->calls = $calls;
+ }
+
+ public function getCalls()
+ {
+ return $this->calls;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php
new file mode 100644
index 0000000..1b03eaf
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception\Prophecy;
+
+use Prophecy\Prophecy\MethodProphecy;
+
+class MethodProphecyException extends ObjectProphecyException
+{
+ private $methodProphecy;
+
+ public function __construct($message, MethodProphecy $methodProphecy)
+ {
+ parent::__construct($message, $methodProphecy->getObjectProphecy());
+
+ $this->methodProphecy = $methodProphecy;
+ }
+
+ /**
+ * @return MethodProphecy
+ */
+ public function getMethodProphecy()
+ {
+ return $this->methodProphecy;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php
new file mode 100644
index 0000000..e345402
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception\Prophecy;
+
+use Prophecy\Prophecy\ObjectProphecy;
+
+class ObjectProphecyException extends \RuntimeException implements ProphecyException
+{
+ private $objectProphecy;
+
+ public function __construct($message, ObjectProphecy $objectProphecy)
+ {
+ parent::__construct($message);
+
+ $this->objectProphecy = $objectProphecy;
+ }
+
+ /**
+ * @return ObjectProphecy
+ */
+ public function getObjectProphecy()
+ {
+ return $this->objectProphecy;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php
new file mode 100644
index 0000000..9157332
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Exception\Prophecy;
+
+use Prophecy\Exception\Exception;
+
+interface ProphecyException extends Exception
+{
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassAndInterfaceTagRetriever.php b/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassAndInterfaceTagRetriever.php
new file mode 100644
index 0000000..209821c
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassAndInterfaceTagRetriever.php
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\PhpDocumentor;
+
+use phpDocumentor\Reflection\DocBlock\Tag\MethodTag as LegacyMethodTag;
+use phpDocumentor\Reflection\DocBlock\Tags\Method;
+
+/**
+ * @author Théo FIDRY <theo.fidry@gmail.com>
+ *
+ * @internal
+ */
+final class ClassAndInterfaceTagRetriever implements MethodTagRetrieverInterface
+{
+ private $classRetriever;
+
+ public function __construct(MethodTagRetrieverInterface $classRetriever = null)
+ {
+ if (null !== $classRetriever) {
+ $this->classRetriever = $classRetriever;
+
+ return;
+ }
+
+ $this->classRetriever = class_exists('phpDocumentor\Reflection\DocBlockFactory') && class_exists('phpDocumentor\Reflection\Types\ContextFactory')
+ ? new ClassTagRetriever()
+ : new LegacyClassTagRetriever()
+ ;
+ }
+
+ /**
+ * @param \ReflectionClass $reflectionClass
+ *
+ * @return LegacyMethodTag[]|Method[]
+ */
+ public function getTagList(\ReflectionClass $reflectionClass)
+ {
+ return array_merge(
+ $this->classRetriever->getTagList($reflectionClass),
+ $this->getInterfacesTagList($reflectionClass)
+ );
+ }
+
+ /**
+ * @param \ReflectionClass $reflectionClass
+ *
+ * @return LegacyMethodTag[]|Method[]
+ */
+ private function getInterfacesTagList(\ReflectionClass $reflectionClass)
+ {
+ $interfaces = $reflectionClass->getInterfaces();
+ $tagList = array();
+
+ foreach($interfaces as $interface) {
+ $tagList = array_merge($tagList, $this->classRetriever->getTagList($interface));
+ }
+
+ return $tagList;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassTagRetriever.php b/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassTagRetriever.php
new file mode 100644
index 0000000..1d2da8f
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassTagRetriever.php
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\PhpDocumentor;
+
+use phpDocumentor\Reflection\DocBlock\Tags\Method;
+use phpDocumentor\Reflection\DocBlockFactory;
+use phpDocumentor\Reflection\Types\ContextFactory;
+
+/**
+ * @author Théo FIDRY <theo.fidry@gmail.com>
+ *
+ * @internal
+ */
+final class ClassTagRetriever implements MethodTagRetrieverInterface
+{
+ private $docBlockFactory;
+ private $contextFactory;
+
+ public function __construct()
+ {
+ $this->docBlockFactory = DocBlockFactory::createInstance();
+ $this->contextFactory = new ContextFactory();
+ }
+
+ /**
+ * @param \ReflectionClass $reflectionClass
+ *
+ * @return Method[]
+ */
+ public function getTagList(\ReflectionClass $reflectionClass)
+ {
+ try {
+ $phpdoc = $this->docBlockFactory->create(
+ $reflectionClass,
+ $this->contextFactory->createFromReflector($reflectionClass)
+ );
+
+ return $phpdoc->getTagsByName('method');
+ } catch (\InvalidArgumentException $e) {
+ return array();
+ }
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/LegacyClassTagRetriever.php b/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/LegacyClassTagRetriever.php
new file mode 100644
index 0000000..c0dec3d
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/LegacyClassTagRetriever.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\PhpDocumentor;
+
+use phpDocumentor\Reflection\DocBlock;
+use phpDocumentor\Reflection\DocBlock\Tag\MethodTag as LegacyMethodTag;
+
+/**
+ * @author Théo FIDRY <theo.fidry@gmail.com>
+ *
+ * @internal
+ */
+final class LegacyClassTagRetriever implements MethodTagRetrieverInterface
+{
+ /**
+ * @param \ReflectionClass $reflectionClass
+ *
+ * @return LegacyMethodTag[]
+ */
+ public function getTagList(\ReflectionClass $reflectionClass)
+ {
+ $phpdoc = new DocBlock($reflectionClass->getDocComment());
+
+ return $phpdoc->getTagsByName('method');
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/MethodTagRetrieverInterface.php b/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/MethodTagRetrieverInterface.php
new file mode 100644
index 0000000..d3989da
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/MethodTagRetrieverInterface.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\PhpDocumentor;
+
+use phpDocumentor\Reflection\DocBlock\Tag\MethodTag as LegacyMethodTag;
+use phpDocumentor\Reflection\DocBlock\Tags\Method;
+
+/**
+ * @author Théo FIDRY <theo.fidry@gmail.com>
+ *
+ * @internal
+ */
+interface MethodTagRetrieverInterface
+{
+ /**
+ * @param \ReflectionClass $reflectionClass
+ *
+ * @return LegacyMethodTag[]|Method[]
+ */
+ public function getTagList(\ReflectionClass $reflectionClass);
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php b/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php
new file mode 100644
index 0000000..b478736
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php
@@ -0,0 +1,86 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Prediction;
+
+use Prophecy\Call\Call;
+use Prophecy\Prophecy\ObjectProphecy;
+use Prophecy\Prophecy\MethodProphecy;
+use Prophecy\Argument\ArgumentsWildcard;
+use Prophecy\Argument\Token\AnyValuesToken;
+use Prophecy\Util\StringUtil;
+use Prophecy\Exception\Prediction\NoCallsException;
+
+/**
+ * Call prediction.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class CallPrediction implements PredictionInterface
+{
+ private $util;
+
+ /**
+ * Initializes prediction.
+ *
+ * @param StringUtil $util
+ */
+ public function __construct(StringUtil $util = null)
+ {
+ $this->util = $util ?: new StringUtil;
+ }
+
+ /**
+ * Tests that there was at least one call.
+ *
+ * @param Call[] $calls
+ * @param ObjectProphecy $object
+ * @param MethodProphecy $method
+ *
+ * @throws \Prophecy\Exception\Prediction\NoCallsException
+ */
+ public function check(array $calls, ObjectProphecy $object, MethodProphecy $method)
+ {
+ if (count($calls)) {
+ return;
+ }
+
+ $methodCalls = $object->findProphecyMethodCalls(
+ $method->getMethodName(),
+ new ArgumentsWildcard(array(new AnyValuesToken))
+ );
+
+ if (count($methodCalls)) {
+ throw new NoCallsException(sprintf(
+ "No calls have been made that match:\n".
+ " %s->%s(%s)\n".
+ "but expected at least one.\n".
+ "Recorded `%s(...)` calls:\n%s",
+
+ get_class($object->reveal()),
+ $method->getMethodName(),
+ $method->getArgumentsWildcard(),
+ $method->getMethodName(),
+ $this->util->stringifyCalls($methodCalls)
+ ), $method);
+ }
+
+ throw new NoCallsException(sprintf(
+ "No calls have been made that match:\n".
+ " %s->%s(%s)\n".
+ "but expected at least one.",
+
+ get_class($object->reveal()),
+ $method->getMethodName(),
+ $method->getArgumentsWildcard()
+ ), $method);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php b/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php
new file mode 100644
index 0000000..31c6c57
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php
@@ -0,0 +1,107 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Prediction;
+
+use Prophecy\Call\Call;
+use Prophecy\Prophecy\ObjectProphecy;
+use Prophecy\Prophecy\MethodProphecy;
+use Prophecy\Argument\ArgumentsWildcard;
+use Prophecy\Argument\Token\AnyValuesToken;
+use Prophecy\Util\StringUtil;
+use Prophecy\Exception\Prediction\UnexpectedCallsCountException;
+
+/**
+ * Prediction interface.
+ * Predictions are logical test blocks, tied to `should...` keyword.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class CallTimesPrediction implements PredictionInterface
+{
+ private $times;
+ private $util;
+
+ /**
+ * Initializes prediction.
+ *
+ * @param int $times
+ * @param StringUtil $util
+ */
+ public function __construct($times, StringUtil $util = null)
+ {
+ $this->times = intval($times);
+ $this->util = $util ?: new StringUtil;
+ }
+
+ /**
+ * Tests that there was exact amount of calls made.
+ *
+ * @param Call[] $calls
+ * @param ObjectProphecy $object
+ * @param MethodProphecy $method
+ *
+ * @throws \Prophecy\Exception\Prediction\UnexpectedCallsCountException
+ */
+ public function check(array $calls, ObjectProphecy $object, MethodProphecy $method)
+ {
+ if ($this->times == count($calls)) {
+ return;
+ }
+
+ $methodCalls = $object->findProphecyMethodCalls(
+ $method->getMethodName(),
+ new ArgumentsWildcard(array(new AnyValuesToken))
+ );
+
+ if (count($calls)) {
+ $message = sprintf(
+ "Expected exactly %d calls that match:\n".
+ " %s->%s(%s)\n".
+ "but %d were made:\n%s",
+
+ $this->times,
+ get_class($object->reveal()),
+ $method->getMethodName(),
+ $method->getArgumentsWildcard(),
+ count($calls),
+ $this->util->stringifyCalls($calls)
+ );
+ } elseif (count($methodCalls)) {
+ $message = sprintf(
+ "Expected exactly %d calls that match:\n".
+ " %s->%s(%s)\n".
+ "but none were made.\n".
+ "Recorded `%s(...)` calls:\n%s",
+
+ $this->times,
+ get_class($object->reveal()),
+ $method->getMethodName(),
+ $method->getArgumentsWildcard(),
+ $method->getMethodName(),
+ $this->util->stringifyCalls($methodCalls)
+ );
+ } else {
+ $message = sprintf(
+ "Expected exactly %d calls that match:\n".
+ " %s->%s(%s)\n".
+ "but none were made.",
+
+ $this->times,
+ get_class($object->reveal()),
+ $method->getMethodName(),
+ $method->getArgumentsWildcard()
+ );
+ }
+
+ throw new UnexpectedCallsCountException($message, $method, $this->times, $calls);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php b/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php
new file mode 100644
index 0000000..44bc782
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Prediction;
+
+use Prophecy\Call\Call;
+use Prophecy\Prophecy\ObjectProphecy;
+use Prophecy\Prophecy\MethodProphecy;
+use Prophecy\Exception\InvalidArgumentException;
+use Closure;
+
+/**
+ * Callback prediction.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class CallbackPrediction implements PredictionInterface
+{
+ private $callback;
+
+ /**
+ * Initializes callback prediction.
+ *
+ * @param callable $callback Custom callback
+ *
+ * @throws \Prophecy\Exception\InvalidArgumentException
+ */
+ public function __construct($callback)
+ {
+ if (!is_callable($callback)) {
+ throw new InvalidArgumentException(sprintf(
+ 'Callable expected as an argument to CallbackPrediction, but got %s.',
+ gettype($callback)
+ ));
+ }
+
+ $this->callback = $callback;
+ }
+
+ /**
+ * Executes preset callback.
+ *
+ * @param Call[] $calls
+ * @param ObjectProphecy $object
+ * @param MethodProphecy $method
+ */
+ public function check(array $calls, ObjectProphecy $object, MethodProphecy $method)
+ {
+ $callback = $this->callback;
+
+ if ($callback instanceof Closure && method_exists('Closure', 'bind')) {
+ $callback = Closure::bind($callback, $object);
+ }
+
+ call_user_func($callback, $calls, $object, $method);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php b/vendor/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php
new file mode 100644
index 0000000..46ac5bf
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Prediction;
+
+use Prophecy\Call\Call;
+use Prophecy\Prophecy\ObjectProphecy;
+use Prophecy\Prophecy\MethodProphecy;
+use Prophecy\Util\StringUtil;
+use Prophecy\Exception\Prediction\UnexpectedCallsException;
+
+/**
+ * No calls prediction.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class NoCallsPrediction implements PredictionInterface
+{
+ private $util;
+
+ /**
+ * Initializes prediction.
+ *
+ * @param null|StringUtil $util
+ */
+ public function __construct(StringUtil $util = null)
+ {
+ $this->util = $util ?: new StringUtil;
+ }
+
+ /**
+ * Tests that there were no calls made.
+ *
+ * @param Call[] $calls
+ * @param ObjectProphecy $object
+ * @param MethodProphecy $method
+ *
+ * @throws \Prophecy\Exception\Prediction\UnexpectedCallsException
+ */
+ public function check(array $calls, ObjectProphecy $object, MethodProphecy $method)
+ {
+ if (!count($calls)) {
+ return;
+ }
+
+ $verb = count($calls) === 1 ? 'was' : 'were';
+
+ throw new UnexpectedCallsException(sprintf(
+ "No calls expected that match:\n".
+ " %s->%s(%s)\n".
+ "but %d %s made:\n%s",
+ get_class($object->reveal()),
+ $method->getMethodName(),
+ $method->getArgumentsWildcard(),
+ count($calls),
+ $verb,
+ $this->util->stringifyCalls($calls)
+ ), $method, $calls);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php
new file mode 100644
index 0000000..f7fb06a
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php
@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Prediction;
+
+use Prophecy\Call\Call;
+use Prophecy\Prophecy\ObjectProphecy;
+use Prophecy\Prophecy\MethodProphecy;
+
+/**
+ * Prediction interface.
+ * Predictions are logical test blocks, tied to `should...` keyword.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface PredictionInterface
+{
+ /**
+ * Tests that double fulfilled prediction.
+ *
+ * @param Call[] $calls
+ * @param ObjectProphecy $object
+ * @param MethodProphecy $method
+ *
+ * @throws object
+ * @return void
+ */
+ public function check(array $calls, ObjectProphecy $object, MethodProphecy $method);
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php b/vendor/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php
new file mode 100644
index 0000000..5f406bf
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php
@@ -0,0 +1,66 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Promise;
+
+use Prophecy\Prophecy\ObjectProphecy;
+use Prophecy\Prophecy\MethodProphecy;
+use Prophecy\Exception\InvalidArgumentException;
+use Closure;
+
+/**
+ * Callback promise.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class CallbackPromise implements PromiseInterface
+{
+ private $callback;
+
+ /**
+ * Initializes callback promise.
+ *
+ * @param callable $callback Custom callback
+ *
+ * @throws \Prophecy\Exception\InvalidArgumentException
+ */
+ public function __construct($callback)
+ {
+ if (!is_callable($callback)) {
+ throw new InvalidArgumentException(sprintf(
+ 'Callable expected as an argument to CallbackPromise, but got %s.',
+ gettype($callback)
+ ));
+ }
+
+ $this->callback = $callback;
+ }
+
+ /**
+ * Evaluates promise callback.
+ *
+ * @param array $args
+ * @param ObjectProphecy $object
+ * @param MethodProphecy $method
+ *
+ * @return mixed
+ */
+ public function execute(array $args, ObjectProphecy $object, MethodProphecy $method)
+ {
+ $callback = $this->callback;
+
+ if ($callback instanceof Closure && method_exists('Closure', 'bind')) {
+ $callback = Closure::bind($callback, $object);
+ }
+
+ return call_user_func($callback, $args, $object, $method);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php
new file mode 100644
index 0000000..382537b
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Promise;
+
+use Prophecy\Prophecy\ObjectProphecy;
+use Prophecy\Prophecy\MethodProphecy;
+
+/**
+ * Promise interface.
+ * Promises are logical blocks, tied to `will...` keyword.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface PromiseInterface
+{
+ /**
+ * Evaluates promise.
+ *
+ * @param array $args
+ * @param ObjectProphecy $object
+ * @param MethodProphecy $method
+ *
+ * @return mixed
+ */
+ public function execute(array $args, ObjectProphecy $object, MethodProphecy $method);
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php b/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php
new file mode 100644
index 0000000..39bfeea
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Promise;
+
+use Prophecy\Exception\InvalidArgumentException;
+use Prophecy\Prophecy\ObjectProphecy;
+use Prophecy\Prophecy\MethodProphecy;
+
+/**
+ * Return argument promise.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ReturnArgumentPromise implements PromiseInterface
+{
+ /**
+ * @var int
+ */
+ private $index;
+
+ /**
+ * Initializes callback promise.
+ *
+ * @param int $index The zero-indexed number of the argument to return
+ *
+ * @throws \Prophecy\Exception\InvalidArgumentException
+ */
+ public function __construct($index = 0)
+ {
+ if (!is_int($index) || $index < 0) {
+ throw new InvalidArgumentException(sprintf(
+ 'Zero-based index expected as argument to ReturnArgumentPromise, but got %s.',
+ $index
+ ));
+ }
+ $this->index = $index;
+ }
+
+ /**
+ * Returns nth argument if has one, null otherwise.
+ *
+ * @param array $args
+ * @param ObjectProphecy $object
+ * @param MethodProphecy $method
+ *
+ * @return null|mixed
+ */
+ public function execute(array $args, ObjectProphecy $object, MethodProphecy $method)
+ {
+ return count($args) > $this->index ? $args[$this->index] : null;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php b/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php
new file mode 100644
index 0000000..c7d5ac5
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Promise;
+
+use Prophecy\Prophecy\ObjectProphecy;
+use Prophecy\Prophecy\MethodProphecy;
+
+/**
+ * Return promise.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ReturnPromise implements PromiseInterface
+{
+ private $returnValues = array();
+
+ /**
+ * Initializes promise.
+ *
+ * @param array $returnValues Array of values
+ */
+ public function __construct(array $returnValues)
+ {
+ $this->returnValues = $returnValues;
+ }
+
+ /**
+ * Returns saved values one by one until last one, then continuously returns last value.
+ *
+ * @param array $args
+ * @param ObjectProphecy $object
+ * @param MethodProphecy $method
+ *
+ * @return mixed
+ */
+ public function execute(array $args, ObjectProphecy $object, MethodProphecy $method)
+ {
+ $value = array_shift($this->returnValues);
+
+ if (!count($this->returnValues)) {
+ $this->returnValues[] = $value;
+ }
+
+ return $value;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php b/vendor/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php
new file mode 100644
index 0000000..7250fa3
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php
@@ -0,0 +1,99 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Promise;
+
+use Doctrine\Instantiator\Instantiator;
+use Prophecy\Prophecy\ObjectProphecy;
+use Prophecy\Prophecy\MethodProphecy;
+use Prophecy\Exception\InvalidArgumentException;
+use ReflectionClass;
+
+/**
+ * Throw promise.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ThrowPromise implements PromiseInterface
+{
+ private $exception;
+
+ /**
+ * @var \Doctrine\Instantiator\Instantiator
+ */
+ private $instantiator;
+
+ /**
+ * Initializes promise.
+ *
+ * @param string|\Exception|\Throwable $exception Exception class name or instance
+ *
+ * @throws \Prophecy\Exception\InvalidArgumentException
+ */
+ public function __construct($exception)
+ {
+ if (is_string($exception)) {
+ if (!class_exists($exception) || !$this->isAValidThrowable($exception)) {
+ throw new InvalidArgumentException(sprintf(
+ 'Exception / Throwable class or instance expected as argument to ThrowPromise, but got %s.',
+ $exception
+ ));
+ }
+ } elseif (!$exception instanceof \Exception && !$exception instanceof \Throwable) {
+ throw new InvalidArgumentException(sprintf(
+ 'Exception / Throwable class or instance expected as argument to ThrowPromise, but got %s.',
+ is_object($exception) ? get_class($exception) : gettype($exception)
+ ));
+ }
+
+ $this->exception = $exception;
+ }
+
+ /**
+ * Throws predefined exception.
+ *
+ * @param array $args
+ * @param ObjectProphecy $object
+ * @param MethodProphecy $method
+ *
+ * @throws object
+ */
+ public function execute(array $args, ObjectProphecy $object, MethodProphecy $method)
+ {
+ if (is_string($this->exception)) {
+ $classname = $this->exception;
+ $reflection = new ReflectionClass($classname);
+ $constructor = $reflection->getConstructor();
+
+ if ($constructor->isPublic() && 0 == $constructor->getNumberOfRequiredParameters()) {
+ throw $reflection->newInstance();
+ }
+
+ if (!$this->instantiator) {
+ $this->instantiator = new Instantiator();
+ }
+
+ throw $this->instantiator->instantiate($classname);
+ }
+
+ throw $this->exception;
+ }
+
+ /**
+ * @param string $exception
+ *
+ * @return bool
+ */
+ private function isAValidThrowable($exception)
+ {
+ return is_a($exception, 'Exception', true) || is_subclass_of($exception, 'Throwable', true);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php
new file mode 100644
index 0000000..7084ed6
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php
@@ -0,0 +1,488 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Prophecy;
+
+use Prophecy\Argument;
+use Prophecy\Prophet;
+use Prophecy\Promise;
+use Prophecy\Prediction;
+use Prophecy\Exception\Doubler\MethodNotFoundException;
+use Prophecy\Exception\InvalidArgumentException;
+use Prophecy\Exception\Prophecy\MethodProphecyException;
+
+/**
+ * Method prophecy.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class MethodProphecy
+{
+ private $objectProphecy;
+ private $methodName;
+ private $argumentsWildcard;
+ private $promise;
+ private $prediction;
+ private $checkedPredictions = array();
+ private $bound = false;
+ private $voidReturnType = false;
+
+ /**
+ * Initializes method prophecy.
+ *
+ * @param ObjectProphecy $objectProphecy
+ * @param string $methodName
+ * @param null|Argument\ArgumentsWildcard|array $arguments
+ *
+ * @throws \Prophecy\Exception\Doubler\MethodNotFoundException If method not found
+ */
+ public function __construct(ObjectProphecy $objectProphecy, $methodName, $arguments = null)
+ {
+ $double = $objectProphecy->reveal();
+ if (!method_exists($double, $methodName)) {
+ throw new MethodNotFoundException(sprintf(
+ 'Method `%s::%s()` is not defined.', get_class($double), $methodName
+ ), get_class($double), $methodName, $arguments);
+ }
+
+ $this->objectProphecy = $objectProphecy;
+ $this->methodName = $methodName;
+
+ $reflectedMethod = new \ReflectionMethod($double, $methodName);
+ if ($reflectedMethod->isFinal()) {
+ throw new MethodProphecyException(sprintf(
+ "Can not add prophecy for a method `%s::%s()`\n".
+ "as it is a final method.",
+ get_class($double),
+ $methodName
+ ), $this);
+ }
+
+ if (null !== $arguments) {
+ $this->withArguments($arguments);
+ }
+
+ if (version_compare(PHP_VERSION, '7.0', '>=') && true === $reflectedMethod->hasReturnType()) {
+ $type = (string) $reflectedMethod->getReturnType();
+
+ if ('void' === $type) {
+ $this->voidReturnType = true;
+ }
+
+ $this->will(function () use ($type) {
+ switch ($type) {
+ case 'void': return;
+ case 'string': return '';
+ case 'float': return 0.0;
+ case 'int': return 0;
+ case 'bool': return false;
+ case 'array': return array();
+
+ case 'callable':
+ case 'Closure':
+ return function () {};
+
+ case 'Traversable':
+ case 'Generator':
+ // Remove eval() when minimum version >=5.5
+ /** @var callable $generator */
+ $generator = eval('return function () { yield; };');
+ return $generator();
+
+ default:
+ $prophet = new Prophet;
+ return $prophet->prophesize($type)->reveal();
+ }
+ });
+ }
+ }
+
+ /**
+ * Sets argument wildcard.
+ *
+ * @param array|Argument\ArgumentsWildcard $arguments
+ *
+ * @return $this
+ *
+ * @throws \Prophecy\Exception\InvalidArgumentException
+ */
+ public function withArguments($arguments)
+ {
+ if (is_array($arguments)) {
+ $arguments = new Argument\ArgumentsWildcard($arguments);
+ }
+
+ if (!$arguments instanceof Argument\ArgumentsWildcard) {
+ throw new InvalidArgumentException(sprintf(
+ "Either an array or an instance of ArgumentsWildcard expected as\n".
+ 'a `MethodProphecy::withArguments()` argument, but got %s.',
+ gettype($arguments)
+ ));
+ }
+
+ $this->argumentsWildcard = $arguments;
+
+ return $this;
+ }
+
+ /**
+ * Sets custom promise to the prophecy.
+ *
+ * @param callable|Promise\PromiseInterface $promise
+ *
+ * @return $this
+ *
+ * @throws \Prophecy\Exception\InvalidArgumentException
+ */
+ public function will($promise)
+ {
+ if (is_callable($promise)) {
+ $promise = new Promise\CallbackPromise($promise);
+ }
+
+ if (!$promise instanceof Promise\PromiseInterface) {
+ throw new InvalidArgumentException(sprintf(
+ 'Expected callable or instance of PromiseInterface, but got %s.',
+ gettype($promise)
+ ));
+ }
+
+ $this->bindToObjectProphecy();
+ $this->promise = $promise;
+
+ return $this;
+ }
+
+ /**
+ * Sets return promise to the prophecy.
+ *
+ * @see \Prophecy\Promise\ReturnPromise
+ *
+ * @return $this
+ */
+ public function willReturn()
+ {
+ if ($this->voidReturnType) {
+ throw new MethodProphecyException(
+ "The method \"$this->methodName\" has a void return type, and so cannot return anything",
+ $this
+ );
+ }
+
+ return $this->will(new Promise\ReturnPromise(func_get_args()));
+ }
+
+ /**
+ * Sets return argument promise to the prophecy.
+ *
+ * @param int $index The zero-indexed number of the argument to return
+ *
+ * @see \Prophecy\Promise\ReturnArgumentPromise
+ *
+ * @return $this
+ */
+ public function willReturnArgument($index = 0)
+ {
+ if ($this->voidReturnType) {
+ throw new MethodProphecyException("The method \"$this->methodName\" has a void return type", $this);
+ }
+
+ return $this->will(new Promise\ReturnArgumentPromise($index));
+ }
+
+ /**
+ * Sets throw promise to the prophecy.
+ *
+ * @see \Prophecy\Promise\ThrowPromise
+ *
+ * @param string|\Exception $exception Exception class or instance
+ *
+ * @return $this
+ */
+ public function willThrow($exception)
+ {
+ return $this->will(new Promise\ThrowPromise($exception));
+ }
+
+ /**
+ * Sets custom prediction to the prophecy.
+ *
+ * @param callable|Prediction\PredictionInterface $prediction
+ *
+ * @return $this
+ *
+ * @throws \Prophecy\Exception\InvalidArgumentException
+ */
+ public function should($prediction)
+ {
+ if (is_callable($prediction)) {
+ $prediction = new Prediction\CallbackPrediction($prediction);
+ }
+
+ if (!$prediction instanceof Prediction\PredictionInterface) {
+ throw new InvalidArgumentException(sprintf(
+ 'Expected callable or instance of PredictionInterface, but got %s.',
+ gettype($prediction)
+ ));
+ }
+
+ $this->bindToObjectProphecy();
+ $this->prediction = $prediction;
+
+ return $this;
+ }
+
+ /**
+ * Sets call prediction to the prophecy.
+ *
+ * @see \Prophecy\Prediction\CallPrediction
+ *
+ * @return $this
+ */
+ public function shouldBeCalled()
+ {
+ return $this->should(new Prediction\CallPrediction);
+ }
+
+ /**
+ * Sets no calls prediction to the prophecy.
+ *
+ * @see \Prophecy\Prediction\NoCallsPrediction
+ *
+ * @return $this
+ */
+ public function shouldNotBeCalled()
+ {
+ return $this->should(new Prediction\NoCallsPrediction);
+ }
+
+ /**
+ * Sets call times prediction to the prophecy.
+ *
+ * @see \Prophecy\Prediction\CallTimesPrediction
+ *
+ * @param $count
+ *
+ * @return $this
+ */
+ public function shouldBeCalledTimes($count)
+ {
+ return $this->should(new Prediction\CallTimesPrediction($count));
+ }
+
+ /**
+ * Sets call times prediction to the prophecy.
+ *
+ * @see \Prophecy\Prediction\CallTimesPrediction
+ *
+ * @return $this
+ */
+ public function shouldBeCalledOnce()
+ {
+ return $this->shouldBeCalledTimes(1);
+ }
+
+ /**
+ * Checks provided prediction immediately.
+ *
+ * @param callable|Prediction\PredictionInterface $prediction
+ *
+ * @return $this
+ *
+ * @throws \Prophecy\Exception\InvalidArgumentException
+ */
+ public function shouldHave($prediction)
+ {
+ if (is_callable($prediction)) {
+ $prediction = new Prediction\CallbackPrediction($prediction);
+ }
+
+ if (!$prediction instanceof Prediction\PredictionInterface) {
+ throw new InvalidArgumentException(sprintf(
+ 'Expected callable or instance of PredictionInterface, but got %s.',
+ gettype($prediction)
+ ));
+ }
+
+ if (null === $this->promise && !$this->voidReturnType) {
+ $this->willReturn();
+ }
+
+ $calls = $this->getObjectProphecy()->findProphecyMethodCalls(
+ $this->getMethodName(),
+ $this->getArgumentsWildcard()
+ );
+
+ try {
+ $prediction->check($calls, $this->getObjectProphecy(), $this);
+ $this->checkedPredictions[] = $prediction;
+ } catch (\Exception $e) {
+ $this->checkedPredictions[] = $prediction;
+
+ throw $e;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Checks call prediction.
+ *
+ * @see \Prophecy\Prediction\CallPrediction
+ *
+ * @return $this
+ */
+ public function shouldHaveBeenCalled()
+ {
+ return $this->shouldHave(new Prediction\CallPrediction);
+ }
+
+ /**
+ * Checks no calls prediction.
+ *
+ * @see \Prophecy\Prediction\NoCallsPrediction
+ *
+ * @return $this
+ */
+ public function shouldNotHaveBeenCalled()
+ {
+ return $this->shouldHave(new Prediction\NoCallsPrediction);
+ }
+
+ /**
+ * Checks no calls prediction.
+ *
+ * @see \Prophecy\Prediction\NoCallsPrediction
+ * @deprecated
+ *
+ * @return $this
+ */
+ public function shouldNotBeenCalled()
+ {
+ return $this->shouldNotHaveBeenCalled();
+ }
+
+ /**
+ * Checks call times prediction.
+ *
+ * @see \Prophecy\Prediction\CallTimesPrediction
+ *
+ * @param int $count
+ *
+ * @return $this
+ */
+ public function shouldHaveBeenCalledTimes($count)
+ {
+ return $this->shouldHave(new Prediction\CallTimesPrediction($count));
+ }
+
+ /**
+ * Checks call times prediction.
+ *
+ * @see \Prophecy\Prediction\CallTimesPrediction
+ *
+ * @return $this
+ */
+ public function shouldHaveBeenCalledOnce()
+ {
+ return $this->shouldHaveBeenCalledTimes(1);
+ }
+
+ /**
+ * Checks currently registered [with should(...)] prediction.
+ */
+ public function checkPrediction()
+ {
+ if (null === $this->prediction) {
+ return;
+ }
+
+ $this->shouldHave($this->prediction);
+ }
+
+ /**
+ * Returns currently registered promise.
+ *
+ * @return null|Promise\PromiseInterface
+ */
+ public function getPromise()
+ {
+ return $this->promise;
+ }
+
+ /**
+ * Returns currently registered prediction.
+ *
+ * @return null|Prediction\PredictionInterface
+ */
+ public function getPrediction()
+ {
+ return $this->prediction;
+ }
+
+ /**
+ * Returns predictions that were checked on this object.
+ *
+ * @return Prediction\PredictionInterface[]
+ */
+ public function getCheckedPredictions()
+ {
+ return $this->checkedPredictions;
+ }
+
+ /**
+ * Returns object prophecy this method prophecy is tied to.
+ *
+ * @return ObjectProphecy
+ */
+ public function getObjectProphecy()
+ {
+ return $this->objectProphecy;
+ }
+
+ /**
+ * Returns method name.
+ *
+ * @return string
+ */
+ public function getMethodName()
+ {
+ return $this->methodName;
+ }
+
+ /**
+ * Returns arguments wildcard.
+ *
+ * @return Argument\ArgumentsWildcard
+ */
+ public function getArgumentsWildcard()
+ {
+ return $this->argumentsWildcard;
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasReturnVoid()
+ {
+ return $this->voidReturnType;
+ }
+
+ private function bindToObjectProphecy()
+ {
+ if ($this->bound) {
+ return;
+ }
+
+ $this->getObjectProphecy()->addMethodProphecy($this);
+ $this->bound = true;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php
new file mode 100644
index 0000000..8d8f8a1
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php
@@ -0,0 +1,281 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Prophecy;
+
+use SebastianBergmann\Comparator\ComparisonFailure;
+use Prophecy\Comparator\Factory as ComparatorFactory;
+use Prophecy\Call\Call;
+use Prophecy\Doubler\LazyDouble;
+use Prophecy\Argument\ArgumentsWildcard;
+use Prophecy\Call\CallCenter;
+use Prophecy\Exception\Prophecy\ObjectProphecyException;
+use Prophecy\Exception\Prophecy\MethodProphecyException;
+use Prophecy\Exception\Prediction\AggregateException;
+use Prophecy\Exception\Prediction\PredictionException;
+
+/**
+ * Object prophecy.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class ObjectProphecy implements ProphecyInterface
+{
+ private $lazyDouble;
+ private $callCenter;
+ private $revealer;
+ private $comparatorFactory;
+
+ /**
+ * @var MethodProphecy[][]
+ */
+ private $methodProphecies = array();
+
+ /**
+ * Initializes object prophecy.
+ *
+ * @param LazyDouble $lazyDouble
+ * @param CallCenter $callCenter
+ * @param RevealerInterface $revealer
+ * @param ComparatorFactory $comparatorFactory
+ */
+ public function __construct(
+ LazyDouble $lazyDouble,
+ CallCenter $callCenter = null,
+ RevealerInterface $revealer = null,
+ ComparatorFactory $comparatorFactory = null
+ ) {
+ $this->lazyDouble = $lazyDouble;
+ $this->callCenter = $callCenter ?: new CallCenter;
+ $this->revealer = $revealer ?: new Revealer;
+
+ $this->comparatorFactory = $comparatorFactory ?: ComparatorFactory::getInstance();
+ }
+
+ /**
+ * Forces double to extend specific class.
+ *
+ * @param string $class
+ *
+ * @return $this
+ */
+ public function willExtend($class)
+ {
+ $this->lazyDouble->setParentClass($class);
+
+ return $this;
+ }
+
+ /**
+ * Forces double to implement specific interface.
+ *
+ * @param string $interface
+ *
+ * @return $this
+ */
+ public function willImplement($interface)
+ {
+ $this->lazyDouble->addInterface($interface);
+
+ return $this;
+ }
+
+ /**
+ * Sets constructor arguments.
+ *
+ * @param array $arguments
+ *
+ * @return $this
+ */
+ public function willBeConstructedWith(array $arguments = null)
+ {
+ $this->lazyDouble->setArguments($arguments);
+
+ return $this;
+ }
+
+ /**
+ * Reveals double.
+ *
+ * @return object
+ *
+ * @throws \Prophecy\Exception\Prophecy\ObjectProphecyException If double doesn't implement needed interface
+ */
+ public function reveal()
+ {
+ $double = $this->lazyDouble->getInstance();
+
+ if (null === $double || !$double instanceof ProphecySubjectInterface) {
+ throw new ObjectProphecyException(
+ "Generated double must implement ProphecySubjectInterface, but it does not.\n".
+ 'It seems you have wrongly configured doubler without required ClassPatch.',
+ $this
+ );
+ }
+
+ $double->setProphecy($this);
+
+ return $double;
+ }
+
+ /**
+ * Adds method prophecy to object prophecy.
+ *
+ * @param MethodProphecy $methodProphecy
+ *
+ * @throws \Prophecy\Exception\Prophecy\MethodProphecyException If method prophecy doesn't
+ * have arguments wildcard
+ */
+ public function addMethodProphecy(MethodProphecy $methodProphecy)
+ {
+ $argumentsWildcard = $methodProphecy->getArgumentsWildcard();
+ if (null === $argumentsWildcard) {
+ throw new MethodProphecyException(sprintf(
+ "Can not add prophecy for a method `%s::%s()`\n".
+ "as you did not specify arguments wildcard for it.",
+ get_class($this->reveal()),
+ $methodProphecy->getMethodName()
+ ), $methodProphecy);
+ }
+
+ $methodName = $methodProphecy->getMethodName();
+
+ if (!isset($this->methodProphecies[$methodName])) {
+ $this->methodProphecies[$methodName] = array();
+ }
+
+ $this->methodProphecies[$methodName][] = $methodProphecy;
+ }
+
+ /**
+ * Returns either all or related to single method prophecies.
+ *
+ * @param null|string $methodName
+ *
+ * @return MethodProphecy[]
+ */
+ public function getMethodProphecies($methodName = null)
+ {
+ if (null === $methodName) {
+ return $this->methodProphecies;
+ }
+
+ if (!isset($this->methodProphecies[$methodName])) {
+ return array();
+ }
+
+ return $this->methodProphecies[$methodName];
+ }
+
+ /**
+ * Makes specific method call.
+ *
+ * @param string $methodName
+ * @param array $arguments
+ *
+ * @return mixed
+ */
+ public function makeProphecyMethodCall($methodName, array $arguments)
+ {
+ $arguments = $this->revealer->reveal($arguments);
+ $return = $this->callCenter->makeCall($this, $methodName, $arguments);
+
+ return $this->revealer->reveal($return);
+ }
+
+ /**
+ * Finds calls by method name & arguments wildcard.
+ *
+ * @param string $methodName
+ * @param ArgumentsWildcard $wildcard
+ *
+ * @return Call[]
+ */
+ public function findProphecyMethodCalls($methodName, ArgumentsWildcard $wildcard)
+ {
+ return $this->callCenter->findCalls($methodName, $wildcard);
+ }
+
+ /**
+ * Checks that registered method predictions do not fail.
+ *
+ * @throws \Prophecy\Exception\Prediction\AggregateException If any of registered predictions fail
+ */
+ public function checkProphecyMethodsPredictions()
+ {
+ $exception = new AggregateException(sprintf("%s:\n", get_class($this->reveal())));
+ $exception->setObjectProphecy($this);
+
+ foreach ($this->methodProphecies as $prophecies) {
+ foreach ($prophecies as $prophecy) {
+ try {
+ $prophecy->checkPrediction();
+ } catch (PredictionException $e) {
+ $exception->append($e);
+ }
+ }
+ }
+
+ if (count($exception->getExceptions())) {
+ throw $exception;
+ }
+ }
+
+ /**
+ * Creates new method prophecy using specified method name and arguments.
+ *
+ * @param string $methodName
+ * @param array $arguments
+ *
+ * @return MethodProphecy
+ */
+ public function __call($methodName, array $arguments)
+ {
+ $arguments = new ArgumentsWildcard($this->revealer->reveal($arguments));
+
+ foreach ($this->getMethodProphecies($methodName) as $prophecy) {
+ $argumentsWildcard = $prophecy->getArgumentsWildcard();
+ $comparator = $this->comparatorFactory->getComparatorFor(
+ $argumentsWildcard, $arguments
+ );
+
+ try {
+ $comparator->assertEquals($argumentsWildcard, $arguments);
+ return $prophecy;
+ } catch (ComparisonFailure $failure) {}
+ }
+
+ return new MethodProphecy($this, $methodName, $arguments);
+ }
+
+ /**
+ * Tries to get property value from double.
+ *
+ * @param string $name
+ *
+ * @return mixed
+ */
+ public function __get($name)
+ {
+ return $this->reveal()->$name;
+ }
+
+ /**
+ * Tries to set property value to double.
+ *
+ * @param string $name
+ * @param mixed $value
+ */
+ public function __set($name, $value)
+ {
+ $this->reveal()->$name = $this->revealer->reveal($value);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php
new file mode 100644
index 0000000..462f15a
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Prophecy;
+
+/**
+ * Core Prophecy interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ProphecyInterface
+{
+ /**
+ * Reveals prophecy object (double) .
+ *
+ * @return object
+ */
+ public function reveal();
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php
new file mode 100644
index 0000000..2d83958
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Prophecy;
+
+/**
+ * Controllable doubles interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface ProphecySubjectInterface
+{
+ /**
+ * Sets subject prophecy.
+ *
+ * @param ProphecyInterface $prophecy
+ */
+ public function setProphecy(ProphecyInterface $prophecy);
+
+ /**
+ * Returns subject prophecy.
+ *
+ * @return ProphecyInterface
+ */
+ public function getProphecy();
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php
new file mode 100644
index 0000000..60ecdac
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Prophecy;
+
+/**
+ * Basic prophecies revealer.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class Revealer implements RevealerInterface
+{
+ /**
+ * Unwraps value(s).
+ *
+ * @param mixed $value
+ *
+ * @return mixed
+ */
+ public function reveal($value)
+ {
+ if (is_array($value)) {
+ return array_map(array($this, __FUNCTION__), $value);
+ }
+
+ if (!is_object($value)) {
+ return $value;
+ }
+
+ if ($value instanceof ProphecyInterface) {
+ $value = $value->reveal();
+ }
+
+ return $value;
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php
new file mode 100644
index 0000000..ffc82bb
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php
@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Prophecy;
+
+/**
+ * Prophecies revealer interface.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+interface RevealerInterface
+{
+ /**
+ * Unwraps value(s).
+ *
+ * @param mixed $value
+ *
+ * @return mixed
+ */
+ public function reveal($value);
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophet.php b/vendor/phpspec/prophecy/src/Prophecy/Prophet.php
new file mode 100644
index 0000000..a4fe4b0
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Prophet.php
@@ -0,0 +1,135 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy;
+
+use Prophecy\Doubler\Doubler;
+use Prophecy\Doubler\LazyDouble;
+use Prophecy\Doubler\ClassPatch;
+use Prophecy\Prophecy\ObjectProphecy;
+use Prophecy\Prophecy\RevealerInterface;
+use Prophecy\Prophecy\Revealer;
+use Prophecy\Call\CallCenter;
+use Prophecy\Util\StringUtil;
+use Prophecy\Exception\Prediction\PredictionException;
+use Prophecy\Exception\Prediction\AggregateException;
+
+/**
+ * Prophet creates prophecies.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class Prophet
+{
+ private $doubler;
+ private $revealer;
+ private $util;
+
+ /**
+ * @var ObjectProphecy[]
+ */
+ private $prophecies = array();
+
+ /**
+ * Initializes Prophet.
+ *
+ * @param null|Doubler $doubler
+ * @param null|RevealerInterface $revealer
+ * @param null|StringUtil $util
+ */
+ public function __construct(Doubler $doubler = null, RevealerInterface $revealer = null,
+ StringUtil $util = null)
+ {
+ if (null === $doubler) {
+ $doubler = new Doubler;
+ $doubler->registerClassPatch(new ClassPatch\SplFileInfoPatch);
+ $doubler->registerClassPatch(new ClassPatch\TraversablePatch);
+ $doubler->registerClassPatch(new ClassPatch\ThrowablePatch);
+ $doubler->registerClassPatch(new ClassPatch\DisableConstructorPatch);
+ $doubler->registerClassPatch(new ClassPatch\ProphecySubjectPatch);
+ $doubler->registerClassPatch(new ClassPatch\ReflectionClassNewInstancePatch);
+ $doubler->registerClassPatch(new ClassPatch\HhvmExceptionPatch());
+ $doubler->registerClassPatch(new ClassPatch\MagicCallPatch);
+ $doubler->registerClassPatch(new ClassPatch\KeywordPatch);
+ }
+
+ $this->doubler = $doubler;
+ $this->revealer = $revealer ?: new Revealer;
+ $this->util = $util ?: new StringUtil;
+ }
+
+ /**
+ * Creates new object prophecy.
+ *
+ * @param null|string $classOrInterface Class or interface name
+ *
+ * @return ObjectProphecy
+ */
+ public function prophesize($classOrInterface = null)
+ {
+ $this->prophecies[] = $prophecy = new ObjectProphecy(
+ new LazyDouble($this->doubler),
+ new CallCenter($this->util),
+ $this->revealer
+ );
+
+ if ($classOrInterface && class_exists($classOrInterface)) {
+ return $prophecy->willExtend($classOrInterface);
+ }
+
+ if ($classOrInterface && interface_exists($classOrInterface)) {
+ return $prophecy->willImplement($classOrInterface);
+ }
+
+ return $prophecy;
+ }
+
+ /**
+ * Returns all created object prophecies.
+ *
+ * @return ObjectProphecy[]
+ */
+ public function getProphecies()
+ {
+ return $this->prophecies;
+ }
+
+ /**
+ * Returns Doubler instance assigned to this Prophet.
+ *
+ * @return Doubler
+ */
+ public function getDoubler()
+ {
+ return $this->doubler;
+ }
+
+ /**
+ * Checks all predictions defined by prophecies of this Prophet.
+ *
+ * @throws Exception\Prediction\AggregateException If any prediction fails
+ */
+ public function checkPredictions()
+ {
+ $exception = new AggregateException("Some predictions failed:\n");
+ foreach ($this->prophecies as $prophecy) {
+ try {
+ $prophecy->checkProphecyMethodsPredictions();
+ } catch (PredictionException $e) {
+ $exception->append($e);
+ }
+ }
+
+ if (count($exception->getExceptions())) {
+ throw $exception;
+ }
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php b/vendor/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php
new file mode 100644
index 0000000..50dd3f3
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php
@@ -0,0 +1,212 @@
+<?php
+
+namespace Prophecy\Util;
+
+use Prophecy\Prophecy\ProphecyInterface;
+use SebastianBergmann\RecursionContext\Context;
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * This class is a modification from sebastianbergmann/exporter
+ * @see https://github.com/sebastianbergmann/exporter
+ */
+class ExportUtil
+{
+ /**
+ * 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 mixed $value
+ * @param int $indentation The indentation level of the 2nd+ line
+ * @return string
+ */
+ public static function export($value, $indentation = 0)
+ {
+ return self::recursiveExport($value, $indentation);
+ }
+
+ /**
+ * Converts an object to an array containing all of its private, protected
+ * and public properties.
+ *
+ * @param mixed $value
+ * @return array
+ */
+ public static function toArray($value)
+ {
+ if (!is_object($value)) {
+ return (array) $value;
+ }
+
+ $array = array();
+
+ foreach ((array) $value as $key => $val) {
+ // 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(.+)$/', $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) {
+ // However, the fast method does work in HHVM, and exposes the
+ // internal implementation. Hide it again.
+ if (property_exists('\SplObjectStorage', '__storage')) {
+ unset($array['__storage']);
+ } elseif (property_exists('\SplObjectStorage', 'storage')) {
+ unset($array['storage']);
+ }
+
+ if (property_exists('\SplObjectStorage', '__key')) {
+ unset($array['__key']);
+ }
+
+ foreach ($value as $key => $val) {
+ $array[spl_object_hash($val)] = array(
+ '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 static 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) && floatval(intval($value)) === $value) {
+ return "$value.0";
+ }
+
+ 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\x20-\xff]/', $value)) {
+ return 'Binary String: 0x' . bin2hex($value);
+ }
+
+ return "'" .
+ str_replace(array("\r\n", "\n\r", "\r"), array("\n", "\n", "\n"), $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,
+ self::recursiveExport($k, $indentation),
+ self::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 ($value instanceof ProphecyInterface) {
+ return sprintf('%s Object (*Prophecy*)', $class);
+ } elseif ($hash = $processed->contains($value)) {
+ return sprintf('%s:%s Object', $class, $hash);
+ }
+
+ $hash = $processed->add($value);
+ $values = '';
+ $array = self::toArray($value);
+
+ if (count($array) > 0) {
+ foreach ($array as $k => $v) {
+ $values .= sprintf(
+ '%s %s => %s' . "\n",
+ $whitespace,
+ self::recursiveExport($k, $indentation),
+ self::recursiveExport($v, $indentation + 1, $processed)
+ );
+ }
+
+ $values = "\n" . $values . $whitespace;
+ }
+
+ return sprintf('%s:%s Object (%s)', $class, $hash, $values);
+ }
+
+ return var_export($value, true);
+ }
+}
diff --git a/vendor/phpspec/prophecy/src/Prophecy/Util/StringUtil.php b/vendor/phpspec/prophecy/src/Prophecy/Util/StringUtil.php
new file mode 100644
index 0000000..ba4faff
--- /dev/null
+++ b/vendor/phpspec/prophecy/src/Prophecy/Util/StringUtil.php
@@ -0,0 +1,99 @@
+<?php
+
+/*
+ * This file is part of the Prophecy.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ * Marcello Duarte <marcello.duarte@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Prophecy\Util;
+
+use Prophecy\Call\Call;
+
+/**
+ * String utility.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+class StringUtil
+{
+ private $verbose;
+
+ /**
+ * @param bool $verbose
+ */
+ public function __construct($verbose = true)
+ {
+ $this->verbose = $verbose;
+ }
+
+ /**
+ * Stringifies any provided value.
+ *
+ * @param mixed $value
+ * @param boolean $exportObject
+ *
+ * @return string
+ */
+ public function stringify($value, $exportObject = true)
+ {
+ if (is_array($value)) {
+ if (range(0, count($value) - 1) === array_keys($value)) {
+ return '['.implode(', ', array_map(array($this, __FUNCTION__), $value)).']';
+ }
+
+ $stringify = array($this, __FUNCTION__);
+
+ return '['.implode(', ', array_map(function ($item, $key) use ($stringify) {
+ return (is_integer($key) ? $key : '"'.$key.'"').
+ ' => '.call_user_func($stringify, $item);
+ }, $value, array_keys($value))).']';
+ }
+ if (is_resource($value)) {
+ return get_resource_type($value).':'.$value;
+ }
+ if (is_object($value)) {
+ return $exportObject ? ExportUtil::export($value) : sprintf('%s:%s', get_class($value), spl_object_hash($value));
+ }
+ if (true === $value || false === $value) {
+ return $value ? 'true' : 'false';
+ }
+ if (is_string($value)) {
+ $str = sprintf('"%s"', str_replace("\n", '\\n', $value));
+
+ if (!$this->verbose && 50 <= strlen($str)) {
+ return substr($str, 0, 50).'"...';
+ }
+
+ return $str;
+ }
+ if (null === $value) {
+ return 'null';
+ }
+
+ return (string) $value;
+ }
+
+ /**
+ * Stringifies provided array of calls.
+ *
+ * @param Call[] $calls Array of Call instances
+ *
+ * @return string
+ */
+ public function stringifyCalls(array $calls)
+ {
+ $self = $this;
+
+ return implode(PHP_EOL, array_map(function (Call $call) use ($self) {
+ return sprintf(' - %s(%s) @ %s',
+ $call->getMethodName(),
+ implode(', ', array_map(array($self, 'stringify'), $call->getArguments())),
+ str_replace(GETCWD().DIRECTORY_SEPARATOR, '', $call->getCallPlace())
+ );
+ }, $calls));
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/.gitattributes b/vendor/phpunit/php-code-coverage/.gitattributes
new file mode 100644
index 0000000..461090b
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/.gitattributes
@@ -0,0 +1 @@
+*.php diff=php
diff --git a/vendor/phpunit/php-code-coverage/.github/CONTRIBUTING.md b/vendor/phpunit/php-code-coverage/.github/CONTRIBUTING.md
new file mode 100644
index 0000000..76a4345
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/.github/CONTRIBUTING.md
@@ -0,0 +1 @@
+Please refer to [https://github.com/sebastianbergmann/phpunit/blob/master/CONTRIBUTING.md](https://github.com/sebastianbergmann/phpunit/blob/master/CONTRIBUTING.md) for details on how to contribute to this project.
diff --git a/vendor/phpunit/php-code-coverage/.github/ISSUE_TEMPLATE.md b/vendor/phpunit/php-code-coverage/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 0000000..dc8e3b0
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,18 @@
+| Q | A
+| --------------------------| ---------------
+| php-code-coverage version | x.y.z
+| PHP version | x.y.z
+| Driver | Xdebug / PHPDBG
+| Xdebug version (if used) | x.y.z
+| Installation Method | Composer / PHPUnit PHAR
+| Usage Method | PHPUnit / other
+| PHPUnit version (if used) | x.y.z
+
+<!--
+- Please fill in this template according to your issue.
+- Please keep the table shown above at the top of your issue.
+- Please post code as text (using proper markup). Do not post screenshots of code.
+- For support request or how-tos, visit https://phpunit.de/support.html
+- Otherwise, replace this comment by the description of your issue.
+-->
+
diff --git a/vendor/phpunit/php-code-coverage/.gitignore b/vendor/phpunit/php-code-coverage/.gitignore
new file mode 100644
index 0000000..603bc9e
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/.gitignore
@@ -0,0 +1,6 @@
+/tests/_files/tmp
+/vendor
+/composer.lock
+/.idea
+/.php_cs.cache
+
diff --git a/vendor/phpunit/php-code-coverage/.php_cs b/vendor/phpunit/php-code-coverage/.php_cs
new file mode 100644
index 0000000..de5cde1
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/.php_cs
@@ -0,0 +1,69 @@
+<?php
+$finder = Symfony\CS\Finder\DefaultFinder::create()
+ ->files()
+ ->in('src')
+ ->in('tests')
+ ->exclude('_files')
+ ->name('*.php');
+
+return Symfony\CS\Config\Config::create()
+ ->setUsingCache(true)
+ ->level(\Symfony\CS\FixerInterface::NONE_LEVEL)
+ ->fixers(
+ array(
+ 'align_double_arrow',
+ 'align_equals',
+ 'braces',
+ 'concat_with_spaces',
+ 'duplicate_semicolon',
+ 'elseif',
+ 'empty_return',
+ 'encoding',
+ 'eof_ending',
+ 'extra_empty_lines',
+ 'function_call_space',
+ 'function_declaration',
+ 'indentation',
+ 'join_function',
+ 'line_after_namespace',
+ 'linefeed',
+ 'list_commas',
+ 'lowercase_constants',
+ 'lowercase_keywords',
+ 'method_argument_space',
+ 'multiple_use',
+ 'namespace_no_leading_whitespace',
+ 'no_blank_lines_after_class_opening',
+ 'no_empty_lines_after_phpdocs',
+ 'parenthesis',
+ 'php_closing_tag',
+ 'phpdoc_indent',
+ 'phpdoc_no_access',
+ 'phpdoc_no_empty_return',
+ 'phpdoc_no_package',
+ 'phpdoc_params',
+ 'phpdoc_scalar',
+ 'phpdoc_separation',
+ 'phpdoc_to_comment',
+ 'phpdoc_trim',
+ 'phpdoc_types',
+ 'phpdoc_var_without_name',
+ 'remove_lines_between_uses',
+ 'return',
+ 'self_accessor',
+ 'short_array_syntax',
+ 'short_tag',
+ 'single_line_after_imports',
+ 'single_quote',
+ 'spaces_before_semicolon',
+ 'spaces_cast',
+ 'ternary_spaces',
+ 'trailing_spaces',
+ 'trim_array_spaces',
+ 'unused_use',
+ 'visibility',
+ 'whitespacy_lines'
+ )
+ )
+ ->finder($finder);
+
diff --git a/vendor/phpunit/php-code-coverage/.travis.yml b/vendor/phpunit/php-code-coverage/.travis.yml
new file mode 100644
index 0000000..96c6368
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/.travis.yml
@@ -0,0 +1,42 @@
+language: php
+
+php:
+ - 5.6
+ - 7.0
+ - 7.0snapshot
+ - 7.1
+ - 7.1snapshot
+ - master
+
+env:
+ matrix:
+ - DRIVER="xdebug"
+ - DRIVER="phpdbg"
+
+matrix:
+ allow_failures:
+ - php: master
+ fast_finish: true
+ exclude:
+ - php: 5.6
+ env: DRIVER="phpdbg"
+
+sudo: false
+
+before_install:
+ - composer self-update
+ - composer clear-cache
+
+install:
+ - travis_retry composer update --no-interaction --no-ansi --no-progress --no-suggest --optimize-autoloader --prefer-stable
+
+script:
+ - if [[ "$DRIVER" = 'phpdbg' ]]; then phpdbg -qrr vendor/bin/phpunit --coverage-clover=coverage.xml; fi
+ - if [[ "$DRIVER" = 'xdebug' ]]; then vendor/bin/phpunit --coverage-clover=coverage.xml; fi
+
+after_success:
+ - bash <(curl -s https://codecov.io/bash)
+
+notifications:
+ email: false
+
diff --git a/vendor/phpunit/php-code-coverage/ChangeLog-2.2.md b/vendor/phpunit/php-code-coverage/ChangeLog-2.2.md
new file mode 100644
index 0000000..353b6f6
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/ChangeLog-2.2.md
@@ -0,0 +1,56 @@
+# Changes in PHP_CodeCoverage 2.2
+
+All notable changes of the PHP_CodeCoverage 2.2 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+
+## [2.2.4] - 2015-10-06
+
+### Fixed
+
+* Fixed [#391](https://github.com/sebastianbergmann/php-code-coverage/pull/391): Missing `</abbr>` tag
+
+## [2.2.3] - 2015-09-14
+
+### Fixed
+
+* Fixed [#368](https://github.com/sebastianbergmann/php-code-coverage/pull/368): Blacklists and whitelists are not merged when merging data sets
+* Fixed [#370](https://github.com/sebastianbergmann/php-code-coverage/issues/370): Confusing statistics for source file that declares a class without methods
+* Fixed [#372](https://github.com/sebastianbergmann/php-code-coverage/pull/372): Nested classes and functions are not handled correctly
+* Fixed [#382](https://github.com/sebastianbergmann/php-code-coverage/issues/382): Crap4J report generates incorrect XML logfile
+
+## [2.2.2] - 2015-08-04
+
+### Added
+
+* Reintroduced the `PHP_CodeCoverage_Driver_HHVM` driver as an extension of `PHP_CodeCoverage_Driver_Xdebug` that does not use `xdebug_start_code_coverage()` with options not supported by HHVM
+
+### Changed
+
+* Bumped required version of `sebastian/environment` to 1.3.2 for [#365](https://github.com/sebastianbergmann/php-code-coverage/issues/365)
+
+## [2.2.1] - 2015-08-02
+
+### Changed
+
+* Bumped required version of `sebastian/environment` to 1.3.1 for [#365](https://github.com/sebastianbergmann/php-code-coverage/issues/365)
+
+## [2.2.0] - 2015-08-01
+
+### Added
+
+* Added a driver for PHPDBG (requires PHP 7)
+* Added `PHP_CodeCoverage::setDisableIgnoredLines()` to disable the ignoring of lines using annotations such as `@codeCoverageIgnore`
+
+### Changed
+
+* Annotating a method with `@deprecated` now has the same effect as annotating it with `@codeCoverageIgnore`
+
+### Removed
+
+* The dedicated driver for HHVM, `PHP_CodeCoverage_Driver_HHVM` has been removed
+
+[2.2.4]: https://github.com/sebastianbergmann/php-code-coverage/compare/2.2.3...2.2.4
+[2.2.3]: https://github.com/sebastianbergmann/php-code-coverage/compare/2.2.2...2.2.3
+[2.2.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/2.2.1...2.2.2
+[2.2.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/2.2.0...2.2.1
+[2.2.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/2.1...2.2.0
+
diff --git a/vendor/phpunit/php-code-coverage/ChangeLog-3.0.md b/vendor/phpunit/php-code-coverage/ChangeLog-3.0.md
new file mode 100644
index 0000000..a39fa8d
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/ChangeLog-3.0.md
@@ -0,0 +1,31 @@
+# Changes in PHP_CodeCoverage 3.0
+
+All notable changes of the PHP_CodeCoverage 3.0 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+
+## [3.0.2] - 2015-11-12
+
+### Changed
+
+* It is now optional that `@deprecated` code is ignored
+
+## [3.0.1] - 2015-10-06
+
+### Fixed
+
+* Fixed [#391](https://github.com/sebastianbergmann/php-code-coverage/pull/391): Missing `</abbr>` tag
+
+## [3.0.0] - 2015-10-02
+
+### Changed
+
+* It is now mandatory to configure a whitelist
+
+### Removed
+
+* The blacklist functionality has been removed
+* PHP_CodeCoverage is no longer supported on PHP 5.3, PHP 5.4, and PHP 5.5
+
+[3.0.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.0.1...3.0.2
+[3.0.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.0.0...3.0.1
+[3.0.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/2.2...3.0.0
+
diff --git a/vendor/phpunit/php-code-coverage/ChangeLog-3.1.md b/vendor/phpunit/php-code-coverage/ChangeLog-3.1.md
new file mode 100644
index 0000000..f7a0de9
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/ChangeLog-3.1.md
@@ -0,0 +1,30 @@
+# Changes in PHP_CodeCoverage 3.1
+
+All notable changes of the PHP_CodeCoverage 3.1 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+
+## [3.1.1] - 2016-02-04
+
+### Changed
+
+* Allow version 2.0.x of `sebastian/version` dependency
+
+## [3.1.0] - 2016-01-11
+
+### Added
+
+* Implemented [#234](https://github.com/sebastianbergmann/php-code-coverage/issues/234): Optionally raise an exception when a specified unit of code is not executed
+
+### Changed
+
+* The Clover XML report now contains cyclomatic complexity information
+* The Clover XML report now contains method visibility information
+* Cleanup and refactoring of various areas of code
+* Added missing test cases
+
+### Removed
+
+* The functionality controlled by the `mapTestClassNameToCoveredClassName` setting has been removed
+
+[3.1.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.1.0...3.1.1
+[3.1.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.0...3.1.0
+
diff --git a/vendor/phpunit/php-code-coverage/ChangeLog-3.2.md b/vendor/phpunit/php-code-coverage/ChangeLog-3.2.md
new file mode 100644
index 0000000..34c65cf
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/ChangeLog-3.2.md
@@ -0,0 +1,23 @@
+# Changes in PHP_CodeCoverage 3.2
+
+All notable changes of the PHP_CodeCoverage 3.2 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+
+## [3.2.1] - 2016-02-18
+
+### Changed
+
+* Updated dependency information in `composer.json`
+
+## [3.2.0] - 2016-02-13
+
+### Added
+
+* Added optional check for missing `@covers` annotation when the usage of `@covers` annotations is forced
+
+### Changed
+
+* Improved `PHP_CodeCoverage_UnintentionallyCoveredCodeException` message
+
+[3.2.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.2.0...3.2.1
+[3.2.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.1...3.2.0
+
diff --git a/vendor/phpunit/php-code-coverage/ChangeLog-3.3.md b/vendor/phpunit/php-code-coverage/ChangeLog-3.3.md
new file mode 100644
index 0000000..2cf1522
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/ChangeLog-3.3.md
@@ -0,0 +1,33 @@
+# Changes in PHP_CodeCoverage 3.3
+
+All notable changes of the PHP_CodeCoverage 3.3 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+
+## [3.3.3] - 2016-MM-DD
+
+### Fixed
+
+* Fixed [#438](https://github.com/sebastianbergmann/php-code-coverage/issues/438): Wrong base directory for Clover reports
+
+## [3.3.2] - 2016-05-25
+
+### Changed
+
+* The constructor of `PHP_CodeCoverage_Report_Text` now has default values for its parameters
+
+## [3.3.1] - 2016-04-08
+
+### Fixed
+
+* Fixed handling of lines that contain `declare` statements
+
+## [3.3.0] - 2016-03-03
+
+### Added
+
+* Added support for whitelisting classes for the unintentionally covered code unit check
+
+[3.3.3]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.3.2...3.3.3
+[3.3.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.3.1...3.3.2
+[3.3.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.3.0...3.3.1
+[3.3.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.2...3.3.0
+
diff --git a/vendor/phpunit/php-code-coverage/ChangeLog-4.0.md b/vendor/phpunit/php-code-coverage/ChangeLog-4.0.md
new file mode 100644
index 0000000..30df010
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/ChangeLog-4.0.md
@@ -0,0 +1,67 @@
+# Changes in PHP_CodeCoverage 4.0
+
+All notable changes of the PHP_CodeCoverage 4.0 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+
+## [4.0.8] - 2017-04-02
+
+* Fixed [#515](https://github.com/sebastianbergmann/php-code-coverage/pull/515): Wrong use of recursive iterator causing duplicate entries in XML coverage report
+
+## [4.0.7] - 2017-03-01
+
+### Changed
+
+* Cleaned up requirements in `composer.json`
+
+## [4.0.6] - 2017-02-23
+
+### Changed
+
+* Added support for `phpunit/php-token-stream` 2.0
+* Updated HTML report assets
+
+## [4.0.5] - 2017-01-20
+
+### Fixed
+
+* Fixed formatting of executed lines percentage for classes in file view
+
+## [4.0.4] - 2016-12-20
+
+### Changed
+
+* Implemented [#432](https://github.com/sebastianbergmann/php-code-coverage/issues/432): Change how files with no executable lines are displayed in the HTML report
+
+## [4.0.3] - 2016-11-28
+
+### Changed
+
+* The check for unintentionally covered code is no longer performed for `@medium` and `@large` tests
+
+## [4.0.2] - 2016-11-01
+
+### Fixed
+
+* Fixed [#440](https://github.com/sebastianbergmann/php-code-coverage/pull/440): Dashboard charts not showing tooltips for data points
+
+## [4.0.1] - 2016-07-26
+
+### Fixed
+
+* Fixed [#458](https://github.com/sebastianbergmann/php-code-coverage/pull/458): XML report does not know about warning status
+
+## [4.0.0] - 2016-06-03
+
+### Changed
+
+* This component now uses namespaces
+
+[4.0.8]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0.7...4.0.8
+[4.0.7]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0.6...4.0.7
+[4.0.6]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0.5...4.0.6
+[4.0.5]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0.4...4.0.5
+[4.0.4]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0.3...4.0.4
+[4.0.3]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0.2...4.0.3
+[4.0.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0.1...4.0.2
+[4.0.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/4.0.0...4.0.1
+[4.0.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/3.3...4.0.0
+
diff --git a/vendor/phpunit/php-code-coverage/LICENSE b/vendor/phpunit/php-code-coverage/LICENSE
new file mode 100644
index 0000000..fcfa37e
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/LICENSE
@@ -0,0 +1,33 @@
+PHP_CodeCoverage
+
+Copyright (c) 2009-2015, Sebastian Bergmann <sebastian@phpunit.de>.
+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/phpunit/php-code-coverage/README.md b/vendor/phpunit/php-code-coverage/README.md
new file mode 100644
index 0000000..c01384b
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/README.md
@@ -0,0 +1,51 @@
+[![Latest Stable Version](https://poser.pugx.org/phpunit/php-code-coverage/v/stable.png)](https://packagist.org/packages/phpunit/php-code-coverage)
+[![Build Status](https://travis-ci.org/sebastianbergmann/php-code-coverage.svg?branch=master)](https://travis-ci.org/sebastianbergmann/php-code-coverage)
+
+# PHP_CodeCoverage
+
+**PHP_CodeCoverage** is a library that provides collection, processing, and rendering functionality for PHP code coverage information.
+
+## Requirements
+
+PHP 5.6 is required but using the latest version of PHP is highly recommended.
+
+### PHP 5
+
+[Xdebug](http://xdebug.org/) is the only source of raw code coverage data supported for PHP 5. Version 2.2.1 of Xdebug is required but using the latest version is highly recommended.
+
+### PHP 7
+
+Version 2.4.0 (or later) of [Xdebug](http://xdebug.org/) as well as [phpdbg](http://phpdbg.com/docs) are supported sources of raw code coverage data for PHP 7.
+
+### HHVM
+
+A version of HHVM that implements the Xdebug API for code coverage (`xdebug_*_code_coverage()`) is required.
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+ composer require phpunit/php-code-coverage
+
+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 phpunit/php-code-coverage
+
+## Using the PHP_CodeCoverage API
+
+```php
+<?php
+$coverage = new \SebastianBergmann\CodeCoverage\CodeCoverage;
+$coverage->start('<name of test>');
+
+// ...
+
+$coverage->stop();
+
+$writer = new \SebastianBergmann\CodeCoverage\Report\Clover;
+$writer->process($coverage, '/tmp/clover.xml');
+
+$writer = new \SebastianBergmann\CodeCoverage\Report\Html\Facade;
+$writer->process($coverage, '/tmp/code-coverage-report');
+```
+
diff --git a/vendor/phpunit/php-code-coverage/build.xml b/vendor/phpunit/php-code-coverage/build.xml
new file mode 100644
index 0000000..d8168c2
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/build.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="php-code-coverage" default="setup">
+ <target name="setup" depends="clean,composer"/>
+
+ <target name="clean" description="Cleanup build artifacts">
+ <delete dir="${basedir}/vendor"/>
+ <delete file="${basedir}/composer.lock"/>
+ </target>
+
+ <target name="composer" depends="clean" description="Install dependencies with Composer">
+ <exec executable="composer" taskname="composer">
+ <arg value="update"/>
+ <arg value="--no-interaction"/>
+ <arg value="--no-progress"/>
+ <arg value="--no-ansi"/>
+ <arg value="--no-suggest"/>
+ <arg value="--optimize-autoloader"/>
+ <arg value="--prefer-stable"/>
+ </exec>
+ </target>
+</project>
diff --git a/vendor/phpunit/php-code-coverage/composer.json b/vendor/phpunit/php-code-coverage/composer.json
new file mode 100644
index 0000000..7ca434b
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/composer.json
@@ -0,0 +1,51 @@
+{
+ "name": "phpunit/php-code-coverage",
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+ "type": "library",
+ "keywords": [
+ "coverage",
+ "testing",
+ "xunit"
+ ],
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
+ "irc": "irc://irc.freenode.net/phpunit"
+ },
+ "require": {
+ "php": "^5.6 || ^7.0",
+ "ext-dom": "*",
+ "ext-xmlwriter": "*",
+ "phpunit/php-file-iterator": "^1.3",
+ "phpunit/php-token-stream": "^1.4.2 || ^2.0",
+ "phpunit/php-text-template": "^1.2",
+ "sebastian/code-unit-reverse-lookup": "^1.0",
+ "sebastian/environment": "^1.3.2 || ^2.0",
+ "sebastian/version": "^1.0 || ^2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7",
+ "ext-xdebug": "^2.1.4"
+ },
+ "suggest": {
+ "ext-xdebug": "^2.5.1"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/phpunit.xml b/vendor/phpunit/php-code-coverage/phpunit.xml
new file mode 100644
index 0000000..55822f0
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/phpunit.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/5.7/phpunit.xsd"
+ bootstrap="tests/bootstrap.php"
+ backupGlobals="false"
+ verbose="true">
+ <testsuite>
+ <directory suffix="Test.php">tests/tests</directory>
+ </testsuite>
+
+ <filter>
+ <whitelist processUncoveredFilesFromWhitelist="true">
+ <directory suffix=".php">src</directory>
+ </whitelist>
+ </filter>
+
+ <php>
+ <ini name="serialize_precision" value="14"/>
+ </php>
+</phpunit>
+
diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage.php
new file mode 100644
index 0000000..35dab3d
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage.php
@@ -0,0 +1,1107 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage;
+
+use SebastianBergmann\CodeCoverage\Driver\Driver;
+use SebastianBergmann\CodeCoverage\Driver\Xdebug;
+use SebastianBergmann\CodeCoverage\Driver\HHVM;
+use SebastianBergmann\CodeCoverage\Driver\PHPDBG;
+use SebastianBergmann\CodeCoverage\Node\Builder;
+use SebastianBergmann\CodeCoverage\Node\Directory;
+use SebastianBergmann\CodeUnitReverseLookup\Wizard;
+use SebastianBergmann\Environment\Runtime;
+
+/**
+ * Provides collection functionality for PHP code coverage information.
+ */
+class CodeCoverage
+{
+ /**
+ * @var Driver
+ */
+ private $driver;
+
+ /**
+ * @var Filter
+ */
+ private $filter;
+
+ /**
+ * @var Wizard
+ */
+ private $wizard;
+
+ /**
+ * @var bool
+ */
+ private $cacheTokens = false;
+
+ /**
+ * @var bool
+ */
+ private $checkForUnintentionallyCoveredCode = false;
+
+ /**
+ * @var bool
+ */
+ private $forceCoversAnnotation = false;
+
+ /**
+ * @var bool
+ */
+ private $checkForUnexecutedCoveredCode = false;
+
+ /**
+ * @var bool
+ */
+ private $checkForMissingCoversAnnotation = false;
+
+ /**
+ * @var bool
+ */
+ private $addUncoveredFilesFromWhitelist = true;
+
+ /**
+ * @var bool
+ */
+ private $processUncoveredFilesFromWhitelist = false;
+
+ /**
+ * @var bool
+ */
+ private $ignoreDeprecatedCode = false;
+
+ /**
+ * @var mixed
+ */
+ private $currentId;
+
+ /**
+ * Code coverage data.
+ *
+ * @var array
+ */
+ private $data = [];
+
+ /**
+ * @var array
+ */
+ private $ignoredLines = [];
+
+ /**
+ * @var bool
+ */
+ private $disableIgnoredLines = false;
+
+ /**
+ * Test data.
+ *
+ * @var array
+ */
+ private $tests = [];
+
+ /**
+ * @var string[]
+ */
+ private $unintentionallyCoveredSubclassesWhitelist = [];
+
+ /**
+ * Determine if the data has been initialized or not
+ *
+ * @var bool
+ */
+ private $isInitialized = false;
+
+ /**
+ * Determine whether we need to check for dead and unused code on each test
+ *
+ * @var bool
+ */
+ private $shouldCheckForDeadAndUnused = true;
+
+ /**
+ * Constructor.
+ *
+ * @param Driver $driver
+ * @param Filter $filter
+ *
+ * @throws RuntimeException
+ */
+ public function __construct(Driver $driver = null, Filter $filter = null)
+ {
+ if ($driver === null) {
+ $driver = $this->selectDriver();
+ }
+
+ if ($filter === null) {
+ $filter = new Filter;
+ }
+
+ $this->driver = $driver;
+ $this->filter = $filter;
+
+ $this->wizard = new Wizard;
+ }
+
+ /**
+ * Returns the code coverage information as a graph of node objects.
+ *
+ * @return Directory
+ */
+ public function getReport()
+ {
+ $builder = new Builder;
+
+ return $builder->build($this);
+ }
+
+ /**
+ * Clears collected code coverage data.
+ */
+ public function clear()
+ {
+ $this->isInitialized = false;
+ $this->currentId = null;
+ $this->data = [];
+ $this->tests = [];
+ }
+
+ /**
+ * Returns the filter object used.
+ *
+ * @return Filter
+ */
+ public function filter()
+ {
+ return $this->filter;
+ }
+
+ /**
+ * Returns the collected code coverage data.
+ * Set $raw = true to bypass all filters.
+ *
+ * @param bool $raw
+ *
+ * @return array
+ */
+ public function getData($raw = false)
+ {
+ if (!$raw && $this->addUncoveredFilesFromWhitelist) {
+ $this->addUncoveredFilesFromWhitelist();
+ }
+
+ return $this->data;
+ }
+
+ /**
+ * Sets the coverage data.
+ *
+ * @param array $data
+ */
+ public function setData(array $data)
+ {
+ $this->data = $data;
+ }
+
+ /**
+ * Returns the test data.
+ *
+ * @return array
+ */
+ public function getTests()
+ {
+ return $this->tests;
+ }
+
+ /**
+ * Sets the test data.
+ *
+ * @param array $tests
+ */
+ public function setTests(array $tests)
+ {
+ $this->tests = $tests;
+ }
+
+ /**
+ * Start collection of code coverage information.
+ *
+ * @param mixed $id
+ * @param bool $clear
+ *
+ * @throws InvalidArgumentException
+ */
+ public function start($id, $clear = false)
+ {
+ if (!is_bool($clear)) {
+ throw InvalidArgumentException::create(
+ 1,
+ 'boolean'
+ );
+ }
+
+ if ($clear) {
+ $this->clear();
+ }
+
+ if ($this->isInitialized === false) {
+ $this->initializeData();
+ }
+
+ $this->currentId = $id;
+
+ $this->driver->start($this->shouldCheckForDeadAndUnused);
+ }
+
+ /**
+ * Stop collection of code coverage information.
+ *
+ * @param bool $append
+ * @param mixed $linesToBeCovered
+ * @param array $linesToBeUsed
+ *
+ * @return array
+ *
+ * @throws InvalidArgumentException
+ */
+ public function stop($append = true, $linesToBeCovered = [], array $linesToBeUsed = [])
+ {
+ if (!is_bool($append)) {
+ throw InvalidArgumentException::create(
+ 1,
+ 'boolean'
+ );
+ }
+
+ if (!is_array($linesToBeCovered) && $linesToBeCovered !== false) {
+ throw InvalidArgumentException::create(
+ 2,
+ 'array or false'
+ );
+ }
+
+ $data = $this->driver->stop();
+ $this->append($data, null, $append, $linesToBeCovered, $linesToBeUsed);
+
+ $this->currentId = null;
+
+ return $data;
+ }
+
+ /**
+ * Appends code coverage data.
+ *
+ * @param array $data
+ * @param mixed $id
+ * @param bool $append
+ * @param mixed $linesToBeCovered
+ * @param array $linesToBeUsed
+ *
+ * @throws RuntimeException
+ */
+ public function append(array $data, $id = null, $append = true, $linesToBeCovered = [], array $linesToBeUsed = [])
+ {
+ if ($id === null) {
+ $id = $this->currentId;
+ }
+
+ if ($id === null) {
+ throw new RuntimeException;
+ }
+
+ $this->applyListsFilter($data);
+ $this->applyIgnoredLinesFilter($data);
+ $this->initializeFilesThatAreSeenTheFirstTime($data);
+
+ if (!$append) {
+ return;
+ }
+
+ if ($id != 'UNCOVERED_FILES_FROM_WHITELIST') {
+ $this->applyCoversAnnotationFilter(
+ $data,
+ $linesToBeCovered,
+ $linesToBeUsed
+ );
+ }
+
+ if (empty($data)) {
+ return;
+ }
+
+ $size = 'unknown';
+ $status = null;
+
+ if ($id instanceof \PHPUnit_Framework_TestCase) {
+ $_size = $id->getSize();
+
+ if ($_size == \PHPUnit_Util_Test::SMALL) {
+ $size = 'small';
+ } elseif ($_size == \PHPUnit_Util_Test::MEDIUM) {
+ $size = 'medium';
+ } elseif ($_size == \PHPUnit_Util_Test::LARGE) {
+ $size = 'large';
+ }
+
+ $status = $id->getStatus();
+ $id = get_class($id) . '::' . $id->getName();
+ } elseif ($id instanceof \PHPUnit_Extensions_PhptTestCase) {
+ $size = 'large';
+ $id = $id->getName();
+ }
+
+ $this->tests[$id] = ['size' => $size, 'status' => $status];
+
+ foreach ($data as $file => $lines) {
+ if (!$this->filter->isFile($file)) {
+ continue;
+ }
+
+ foreach ($lines as $k => $v) {
+ if ($v == Driver::LINE_EXECUTED) {
+ if (empty($this->data[$file][$k]) || !in_array($id, $this->data[$file][$k])) {
+ $this->data[$file][$k][] = $id;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Merges the data from another instance.
+ *
+ * @param CodeCoverage $that
+ */
+ public function merge(CodeCoverage $that)
+ {
+ $this->filter->setWhitelistedFiles(
+ array_merge($this->filter->getWhitelistedFiles(), $that->filter()->getWhitelistedFiles())
+ );
+
+ foreach ($that->data as $file => $lines) {
+ if (!isset($this->data[$file])) {
+ if (!$this->filter->isFiltered($file)) {
+ $this->data[$file] = $lines;
+ }
+
+ continue;
+ }
+
+ foreach ($lines as $line => $data) {
+ if ($data !== null) {
+ if (!isset($this->data[$file][$line])) {
+ $this->data[$file][$line] = $data;
+ } else {
+ $this->data[$file][$line] = array_unique(
+ array_merge($this->data[$file][$line], $data)
+ );
+ }
+ }
+ }
+ }
+
+ $this->tests = array_merge($this->tests, $that->getTests());
+ }
+
+ /**
+ * @param bool $flag
+ *
+ * @throws InvalidArgumentException
+ */
+ public function setCacheTokens($flag)
+ {
+ if (!is_bool($flag)) {
+ throw InvalidArgumentException::create(
+ 1,
+ 'boolean'
+ );
+ }
+
+ $this->cacheTokens = $flag;
+ }
+
+ /**
+ * @return bool
+ */
+ public function getCacheTokens()
+ {
+ return $this->cacheTokens;
+ }
+
+ /**
+ * @param bool $flag
+ *
+ * @throws InvalidArgumentException
+ */
+ public function setCheckForUnintentionallyCoveredCode($flag)
+ {
+ if (!is_bool($flag)) {
+ throw InvalidArgumentException::create(
+ 1,
+ 'boolean'
+ );
+ }
+
+ $this->checkForUnintentionallyCoveredCode = $flag;
+ }
+
+ /**
+ * @param bool $flag
+ *
+ * @throws InvalidArgumentException
+ */
+ public function setForceCoversAnnotation($flag)
+ {
+ if (!is_bool($flag)) {
+ throw InvalidArgumentException::create(
+ 1,
+ 'boolean'
+ );
+ }
+
+ $this->forceCoversAnnotation = $flag;
+ }
+
+ /**
+ * @param bool $flag
+ *
+ * @throws InvalidArgumentException
+ */
+ public function setCheckForMissingCoversAnnotation($flag)
+ {
+ if (!is_bool($flag)) {
+ throw InvalidArgumentException::create(
+ 1,
+ 'boolean'
+ );
+ }
+
+ $this->checkForMissingCoversAnnotation = $flag;
+ }
+
+ /**
+ * @param bool $flag
+ *
+ * @throws InvalidArgumentException
+ */
+ public function setCheckForUnexecutedCoveredCode($flag)
+ {
+ if (!is_bool($flag)) {
+ throw InvalidArgumentException::create(
+ 1,
+ 'boolean'
+ );
+ }
+
+ $this->checkForUnexecutedCoveredCode = $flag;
+ }
+
+ /**
+ * @deprecated
+ *
+ * @param bool $flag
+ *
+ * @throws InvalidArgumentException
+ */
+ public function setMapTestClassNameToCoveredClassName($flag)
+ {
+ }
+
+ /**
+ * @param bool $flag
+ *
+ * @throws InvalidArgumentException
+ */
+ public function setAddUncoveredFilesFromWhitelist($flag)
+ {
+ if (!is_bool($flag)) {
+ throw InvalidArgumentException::create(
+ 1,
+ 'boolean'
+ );
+ }
+
+ $this->addUncoveredFilesFromWhitelist = $flag;
+ }
+
+ /**
+ * @param bool $flag
+ *
+ * @throws InvalidArgumentException
+ */
+ public function setProcessUncoveredFilesFromWhitelist($flag)
+ {
+ if (!is_bool($flag)) {
+ throw InvalidArgumentException::create(
+ 1,
+ 'boolean'
+ );
+ }
+
+ $this->processUncoveredFilesFromWhitelist = $flag;
+ }
+
+ /**
+ * @param bool $flag
+ *
+ * @throws InvalidArgumentException
+ */
+ public function setDisableIgnoredLines($flag)
+ {
+ if (!is_bool($flag)) {
+ throw InvalidArgumentException::create(
+ 1,
+ 'boolean'
+ );
+ }
+
+ $this->disableIgnoredLines = $flag;
+ }
+
+ /**
+ * @param bool $flag
+ *
+ * @throws InvalidArgumentException
+ */
+ public function setIgnoreDeprecatedCode($flag)
+ {
+ if (!is_bool($flag)) {
+ throw InvalidArgumentException::create(
+ 1,
+ 'boolean'
+ );
+ }
+
+ $this->ignoreDeprecatedCode = $flag;
+ }
+
+ /**
+ * @param array $whitelist
+ */
+ public function setUnintentionallyCoveredSubclassesWhitelist(array $whitelist)
+ {
+ $this->unintentionallyCoveredSubclassesWhitelist = $whitelist;
+ }
+
+ /**
+ * Applies the @covers annotation filtering.
+ *
+ * @param array $data
+ * @param mixed $linesToBeCovered
+ * @param array $linesToBeUsed
+ *
+ * @throws MissingCoversAnnotationException
+ * @throws UnintentionallyCoveredCodeException
+ */
+ private function applyCoversAnnotationFilter(array &$data, $linesToBeCovered, array $linesToBeUsed)
+ {
+ if ($linesToBeCovered === false ||
+ ($this->forceCoversAnnotation && empty($linesToBeCovered))) {
+ if ($this->checkForMissingCoversAnnotation) {
+ throw new MissingCoversAnnotationException;
+ }
+
+ $data = [];
+
+ return;
+ }
+
+ if (empty($linesToBeCovered)) {
+ return;
+ }
+
+ if ($this->checkForUnintentionallyCoveredCode &&
+ (!$this->currentId instanceof \PHPUnit_Framework_TestCase ||
+ (!$this->currentId->isMedium() && !$this->currentId->isLarge()))) {
+ $this->performUnintentionallyCoveredCodeCheck(
+ $data,
+ $linesToBeCovered,
+ $linesToBeUsed
+ );
+ }
+
+ if ($this->checkForUnexecutedCoveredCode) {
+ $this->performUnexecutedCoveredCodeCheck($data, $linesToBeCovered, $linesToBeUsed);
+ }
+
+ $data = array_intersect_key($data, $linesToBeCovered);
+
+ foreach (array_keys($data) as $filename) {
+ $_linesToBeCovered = array_flip($linesToBeCovered[$filename]);
+
+ $data[$filename] = array_intersect_key(
+ $data[$filename],
+ $_linesToBeCovered
+ );
+ }
+ }
+
+ /**
+ * Applies the whitelist filtering.
+ *
+ * @param array $data
+ */
+ private function applyListsFilter(array &$data)
+ {
+ foreach (array_keys($data) as $filename) {
+ if ($this->filter->isFiltered($filename)) {
+ unset($data[$filename]);
+ }
+ }
+ }
+
+ /**
+ * Applies the "ignored lines" filtering.
+ *
+ * @param array $data
+ */
+ private function applyIgnoredLinesFilter(array &$data)
+ {
+ foreach (array_keys($data) as $filename) {
+ if (!$this->filter->isFile($filename)) {
+ continue;
+ }
+
+ foreach ($this->getLinesToBeIgnored($filename) as $line) {
+ unset($data[$filename][$line]);
+ }
+ }
+ }
+
+ /**
+ * @param array $data
+ */
+ private function initializeFilesThatAreSeenTheFirstTime(array $data)
+ {
+ foreach ($data as $file => $lines) {
+ if ($this->filter->isFile($file) && !isset($this->data[$file])) {
+ $this->data[$file] = [];
+
+ foreach ($lines as $k => $v) {
+ $this->data[$file][$k] = $v == -2 ? null : [];
+ }
+ }
+ }
+ }
+
+ /**
+ * Processes whitelisted files that are not covered.
+ */
+ private function addUncoveredFilesFromWhitelist()
+ {
+ $data = [];
+ $uncoveredFiles = array_diff(
+ $this->filter->getWhitelist(),
+ array_keys($this->data)
+ );
+
+ foreach ($uncoveredFiles as $uncoveredFile) {
+ if (!file_exists($uncoveredFile)) {
+ continue;
+ }
+
+ if (!$this->processUncoveredFilesFromWhitelist) {
+ $data[$uncoveredFile] = [];
+
+ $lines = count(file($uncoveredFile));
+
+ for ($i = 1; $i <= $lines; $i++) {
+ $data[$uncoveredFile][$i] = Driver::LINE_NOT_EXECUTED;
+ }
+ }
+ }
+
+ $this->append($data, 'UNCOVERED_FILES_FROM_WHITELIST');
+ }
+
+ /**
+ * Returns the lines of a source file that should be ignored.
+ *
+ * @param string $filename
+ *
+ * @return array
+ *
+ * @throws InvalidArgumentException
+ */
+ private function getLinesToBeIgnored($filename)
+ {
+ if (!is_string($filename)) {
+ throw InvalidArgumentException::create(
+ 1,
+ 'string'
+ );
+ }
+
+ if (!isset($this->ignoredLines[$filename])) {
+ $this->ignoredLines[$filename] = [];
+
+ if ($this->disableIgnoredLines) {
+ return $this->ignoredLines[$filename];
+ }
+
+ $ignore = false;
+ $stop = false;
+ $lines = file($filename);
+ $numLines = count($lines);
+
+ foreach ($lines as $index => $line) {
+ if (!trim($line)) {
+ $this->ignoredLines[$filename][] = $index + 1;
+ }
+ }
+
+ if ($this->cacheTokens) {
+ $tokens = \PHP_Token_Stream_CachingFactory::get($filename);
+ } else {
+ $tokens = new \PHP_Token_Stream($filename);
+ }
+
+ $classes = array_merge($tokens->getClasses(), $tokens->getTraits());
+ $tokens = $tokens->tokens();
+
+ foreach ($tokens as $token) {
+ switch (get_class($token)) {
+ case 'PHP_Token_COMMENT':
+ case 'PHP_Token_DOC_COMMENT':
+ $_token = trim($token);
+ $_line = trim($lines[$token->getLine() - 1]);
+
+ if ($_token == '// @codeCoverageIgnore' ||
+ $_token == '//@codeCoverageIgnore') {
+ $ignore = true;
+ $stop = true;
+ } elseif ($_token == '// @codeCoverageIgnoreStart' ||
+ $_token == '//@codeCoverageIgnoreStart') {
+ $ignore = true;
+ } elseif ($_token == '// @codeCoverageIgnoreEnd' ||
+ $_token == '//@codeCoverageIgnoreEnd') {
+ $stop = true;
+ }
+
+ if (!$ignore) {
+ $start = $token->getLine();
+ $end = $start + substr_count($token, "\n");
+
+ // Do not ignore the first line when there is a token
+ // before the comment
+ if (0 !== strpos($_token, $_line)) {
+ $start++;
+ }
+
+ for ($i = $start; $i < $end; $i++) {
+ $this->ignoredLines[$filename][] = $i;
+ }
+
+ // A DOC_COMMENT token or a COMMENT token starting with "/*"
+ // does not contain the final \n character in its text
+ if (isset($lines[$i-1]) && 0 === strpos($_token, '/*') && '*/' === substr(trim($lines[$i-1]), -2)) {
+ $this->ignoredLines[$filename][] = $i;
+ }
+ }
+ break;
+
+ case 'PHP_Token_INTERFACE':
+ case 'PHP_Token_TRAIT':
+ case 'PHP_Token_CLASS':
+ case 'PHP_Token_FUNCTION':
+ /* @var \PHP_Token_Interface $token */
+
+ $docblock = $token->getDocblock();
+
+ $this->ignoredLines[$filename][] = $token->getLine();
+
+ if (strpos($docblock, '@codeCoverageIgnore') || ($this->ignoreDeprecatedCode && strpos($docblock, '@deprecated'))) {
+ $endLine = $token->getEndLine();
+
+ for ($i = $token->getLine(); $i <= $endLine; $i++) {
+ $this->ignoredLines[$filename][] = $i;
+ }
+ } elseif ($token instanceof \PHP_Token_INTERFACE ||
+ $token instanceof \PHP_Token_TRAIT ||
+ $token instanceof \PHP_Token_CLASS) {
+ if (empty($classes[$token->getName()]['methods'])) {
+ for ($i = $token->getLine();
+ $i <= $token->getEndLine();
+ $i++) {
+ $this->ignoredLines[$filename][] = $i;
+ }
+ } else {
+ $firstMethod = array_shift(
+ $classes[$token->getName()]['methods']
+ );
+
+ do {
+ $lastMethod = array_pop(
+ $classes[$token->getName()]['methods']
+ );
+ } while ($lastMethod !== null &&
+ substr($lastMethod['signature'], 0, 18) == 'anonymous function');
+
+ if ($lastMethod === null) {
+ $lastMethod = $firstMethod;
+ }
+
+ for ($i = $token->getLine();
+ $i < $firstMethod['startLine'];
+ $i++) {
+ $this->ignoredLines[$filename][] = $i;
+ }
+
+ for ($i = $token->getEndLine();
+ $i > $lastMethod['endLine'];
+ $i--) {
+ $this->ignoredLines[$filename][] = $i;
+ }
+ }
+ }
+ break;
+
+ case 'PHP_Token_NAMESPACE':
+ $this->ignoredLines[$filename][] = $token->getEndLine();
+
+ // Intentional fallthrough
+ case 'PHP_Token_DECLARE':
+ case 'PHP_Token_OPEN_TAG':
+ case 'PHP_Token_CLOSE_TAG':
+ case 'PHP_Token_USE':
+ $this->ignoredLines[$filename][] = $token->getLine();
+ break;
+ }
+
+ if ($ignore) {
+ $this->ignoredLines[$filename][] = $token->getLine();
+
+ if ($stop) {
+ $ignore = false;
+ $stop = false;
+ }
+ }
+ }
+
+ $this->ignoredLines[$filename][] = $numLines + 1;
+
+ $this->ignoredLines[$filename] = array_unique(
+ $this->ignoredLines[$filename]
+ );
+
+ sort($this->ignoredLines[$filename]);
+ }
+
+ return $this->ignoredLines[$filename];
+ }
+
+ /**
+ * @param array $data
+ * @param array $linesToBeCovered
+ * @param array $linesToBeUsed
+ *
+ * @throws UnintentionallyCoveredCodeException
+ */
+ private function performUnintentionallyCoveredCodeCheck(array &$data, array $linesToBeCovered, array $linesToBeUsed)
+ {
+ $allowedLines = $this->getAllowedLines(
+ $linesToBeCovered,
+ $linesToBeUsed
+ );
+
+ $unintentionallyCoveredUnits = [];
+
+ foreach ($data as $file => $_data) {
+ foreach ($_data as $line => $flag) {
+ if ($flag == 1 && !isset($allowedLines[$file][$line])) {
+ $unintentionallyCoveredUnits[] = $this->wizard->lookup($file, $line);
+ }
+ }
+ }
+
+ $unintentionallyCoveredUnits = $this->processUnintentionallyCoveredUnits($unintentionallyCoveredUnits);
+
+ if (!empty($unintentionallyCoveredUnits)) {
+ throw new UnintentionallyCoveredCodeException(
+ $unintentionallyCoveredUnits
+ );
+ }
+ }
+
+ /**
+ * @param array $data
+ * @param array $linesToBeCovered
+ * @param array $linesToBeUsed
+ *
+ * @throws CoveredCodeNotExecutedException
+ */
+ private function performUnexecutedCoveredCodeCheck(array &$data, array $linesToBeCovered, array $linesToBeUsed)
+ {
+ $expectedLines = $this->getAllowedLines(
+ $linesToBeCovered,
+ $linesToBeUsed
+ );
+
+ foreach ($data as $file => $_data) {
+ foreach (array_keys($_data) as $line) {
+ if (!isset($expectedLines[$file][$line])) {
+ continue;
+ }
+
+ unset($expectedLines[$file][$line]);
+ }
+ }
+
+ $message = '';
+
+ foreach ($expectedLines as $file => $lines) {
+ if (empty($lines)) {
+ continue;
+ }
+
+ foreach (array_keys($lines) as $line) {
+ $message .= sprintf('- %s:%d' . PHP_EOL, $file, $line);
+ }
+ }
+
+ if (!empty($message)) {
+ throw new CoveredCodeNotExecutedException($message);
+ }
+ }
+
+ /**
+ * @param array $linesToBeCovered
+ * @param array $linesToBeUsed
+ *
+ * @return array
+ */
+ private function getAllowedLines(array $linesToBeCovered, array $linesToBeUsed)
+ {
+ $allowedLines = [];
+
+ foreach (array_keys($linesToBeCovered) as $file) {
+ if (!isset($allowedLines[$file])) {
+ $allowedLines[$file] = [];
+ }
+
+ $allowedLines[$file] = array_merge(
+ $allowedLines[$file],
+ $linesToBeCovered[$file]
+ );
+ }
+
+ foreach (array_keys($linesToBeUsed) as $file) {
+ if (!isset($allowedLines[$file])) {
+ $allowedLines[$file] = [];
+ }
+
+ $allowedLines[$file] = array_merge(
+ $allowedLines[$file],
+ $linesToBeUsed[$file]
+ );
+ }
+
+ foreach (array_keys($allowedLines) as $file) {
+ $allowedLines[$file] = array_flip(
+ array_unique($allowedLines[$file])
+ );
+ }
+
+ return $allowedLines;
+ }
+
+ /**
+ * @return Driver
+ *
+ * @throws RuntimeException
+ */
+ private function selectDriver()
+ {
+ $runtime = new Runtime;
+
+ if (!$runtime->canCollectCodeCoverage()) {
+ throw new RuntimeException('No code coverage driver available');
+ }
+
+ if ($runtime->isHHVM()) {
+ return new HHVM;
+ } elseif ($runtime->isPHPDBG()) {
+ return new PHPDBG;
+ } else {
+ return new Xdebug;
+ }
+ }
+
+ /**
+ * @param array $unintentionallyCoveredUnits
+ *
+ * @return array
+ */
+ private function processUnintentionallyCoveredUnits(array $unintentionallyCoveredUnits)
+ {
+ $unintentionallyCoveredUnits = array_unique($unintentionallyCoveredUnits);
+ sort($unintentionallyCoveredUnits);
+
+ foreach (array_keys($unintentionallyCoveredUnits) as $k => $v) {
+ $unit = explode('::', $unintentionallyCoveredUnits[$k]);
+
+ if (count($unit) != 2) {
+ continue;
+ }
+
+ $class = new \ReflectionClass($unit[0]);
+
+ foreach ($this->unintentionallyCoveredSubclassesWhitelist as $whitelisted) {
+ if ($class->isSubclassOf($whitelisted)) {
+ unset($unintentionallyCoveredUnits[$k]);
+ break;
+ }
+ }
+ }
+
+ return array_values($unintentionallyCoveredUnits);
+ }
+
+ /**
+ * If we are processing uncovered files from whitelist,
+ * we can initialize the data before we start to speed up the tests
+ */
+ protected function initializeData()
+ {
+ $this->isInitialized = true;
+
+ if ($this->processUncoveredFilesFromWhitelist) {
+ $this->shouldCheckForDeadAndUnused = false;
+
+ $this->driver->start(true);
+
+ foreach ($this->filter->getWhitelist() as $file) {
+ if ($this->filter->isFile($file)) {
+ include_once($file);
+ }
+ }
+
+ $data = [];
+ $coverage = $this->driver->stop();
+
+ foreach ($coverage as $file => $fileCoverage) {
+ if ($this->filter->isFiltered($file)) {
+ continue;
+ }
+
+ foreach (array_keys($fileCoverage) as $key) {
+ if ($fileCoverage[$key] == Driver::LINE_EXECUTED) {
+ $fileCoverage[$key] = Driver::LINE_NOT_EXECUTED;
+ }
+ }
+
+ $data[$file] = $fileCoverage;
+ }
+
+ $this->append($data, 'UNCOVERED_FILES_FROM_WHITELIST');
+ }
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Driver/Driver.php b/vendor/phpunit/php-code-coverage/src/Driver/Driver.php
new file mode 100644
index 0000000..bdd1b97
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Driver/Driver.php
@@ -0,0 +1,52 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Driver;
+
+/**
+ * Interface for code coverage drivers.
+ */
+interface Driver
+{
+ /**
+ * @var int
+ *
+ * @see http://xdebug.org/docs/code_coverage
+ */
+ const LINE_EXECUTED = 1;
+
+ /**
+ * @var int
+ *
+ * @see http://xdebug.org/docs/code_coverage
+ */
+ const LINE_NOT_EXECUTED = -1;
+
+ /**
+ * @var int
+ *
+ * @see http://xdebug.org/docs/code_coverage
+ */
+ const LINE_NOT_EXECUTABLE = -2;
+
+ /**
+ * Start collection of code coverage information.
+ *
+ * @param bool $determineUnusedAndDead
+ */
+ public function start($determineUnusedAndDead = true);
+
+ /**
+ * Stop collection of code coverage information.
+ *
+ * @return array
+ */
+ public function stop();
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Driver/HHVM.php b/vendor/phpunit/php-code-coverage/src/Driver/HHVM.php
new file mode 100644
index 0000000..b35ea81
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Driver/HHVM.php
@@ -0,0 +1,29 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Driver;
+
+/**
+ * Driver for HHVM's code coverage functionality.
+ *
+ * @codeCoverageIgnore
+ */
+class HHVM extends Xdebug
+{
+ /**
+ * Start collection of code coverage information.
+ *
+ * @param bool $determineUnusedAndDead
+ */
+ public function start($determineUnusedAndDead = true)
+ {
+ xdebug_start_code_coverage();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Driver/PHPDBG.php b/vendor/phpunit/php-code-coverage/src/Driver/PHPDBG.php
new file mode 100644
index 0000000..86cc844
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Driver/PHPDBG.php
@@ -0,0 +1,111 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Driver;
+
+use SebastianBergmann\CodeCoverage\RuntimeException;
+
+/**
+ * Driver for PHPDBG's code coverage functionality.
+ *
+ * @codeCoverageIgnore
+ */
+class PHPDBG implements Driver
+{
+ /**
+ * Constructor.
+ */
+ public function __construct()
+ {
+ if (PHP_SAPI !== 'phpdbg') {
+ throw new RuntimeException(
+ 'This driver requires the PHPDBG SAPI'
+ );
+ }
+
+ if (!function_exists('phpdbg_start_oplog')) {
+ throw new RuntimeException(
+ 'This build of PHPDBG does not support code coverage'
+ );
+ }
+ }
+
+ /**
+ * Start collection of code coverage information.
+ *
+ * @param bool $determineUnusedAndDead
+ */
+ public function start($determineUnusedAndDead = true)
+ {
+ phpdbg_start_oplog();
+ }
+
+ /**
+ * Stop collection of code coverage information.
+ *
+ * @return array
+ */
+ public function stop()
+ {
+ static $fetchedLines = [];
+
+ $dbgData = phpdbg_end_oplog();
+
+ if ($fetchedLines == []) {
+ $sourceLines = phpdbg_get_executable();
+ } else {
+ $newFiles = array_diff(
+ get_included_files(),
+ array_keys($fetchedLines)
+ );
+
+ if ($newFiles) {
+ $sourceLines = phpdbg_get_executable(
+ ['files' => $newFiles]
+ );
+ } else {
+ $sourceLines = [];
+ }
+ }
+
+ foreach ($sourceLines as $file => $lines) {
+ foreach ($lines as $lineNo => $numExecuted) {
+ $sourceLines[$file][$lineNo] = self::LINE_NOT_EXECUTED;
+ }
+ }
+
+ $fetchedLines = array_merge($fetchedLines, $sourceLines);
+
+ return $this->detectExecutedLines($fetchedLines, $dbgData);
+ }
+
+ /**
+ * Convert phpdbg based data into the format CodeCoverage expects
+ *
+ * @param array $sourceLines
+ * @param array $dbgData
+ *
+ * @return array
+ */
+ private function detectExecutedLines(array $sourceLines, array $dbgData)
+ {
+ foreach ($dbgData as $file => $coveredLines) {
+ foreach ($coveredLines as $lineNo => $numExecuted) {
+ // phpdbg also reports $lineNo=0 when e.g. exceptions get thrown.
+ // make sure we only mark lines executed which are actually executable.
+ if (isset($sourceLines[$file][$lineNo])) {
+ $sourceLines[$file][$lineNo] = self::LINE_EXECUTED;
+ }
+ }
+ }
+
+ return $sourceLines;
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Driver/Xdebug.php b/vendor/phpunit/php-code-coverage/src/Driver/Xdebug.php
new file mode 100644
index 0000000..30099e0
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Driver/Xdebug.php
@@ -0,0 +1,117 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Driver;
+
+use SebastianBergmann\CodeCoverage\RuntimeException;
+
+/**
+ * Driver for Xdebug's code coverage functionality.
+ *
+ * @codeCoverageIgnore
+ */
+class Xdebug implements Driver
+{
+ /**
+ * Cache the number of lines for each file
+ *
+ * @var array
+ */
+ private $cacheNumLines = [];
+
+ /**
+ * Constructor.
+ */
+ public function __construct()
+ {
+ if (!extension_loaded('xdebug')) {
+ throw new RuntimeException('This driver requires Xdebug');
+ }
+
+ if (version_compare(phpversion('xdebug'), '2.2.1', '>=') &&
+ !ini_get('xdebug.coverage_enable')) {
+ throw new RuntimeException(
+ 'xdebug.coverage_enable=On has to be set in php.ini'
+ );
+ }
+ }
+
+ /**
+ * Start collection of code coverage information.
+ *
+ * @param bool $determineUnusedAndDead
+ */
+ public function start($determineUnusedAndDead = true)
+ {
+ if ($determineUnusedAndDead) {
+ xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
+ } else {
+ xdebug_start_code_coverage();
+ }
+ }
+
+ /**
+ * Stop collection of code coverage information.
+ *
+ * @return array
+ */
+ public function stop()
+ {
+ $data = xdebug_get_code_coverage();
+ xdebug_stop_code_coverage();
+
+ return $this->cleanup($data);
+ }
+
+ /**
+ * @param array $data
+ *
+ * @return array
+ */
+ private function cleanup(array $data)
+ {
+ foreach (array_keys($data) as $file) {
+ unset($data[$file][0]);
+
+ if (strpos($file, 'xdebug://debug-eval') !== 0 && file_exists($file)) {
+ $numLines = $this->getNumberOfLinesInFile($file);
+
+ foreach (array_keys($data[$file]) as $line) {
+ if ($line > $numLines) {
+ unset($data[$file][$line]);
+ }
+ }
+ }
+ }
+
+ return $data;
+ }
+
+ /**
+ * @param string $file
+ *
+ * @return int
+ */
+ private function getNumberOfLinesInFile($file)
+ {
+ if (!isset($this->cacheNumLines[$file])) {
+ $buffer = file_get_contents($file);
+ $lines = substr_count($buffer, "\n");
+
+ if (substr($buffer, -1) !== "\n") {
+ $lines++;
+ }
+
+ $this->cacheNumLines[$file] = $lines;
+ }
+
+ return $this->cacheNumLines[$file];
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php b/vendor/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php
new file mode 100644
index 0000000..ca28a23
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php
@@ -0,0 +1,18 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage;
+
+/**
+ * Exception that is raised when covered code is not executed.
+ */
+class CoveredCodeNotExecutedException extends RuntimeException
+{
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Exception/Exception.php b/vendor/phpunit/php-code-coverage/src/Exception/Exception.php
new file mode 100644
index 0000000..a3ba4c4
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Exception/Exception.php
@@ -0,0 +1,18 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage;
+
+/**
+ * Exception interface for php-code-coverage component.
+ */
+interface Exception
+{
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php b/vendor/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php
new file mode 100644
index 0000000..1733f6c
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php
@@ -0,0 +1,37 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage;
+
+class InvalidArgumentException extends \InvalidArgumentException implements Exception
+{
+ /**
+ * @param int $argument
+ * @param string $type
+ * @param mixed $value
+ *
+ * @return InvalidArgumentException
+ */
+ public static function create($argument, $type, $value = null)
+ {
+ $stack = debug_backtrace(0);
+
+ return new self(
+ sprintf(
+ 'Argument #%d%sof %s::%s() must be a %s',
+ $argument,
+ $value !== null ? ' (' . gettype($value) . '#' . $value . ')' : ' (No Value) ',
+ $stack[1]['class'],
+ $stack[1]['function'],
+ $type
+ )
+ );
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php b/vendor/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php
new file mode 100644
index 0000000..7bc5cf3
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php
@@ -0,0 +1,18 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage;
+
+/**
+ * Exception that is raised when @covers must be used but is not.
+ */
+class MissingCoversAnnotationException extends RuntimeException
+{
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Exception/RuntimeException.php b/vendor/phpunit/php-code-coverage/src/Exception/RuntimeException.php
new file mode 100644
index 0000000..c143db7
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Exception/RuntimeException.php
@@ -0,0 +1,15 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage;
+
+class RuntimeException extends \RuntimeException implements Exception
+{
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php b/vendor/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php
new file mode 100644
index 0000000..3ea542b
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php
@@ -0,0 +1,54 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage;
+
+/**
+ * Exception that is raised when code is unintentionally covered.
+ */
+class UnintentionallyCoveredCodeException extends RuntimeException
+{
+ /**
+ * @var array
+ */
+ private $unintentionallyCoveredUnits = [];
+
+ /**
+ * @param array $unintentionallyCoveredUnits
+ */
+ public function __construct(array $unintentionallyCoveredUnits)
+ {
+ $this->unintentionallyCoveredUnits = $unintentionallyCoveredUnits;
+
+ parent::__construct($this->toString());
+ }
+
+ /**
+ * @return array
+ */
+ public function getUnintentionallyCoveredUnits()
+ {
+ return $this->unintentionallyCoveredUnits;
+ }
+
+ /**
+ * @return string
+ */
+ private function toString()
+ {
+ $message = '';
+
+ foreach ($this->unintentionallyCoveredUnits as $unit) {
+ $message .= '- ' . $unit . "\n";
+ }
+
+ return $message;
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Filter.php b/vendor/phpunit/php-code-coverage/src/Filter.php
new file mode 100644
index 0000000..771a657
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Filter.php
@@ -0,0 +1,173 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage;
+
+/**
+ * Filter for whitelisting of code coverage information.
+ */
+class Filter
+{
+ /**
+ * Source files that are whitelisted.
+ *
+ * @var array
+ */
+ private $whitelistedFiles = [];
+
+ /**
+ * Adds a directory to the whitelist (recursively).
+ *
+ * @param string $directory
+ * @param string $suffix
+ * @param string $prefix
+ */
+ public function addDirectoryToWhitelist($directory, $suffix = '.php', $prefix = '')
+ {
+ $facade = new \File_Iterator_Facade;
+ $files = $facade->getFilesAsArray($directory, $suffix, $prefix);
+
+ foreach ($files as $file) {
+ $this->addFileToWhitelist($file);
+ }
+ }
+
+ /**
+ * Adds a file to the whitelist.
+ *
+ * @param string $filename
+ */
+ public function addFileToWhitelist($filename)
+ {
+ $this->whitelistedFiles[realpath($filename)] = true;
+ }
+
+ /**
+ * Adds files to the whitelist.
+ *
+ * @param array $files
+ */
+ public function addFilesToWhitelist(array $files)
+ {
+ foreach ($files as $file) {
+ $this->addFileToWhitelist($file);
+ }
+ }
+
+ /**
+ * Removes a directory from the whitelist (recursively).
+ *
+ * @param string $directory
+ * @param string $suffix
+ * @param string $prefix
+ */
+ public function removeDirectoryFromWhitelist($directory, $suffix = '.php', $prefix = '')
+ {
+ $facade = new \File_Iterator_Facade;
+ $files = $facade->getFilesAsArray($directory, $suffix, $prefix);
+
+ foreach ($files as $file) {
+ $this->removeFileFromWhitelist($file);
+ }
+ }
+
+ /**
+ * Removes a file from the whitelist.
+ *
+ * @param string $filename
+ */
+ public function removeFileFromWhitelist($filename)
+ {
+ $filename = realpath($filename);
+
+ unset($this->whitelistedFiles[$filename]);
+ }
+
+ /**
+ * Checks whether a filename is a real filename.
+ *
+ * @param string $filename
+ *
+ * @return bool
+ */
+ public function isFile($filename)
+ {
+ if ($filename == '-' ||
+ strpos($filename, 'vfs://') === 0 ||
+ strpos($filename, 'xdebug://debug-eval') !== false ||
+ strpos($filename, 'eval()\'d code') !== false ||
+ strpos($filename, 'runtime-created function') !== false ||
+ strpos($filename, 'runkit created function') !== false ||
+ strpos($filename, 'assert code') !== false ||
+ strpos($filename, 'regexp code') !== false) {
+ return false;
+ }
+
+ return file_exists($filename);
+ }
+
+ /**
+ * Checks whether or not a file is filtered.
+ *
+ * @param string $filename
+ *
+ * @return bool
+ */
+ public function isFiltered($filename)
+ {
+ if (!$this->isFile($filename)) {
+ return true;
+ }
+
+ $filename = realpath($filename);
+
+ return !isset($this->whitelistedFiles[$filename]);
+ }
+
+ /**
+ * Returns the list of whitelisted files.
+ *
+ * @return array
+ */
+ public function getWhitelist()
+ {
+ return array_keys($this->whitelistedFiles);
+ }
+
+ /**
+ * Returns whether this filter has a whitelist.
+ *
+ * @return bool
+ */
+ public function hasWhitelist()
+ {
+ return !empty($this->whitelistedFiles);
+ }
+
+ /**
+ * Returns the whitelisted files.
+ *
+ * @return array
+ */
+ public function getWhitelistedFiles()
+ {
+ return $this->whitelistedFiles;
+ }
+
+ /**
+ * Sets the whitelisted files.
+ *
+ * @param array $whitelistedFiles
+ */
+ public function setWhitelistedFiles($whitelistedFiles)
+ {
+ $this->whitelistedFiles = $whitelistedFiles;
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Node/AbstractNode.php b/vendor/phpunit/php-code-coverage/src/Node/AbstractNode.php
new file mode 100644
index 0000000..f360805
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Node/AbstractNode.php
@@ -0,0 +1,342 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Node;
+
+use SebastianBergmann\CodeCoverage\Util;
+
+/**
+ * Base class for nodes in the code coverage information tree.
+ */
+abstract class AbstractNode implements \Countable
+{
+ /**
+ * @var string
+ */
+ private $name;
+
+ /**
+ * @var string
+ */
+ private $path;
+
+ /**
+ * @var array
+ */
+ private $pathArray;
+
+ /**
+ * @var AbstractNode
+ */
+ private $parent;
+
+ /**
+ * @var string
+ */
+ private $id;
+
+ /**
+ * Constructor.
+ *
+ * @param string $name
+ * @param AbstractNode $parent
+ */
+ public function __construct($name, AbstractNode $parent = null)
+ {
+ if (substr($name, -1) == '/') {
+ $name = substr($name, 0, -1);
+ }
+
+ $this->name = $name;
+ $this->parent = $parent;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * @return string
+ */
+ public function getId()
+ {
+ if ($this->id === null) {
+ $parent = $this->getParent();
+
+ if ($parent === null) {
+ $this->id = 'index';
+ } else {
+ $parentId = $parent->getId();
+
+ if ($parentId == 'index') {
+ $this->id = str_replace(':', '_', $this->name);
+ } else {
+ $this->id = $parentId . '/' . $this->name;
+ }
+ }
+ }
+
+ return $this->id;
+ }
+
+ /**
+ * @return string
+ */
+ public function getPath()
+ {
+ if ($this->path === null) {
+ if ($this->parent === null || $this->parent->getPath() === null || $this->parent->getPath() === false) {
+ $this->path = $this->name;
+ } else {
+ $this->path = $this->parent->getPath() . '/' . $this->name;
+ }
+ }
+
+ return $this->path;
+ }
+
+ /**
+ * @return array
+ */
+ public function getPathAsArray()
+ {
+ if ($this->pathArray === null) {
+ if ($this->parent === null) {
+ $this->pathArray = [];
+ } else {
+ $this->pathArray = $this->parent->getPathAsArray();
+ }
+
+ $this->pathArray[] = $this;
+ }
+
+ return $this->pathArray;
+ }
+
+ /**
+ * @return AbstractNode
+ */
+ public function getParent()
+ {
+ return $this->parent;
+ }
+
+ /**
+ * Returns the percentage of classes that has been tested.
+ *
+ * @param bool $asString
+ *
+ * @return int
+ */
+ public function getTestedClassesPercent($asString = true)
+ {
+ return Util::percent(
+ $this->getNumTestedClasses(),
+ $this->getNumClasses(),
+ $asString
+ );
+ }
+
+ /**
+ * Returns the percentage of traits that has been tested.
+ *
+ * @param bool $asString
+ *
+ * @return int
+ */
+ public function getTestedTraitsPercent($asString = true)
+ {
+ return Util::percent(
+ $this->getNumTestedTraits(),
+ $this->getNumTraits(),
+ $asString
+ );
+ }
+
+ /**
+ * Returns the percentage of traits that has been tested.
+ *
+ * @param bool $asString
+ *
+ * @return int
+ */
+ public function getTestedClassesAndTraitsPercent($asString = true)
+ {
+ return Util::percent(
+ $this->getNumTestedClassesAndTraits(),
+ $this->getNumClassesAndTraits(),
+ $asString
+ );
+ }
+
+ /**
+ * Returns the percentage of methods that has been tested.
+ *
+ * @param bool $asString
+ *
+ * @return int
+ */
+ public function getTestedMethodsPercent($asString = true)
+ {
+ return Util::percent(
+ $this->getNumTestedMethods(),
+ $this->getNumMethods(),
+ $asString
+ );
+ }
+
+ /**
+ * Returns the percentage of executed lines.
+ *
+ * @param bool $asString
+ *
+ * @return int
+ */
+ public function getLineExecutedPercent($asString = true)
+ {
+ return Util::percent(
+ $this->getNumExecutedLines(),
+ $this->getNumExecutableLines(),
+ $asString
+ );
+ }
+
+ /**
+ * Returns the number of classes and traits.
+ *
+ * @return int
+ */
+ public function getNumClassesAndTraits()
+ {
+ return $this->getNumClasses() + $this->getNumTraits();
+ }
+
+ /**
+ * Returns the number of tested classes and traits.
+ *
+ * @return int
+ */
+ public function getNumTestedClassesAndTraits()
+ {
+ return $this->getNumTestedClasses() + $this->getNumTestedTraits();
+ }
+
+ /**
+ * Returns the classes and traits of this node.
+ *
+ * @return array
+ */
+ public function getClassesAndTraits()
+ {
+ return array_merge($this->getClasses(), $this->getTraits());
+ }
+
+ /**
+ * Returns the classes of this node.
+ *
+ * @return array
+ */
+ abstract public function getClasses();
+
+ /**
+ * Returns the traits of this node.
+ *
+ * @return array
+ */
+ abstract public function getTraits();
+
+ /**
+ * Returns the functions of this node.
+ *
+ * @return array
+ */
+ abstract public function getFunctions();
+
+ /**
+ * Returns the LOC/CLOC/NCLOC of this node.
+ *
+ * @return array
+ */
+ abstract public function getLinesOfCode();
+
+ /**
+ * Returns the number of executable lines.
+ *
+ * @return int
+ */
+ abstract public function getNumExecutableLines();
+
+ /**
+ * Returns the number of executed lines.
+ *
+ * @return int
+ */
+ abstract public function getNumExecutedLines();
+
+ /**
+ * Returns the number of classes.
+ *
+ * @return int
+ */
+ abstract public function getNumClasses();
+
+ /**
+ * Returns the number of tested classes.
+ *
+ * @return int
+ */
+ abstract public function getNumTestedClasses();
+
+ /**
+ * Returns the number of traits.
+ *
+ * @return int
+ */
+ abstract public function getNumTraits();
+
+ /**
+ * Returns the number of tested traits.
+ *
+ * @return int
+ */
+ abstract public function getNumTestedTraits();
+
+ /**
+ * Returns the number of methods.
+ *
+ * @return int
+ */
+ abstract public function getNumMethods();
+
+ /**
+ * Returns the number of tested methods.
+ *
+ * @return int
+ */
+ abstract public function getNumTestedMethods();
+
+ /**
+ * Returns the number of functions.
+ *
+ * @return int
+ */
+ abstract public function getNumFunctions();
+
+ /**
+ * Returns the number of tested functions.
+ *
+ * @return int
+ */
+ abstract public function getNumTestedFunctions();
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Node/Builder.php b/vendor/phpunit/php-code-coverage/src/Node/Builder.php
new file mode 100644
index 0000000..8a6a65c
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Node/Builder.php
@@ -0,0 +1,244 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Node;
+
+use SebastianBergmann\CodeCoverage\CodeCoverage;
+
+class Builder
+{
+ /**
+ * @param CodeCoverage $coverage
+ *
+ * @return Directory
+ */
+ public function build(CodeCoverage $coverage)
+ {
+ $files = $coverage->getData();
+ $commonPath = $this->reducePaths($files);
+ $root = new Directory(
+ $commonPath,
+ null
+ );
+
+ $this->addItems(
+ $root,
+ $this->buildDirectoryStructure($files),
+ $coverage->getTests(),
+ $coverage->getCacheTokens()
+ );
+
+ return $root;
+ }
+
+ /**
+ * @param Directory $root
+ * @param array $items
+ * @param array $tests
+ * @param bool $cacheTokens
+ */
+ private function addItems(Directory $root, array $items, array $tests, $cacheTokens)
+ {
+ foreach ($items as $key => $value) {
+ if (substr($key, -2) == '/f') {
+ $key = substr($key, 0, -2);
+
+ if (file_exists($root->getPath() . DIRECTORY_SEPARATOR . $key)) {
+ $root->addFile($key, $value, $tests, $cacheTokens);
+ }
+ } else {
+ $child = $root->addDirectory($key);
+ $this->addItems($child, $value, $tests, $cacheTokens);
+ }
+ }
+ }
+
+ /**
+ * Builds an array representation of the directory structure.
+ *
+ * For instance,
+ *
+ * <code>
+ * Array
+ * (
+ * [Money.php] => Array
+ * (
+ * ...
+ * )
+ *
+ * [MoneyBag.php] => Array
+ * (
+ * ...
+ * )
+ * )
+ * </code>
+ *
+ * is transformed into
+ *
+ * <code>
+ * Array
+ * (
+ * [.] => Array
+ * (
+ * [Money.php] => Array
+ * (
+ * ...
+ * )
+ *
+ * [MoneyBag.php] => Array
+ * (
+ * ...
+ * )
+ * )
+ * )
+ * </code>
+ *
+ * @param array $files
+ *
+ * @return array
+ */
+ private function buildDirectoryStructure($files)
+ {
+ $result = [];
+
+ foreach ($files as $path => $file) {
+ $path = explode('/', $path);
+ $pointer = &$result;
+ $max = count($path);
+
+ for ($i = 0; $i < $max; $i++) {
+ if ($i == ($max - 1)) {
+ $type = '/f';
+ } else {
+ $type = '';
+ }
+
+ $pointer = &$pointer[$path[$i] . $type];
+ }
+
+ $pointer = $file;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Reduces the paths by cutting the longest common start path.
+ *
+ * For instance,
+ *
+ * <code>
+ * Array
+ * (
+ * [/home/sb/Money/Money.php] => Array
+ * (
+ * ...
+ * )
+ *
+ * [/home/sb/Money/MoneyBag.php] => Array
+ * (
+ * ...
+ * )
+ * )
+ * </code>
+ *
+ * is reduced to
+ *
+ * <code>
+ * Array
+ * (
+ * [Money.php] => Array
+ * (
+ * ...
+ * )
+ *
+ * [MoneyBag.php] => Array
+ * (
+ * ...
+ * )
+ * )
+ * </code>
+ *
+ * @param array $files
+ *
+ * @return string
+ */
+ private function reducePaths(&$files)
+ {
+ if (empty($files)) {
+ return '.';
+ }
+
+ $commonPath = '';
+ $paths = array_keys($files);
+
+ if (count($files) == 1) {
+ $commonPath = dirname($paths[0]) . '/';
+ $files[basename($paths[0])] = $files[$paths[0]];
+
+ unset($files[$paths[0]]);
+
+ return $commonPath;
+ }
+
+ $max = count($paths);
+
+ for ($i = 0; $i < $max; $i++) {
+ // strip phar:// prefixes
+ if (strpos($paths[$i], 'phar://') === 0) {
+ $paths[$i] = substr($paths[$i], 7);
+ $paths[$i] = strtr($paths[$i], '/', DIRECTORY_SEPARATOR);
+ }
+ $paths[$i] = explode(DIRECTORY_SEPARATOR, $paths[$i]);
+
+ if (empty($paths[$i][0])) {
+ $paths[$i][0] = DIRECTORY_SEPARATOR;
+ }
+ }
+
+ $done = false;
+ $max = count($paths);
+
+ while (!$done) {
+ for ($i = 0; $i < $max - 1; $i++) {
+ if (!isset($paths[$i][0]) ||
+ !isset($paths[$i+1][0]) ||
+ $paths[$i][0] != $paths[$i+1][0]) {
+ $done = true;
+ break;
+ }
+ }
+
+ if (!$done) {
+ $commonPath .= $paths[0][0];
+
+ if ($paths[0][0] != DIRECTORY_SEPARATOR) {
+ $commonPath .= DIRECTORY_SEPARATOR;
+ }
+
+ for ($i = 0; $i < $max; $i++) {
+ array_shift($paths[$i]);
+ }
+ }
+ }
+
+ $original = array_keys($files);
+ $max = count($original);
+
+ for ($i = 0; $i < $max; $i++) {
+ $files[implode('/', $paths[$i])] = $files[$original[$i]];
+ unset($files[$original[$i]]);
+ }
+
+ ksort($files);
+
+ return substr($commonPath, 0, -1);
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Node/Directory.php b/vendor/phpunit/php-code-coverage/src/Node/Directory.php
new file mode 100644
index 0000000..6a9f28d
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Node/Directory.php
@@ -0,0 +1,483 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Node;
+
+use SebastianBergmann\CodeCoverage\InvalidArgumentException;
+
+/**
+ * Represents a directory in the code coverage information tree.
+ */
+class Directory extends AbstractNode implements \IteratorAggregate
+{
+ /**
+ * @var AbstractNode[]
+ */
+ private $children = [];
+
+ /**
+ * @var Directory[]
+ */
+ private $directories = [];
+
+ /**
+ * @var File[]
+ */
+ private $files = [];
+
+ /**
+ * @var array
+ */
+ private $classes;
+
+ /**
+ * @var array
+ */
+ private $traits;
+
+ /**
+ * @var array
+ */
+ private $functions;
+
+ /**
+ * @var array
+ */
+ private $linesOfCode = null;
+
+ /**
+ * @var int
+ */
+ private $numFiles = -1;
+
+ /**
+ * @var int
+ */
+ private $numExecutableLines = -1;
+
+ /**
+ * @var int
+ */
+ private $numExecutedLines = -1;
+
+ /**
+ * @var int
+ */
+ private $numClasses = -1;
+
+ /**
+ * @var int
+ */
+ private $numTestedClasses = -1;
+
+ /**
+ * @var int
+ */
+ private $numTraits = -1;
+
+ /**
+ * @var int
+ */
+ private $numTestedTraits = -1;
+
+ /**
+ * @var int
+ */
+ private $numMethods = -1;
+
+ /**
+ * @var int
+ */
+ private $numTestedMethods = -1;
+
+ /**
+ * @var int
+ */
+ private $numFunctions = -1;
+
+ /**
+ * @var int
+ */
+ private $numTestedFunctions = -1;
+
+ /**
+ * Returns the number of files in/under this node.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ if ($this->numFiles == -1) {
+ $this->numFiles = 0;
+
+ foreach ($this->children as $child) {
+ $this->numFiles += count($child);
+ }
+ }
+
+ return $this->numFiles;
+ }
+
+ /**
+ * Returns an iterator for this node.
+ *
+ * @return \RecursiveIteratorIterator
+ */
+ public function getIterator()
+ {
+ return new \RecursiveIteratorIterator(
+ new Iterator($this),
+ \RecursiveIteratorIterator::SELF_FIRST
+ );
+ }
+
+ /**
+ * Adds a new directory.
+ *
+ * @param string $name
+ *
+ * @return Directory
+ */
+ public function addDirectory($name)
+ {
+ $directory = new self($name, $this);
+
+ $this->children[] = $directory;
+ $this->directories[] = &$this->children[count($this->children) - 1];
+
+ return $directory;
+ }
+
+ /**
+ * Adds a new file.
+ *
+ * @param string $name
+ * @param array $coverageData
+ * @param array $testData
+ * @param bool $cacheTokens
+ *
+ * @return File
+ *
+ * @throws InvalidArgumentException
+ */
+ public function addFile($name, array $coverageData, array $testData, $cacheTokens)
+ {
+ $file = new File(
+ $name,
+ $this,
+ $coverageData,
+ $testData,
+ $cacheTokens
+ );
+
+ $this->children[] = $file;
+ $this->files[] = &$this->children[count($this->children) - 1];
+
+ $this->numExecutableLines = -1;
+ $this->numExecutedLines = -1;
+
+ return $file;
+ }
+
+ /**
+ * Returns the directories in this directory.
+ *
+ * @return array
+ */
+ public function getDirectories()
+ {
+ return $this->directories;
+ }
+
+ /**
+ * Returns the files in this directory.
+ *
+ * @return array
+ */
+ public function getFiles()
+ {
+ return $this->files;
+ }
+
+ /**
+ * Returns the child nodes of this node.
+ *
+ * @return array
+ */
+ public function getChildNodes()
+ {
+ return $this->children;
+ }
+
+ /**
+ * Returns the classes of this node.
+ *
+ * @return array
+ */
+ public function getClasses()
+ {
+ if ($this->classes === null) {
+ $this->classes = [];
+
+ foreach ($this->children as $child) {
+ $this->classes = array_merge(
+ $this->classes,
+ $child->getClasses()
+ );
+ }
+ }
+
+ return $this->classes;
+ }
+
+ /**
+ * Returns the traits of this node.
+ *
+ * @return array
+ */
+ public function getTraits()
+ {
+ if ($this->traits === null) {
+ $this->traits = [];
+
+ foreach ($this->children as $child) {
+ $this->traits = array_merge(
+ $this->traits,
+ $child->getTraits()
+ );
+ }
+ }
+
+ return $this->traits;
+ }
+
+ /**
+ * Returns the functions of this node.
+ *
+ * @return array
+ */
+ public function getFunctions()
+ {
+ if ($this->functions === null) {
+ $this->functions = [];
+
+ foreach ($this->children as $child) {
+ $this->functions = array_merge(
+ $this->functions,
+ $child->getFunctions()
+ );
+ }
+ }
+
+ return $this->functions;
+ }
+
+ /**
+ * Returns the LOC/CLOC/NCLOC of this node.
+ *
+ * @return array
+ */
+ public function getLinesOfCode()
+ {
+ if ($this->linesOfCode === null) {
+ $this->linesOfCode = ['loc' => 0, 'cloc' => 0, 'ncloc' => 0];
+
+ foreach ($this->children as $child) {
+ $linesOfCode = $child->getLinesOfCode();
+
+ $this->linesOfCode['loc'] += $linesOfCode['loc'];
+ $this->linesOfCode['cloc'] += $linesOfCode['cloc'];
+ $this->linesOfCode['ncloc'] += $linesOfCode['ncloc'];
+ }
+ }
+
+ return $this->linesOfCode;
+ }
+
+ /**
+ * Returns the number of executable lines.
+ *
+ * @return int
+ */
+ public function getNumExecutableLines()
+ {
+ if ($this->numExecutableLines == -1) {
+ $this->numExecutableLines = 0;
+
+ foreach ($this->children as $child) {
+ $this->numExecutableLines += $child->getNumExecutableLines();
+ }
+ }
+
+ return $this->numExecutableLines;
+ }
+
+ /**
+ * Returns the number of executed lines.
+ *
+ * @return int
+ */
+ public function getNumExecutedLines()
+ {
+ if ($this->numExecutedLines == -1) {
+ $this->numExecutedLines = 0;
+
+ foreach ($this->children as $child) {
+ $this->numExecutedLines += $child->getNumExecutedLines();
+ }
+ }
+
+ return $this->numExecutedLines;
+ }
+
+ /**
+ * Returns the number of classes.
+ *
+ * @return int
+ */
+ public function getNumClasses()
+ {
+ if ($this->numClasses == -1) {
+ $this->numClasses = 0;
+
+ foreach ($this->children as $child) {
+ $this->numClasses += $child->getNumClasses();
+ }
+ }
+
+ return $this->numClasses;
+ }
+
+ /**
+ * Returns the number of tested classes.
+ *
+ * @return int
+ */
+ public function getNumTestedClasses()
+ {
+ if ($this->numTestedClasses == -1) {
+ $this->numTestedClasses = 0;
+
+ foreach ($this->children as $child) {
+ $this->numTestedClasses += $child->getNumTestedClasses();
+ }
+ }
+
+ return $this->numTestedClasses;
+ }
+
+ /**
+ * Returns the number of traits.
+ *
+ * @return int
+ */
+ public function getNumTraits()
+ {
+ if ($this->numTraits == -1) {
+ $this->numTraits = 0;
+
+ foreach ($this->children as $child) {
+ $this->numTraits += $child->getNumTraits();
+ }
+ }
+
+ return $this->numTraits;
+ }
+
+ /**
+ * Returns the number of tested traits.
+ *
+ * @return int
+ */
+ public function getNumTestedTraits()
+ {
+ if ($this->numTestedTraits == -1) {
+ $this->numTestedTraits = 0;
+
+ foreach ($this->children as $child) {
+ $this->numTestedTraits += $child->getNumTestedTraits();
+ }
+ }
+
+ return $this->numTestedTraits;
+ }
+
+ /**
+ * Returns the number of methods.
+ *
+ * @return int
+ */
+ public function getNumMethods()
+ {
+ if ($this->numMethods == -1) {
+ $this->numMethods = 0;
+
+ foreach ($this->children as $child) {
+ $this->numMethods += $child->getNumMethods();
+ }
+ }
+
+ return $this->numMethods;
+ }
+
+ /**
+ * Returns the number of tested methods.
+ *
+ * @return int
+ */
+ public function getNumTestedMethods()
+ {
+ if ($this->numTestedMethods == -1) {
+ $this->numTestedMethods = 0;
+
+ foreach ($this->children as $child) {
+ $this->numTestedMethods += $child->getNumTestedMethods();
+ }
+ }
+
+ return $this->numTestedMethods;
+ }
+
+ /**
+ * Returns the number of functions.
+ *
+ * @return int
+ */
+ public function getNumFunctions()
+ {
+ if ($this->numFunctions == -1) {
+ $this->numFunctions = 0;
+
+ foreach ($this->children as $child) {
+ $this->numFunctions += $child->getNumFunctions();
+ }
+ }
+
+ return $this->numFunctions;
+ }
+
+ /**
+ * Returns the number of tested functions.
+ *
+ * @return int
+ */
+ public function getNumTestedFunctions()
+ {
+ if ($this->numTestedFunctions == -1) {
+ $this->numTestedFunctions = 0;
+
+ foreach ($this->children as $child) {
+ $this->numTestedFunctions += $child->getNumTestedFunctions();
+ }
+ }
+
+ return $this->numTestedFunctions;
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Node/File.php b/vendor/phpunit/php-code-coverage/src/Node/File.php
new file mode 100644
index 0000000..44856f0
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Node/File.php
@@ -0,0 +1,722 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Node;
+
+use SebastianBergmann\CodeCoverage\InvalidArgumentException;
+
+/**
+ * Represents a file in the code coverage information tree.
+ */
+class File extends AbstractNode
+{
+ /**
+ * @var array
+ */
+ private $coverageData;
+
+ /**
+ * @var array
+ */
+ private $testData;
+
+ /**
+ * @var int
+ */
+ private $numExecutableLines = 0;
+
+ /**
+ * @var int
+ */
+ private $numExecutedLines = 0;
+
+ /**
+ * @var array
+ */
+ private $classes = [];
+
+ /**
+ * @var array
+ */
+ private $traits = [];
+
+ /**
+ * @var array
+ */
+ private $functions = [];
+
+ /**
+ * @var array
+ */
+ private $linesOfCode = [];
+
+ /**
+ * @var int
+ */
+ private $numClasses = null;
+
+ /**
+ * @var int
+ */
+ private $numTestedClasses = 0;
+
+ /**
+ * @var int
+ */
+ private $numTraits = null;
+
+ /**
+ * @var int
+ */
+ private $numTestedTraits = 0;
+
+ /**
+ * @var int
+ */
+ private $numMethods = null;
+
+ /**
+ * @var int
+ */
+ private $numTestedMethods = null;
+
+ /**
+ * @var int
+ */
+ private $numTestedFunctions = null;
+
+ /**
+ * @var array
+ */
+ private $startLines = [];
+
+ /**
+ * @var array
+ */
+ private $endLines = [];
+
+ /**
+ * @var bool
+ */
+ private $cacheTokens;
+
+ /**
+ * Constructor.
+ *
+ * @param string $name
+ * @param AbstractNode $parent
+ * @param array $coverageData
+ * @param array $testData
+ * @param bool $cacheTokens
+ *
+ * @throws InvalidArgumentException
+ */
+ public function __construct($name, AbstractNode $parent, array $coverageData, array $testData, $cacheTokens)
+ {
+ if (!is_bool($cacheTokens)) {
+ throw InvalidArgumentException::create(
+ 1,
+ 'boolean'
+ );
+ }
+
+ parent::__construct($name, $parent);
+
+ $this->coverageData = $coverageData;
+ $this->testData = $testData;
+ $this->cacheTokens = $cacheTokens;
+
+ $this->calculateStatistics();
+ }
+
+ /**
+ * Returns the number of files in/under this node.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return 1;
+ }
+
+ /**
+ * Returns the code coverage data of this node.
+ *
+ * @return array
+ */
+ public function getCoverageData()
+ {
+ return $this->coverageData;
+ }
+
+ /**
+ * Returns the test data of this node.
+ *
+ * @return array
+ */
+ public function getTestData()
+ {
+ return $this->testData;
+ }
+
+ /**
+ * Returns the classes of this node.
+ *
+ * @return array
+ */
+ public function getClasses()
+ {
+ return $this->classes;
+ }
+
+ /**
+ * Returns the traits of this node.
+ *
+ * @return array
+ */
+ public function getTraits()
+ {
+ return $this->traits;
+ }
+
+ /**
+ * Returns the functions of this node.
+ *
+ * @return array
+ */
+ public function getFunctions()
+ {
+ return $this->functions;
+ }
+
+ /**
+ * Returns the LOC/CLOC/NCLOC of this node.
+ *
+ * @return array
+ */
+ public function getLinesOfCode()
+ {
+ return $this->linesOfCode;
+ }
+
+ /**
+ * Returns the number of executable lines.
+ *
+ * @return int
+ */
+ public function getNumExecutableLines()
+ {
+ return $this->numExecutableLines;
+ }
+
+ /**
+ * Returns the number of executed lines.
+ *
+ * @return int
+ */
+ public function getNumExecutedLines()
+ {
+ return $this->numExecutedLines;
+ }
+
+ /**
+ * Returns the number of classes.
+ *
+ * @return int
+ */
+ public function getNumClasses()
+ {
+ if ($this->numClasses === null) {
+ $this->numClasses = 0;
+
+ foreach ($this->classes as $class) {
+ foreach ($class['methods'] as $method) {
+ if ($method['executableLines'] > 0) {
+ $this->numClasses++;
+
+ continue 2;
+ }
+ }
+ }
+ }
+
+ return $this->numClasses;
+ }
+
+ /**
+ * Returns the number of tested classes.
+ *
+ * @return int
+ */
+ public function getNumTestedClasses()
+ {
+ return $this->numTestedClasses;
+ }
+
+ /**
+ * Returns the number of traits.
+ *
+ * @return int
+ */
+ public function getNumTraits()
+ {
+ if ($this->numTraits === null) {
+ $this->numTraits = 0;
+
+ foreach ($this->traits as $trait) {
+ foreach ($trait['methods'] as $method) {
+ if ($method['executableLines'] > 0) {
+ $this->numTraits++;
+
+ continue 2;
+ }
+ }
+ }
+ }
+
+ return $this->numTraits;
+ }
+
+ /**
+ * Returns the number of tested traits.
+ *
+ * @return int
+ */
+ public function getNumTestedTraits()
+ {
+ return $this->numTestedTraits;
+ }
+
+ /**
+ * Returns the number of methods.
+ *
+ * @return int
+ */
+ public function getNumMethods()
+ {
+ if ($this->numMethods === null) {
+ $this->numMethods = 0;
+
+ foreach ($this->classes as $class) {
+ foreach ($class['methods'] as $method) {
+ if ($method['executableLines'] > 0) {
+ $this->numMethods++;
+ }
+ }
+ }
+
+ foreach ($this->traits as $trait) {
+ foreach ($trait['methods'] as $method) {
+ if ($method['executableLines'] > 0) {
+ $this->numMethods++;
+ }
+ }
+ }
+ }
+
+ return $this->numMethods;
+ }
+
+ /**
+ * Returns the number of tested methods.
+ *
+ * @return int
+ */
+ public function getNumTestedMethods()
+ {
+ if ($this->numTestedMethods === null) {
+ $this->numTestedMethods = 0;
+
+ foreach ($this->classes as $class) {
+ foreach ($class['methods'] as $method) {
+ if ($method['executableLines'] > 0 &&
+ $method['coverage'] == 100) {
+ $this->numTestedMethods++;
+ }
+ }
+ }
+
+ foreach ($this->traits as $trait) {
+ foreach ($trait['methods'] as $method) {
+ if ($method['executableLines'] > 0 &&
+ $method['coverage'] == 100) {
+ $this->numTestedMethods++;
+ }
+ }
+ }
+ }
+
+ return $this->numTestedMethods;
+ }
+
+ /**
+ * Returns the number of functions.
+ *
+ * @return int
+ */
+ public function getNumFunctions()
+ {
+ return count($this->functions);
+ }
+
+ /**
+ * Returns the number of tested functions.
+ *
+ * @return int
+ */
+ public function getNumTestedFunctions()
+ {
+ if ($this->numTestedFunctions === null) {
+ $this->numTestedFunctions = 0;
+
+ foreach ($this->functions as $function) {
+ if ($function['executableLines'] > 0 &&
+ $function['coverage'] == 100) {
+ $this->numTestedFunctions++;
+ }
+ }
+ }
+
+ return $this->numTestedFunctions;
+ }
+
+ /**
+ * Calculates coverage statistics for the file.
+ */
+ protected function calculateStatistics()
+ {
+ $classStack = $functionStack = [];
+
+ if ($this->cacheTokens) {
+ $tokens = \PHP_Token_Stream_CachingFactory::get($this->getPath());
+ } else {
+ $tokens = new \PHP_Token_Stream($this->getPath());
+ }
+
+ $this->processClasses($tokens);
+ $this->processTraits($tokens);
+ $this->processFunctions($tokens);
+ $this->linesOfCode = $tokens->getLinesOfCode();
+ unset($tokens);
+
+ for ($lineNumber = 1; $lineNumber <= $this->linesOfCode['loc']; $lineNumber++) {
+ if (isset($this->startLines[$lineNumber])) {
+ // Start line of a class.
+ if (isset($this->startLines[$lineNumber]['className'])) {
+ if (isset($currentClass)) {
+ $classStack[] = &$currentClass;
+ }
+
+ $currentClass = &$this->startLines[$lineNumber];
+ } // Start line of a trait.
+ elseif (isset($this->startLines[$lineNumber]['traitName'])) {
+ $currentTrait = &$this->startLines[$lineNumber];
+ } // Start line of a method.
+ elseif (isset($this->startLines[$lineNumber]['methodName'])) {
+ $currentMethod = &$this->startLines[$lineNumber];
+ } // Start line of a function.
+ elseif (isset($this->startLines[$lineNumber]['functionName'])) {
+ if (isset($currentFunction)) {
+ $functionStack[] = &$currentFunction;
+ }
+
+ $currentFunction = &$this->startLines[$lineNumber];
+ }
+ }
+
+ if (isset($this->coverageData[$lineNumber])) {
+ if (isset($currentClass)) {
+ $currentClass['executableLines']++;
+ }
+
+ if (isset($currentTrait)) {
+ $currentTrait['executableLines']++;
+ }
+
+ if (isset($currentMethod)) {
+ $currentMethod['executableLines']++;
+ }
+
+ if (isset($currentFunction)) {
+ $currentFunction['executableLines']++;
+ }
+
+ $this->numExecutableLines++;
+
+ if (count($this->coverageData[$lineNumber]) > 0) {
+ if (isset($currentClass)) {
+ $currentClass['executedLines']++;
+ }
+
+ if (isset($currentTrait)) {
+ $currentTrait['executedLines']++;
+ }
+
+ if (isset($currentMethod)) {
+ $currentMethod['executedLines']++;
+ }
+
+ if (isset($currentFunction)) {
+ $currentFunction['executedLines']++;
+ }
+
+ $this->numExecutedLines++;
+ }
+ }
+
+ if (isset($this->endLines[$lineNumber])) {
+ // End line of a class.
+ if (isset($this->endLines[$lineNumber]['className'])) {
+ unset($currentClass);
+
+ if ($classStack) {
+ end($classStack);
+ $key = key($classStack);
+ $currentClass = &$classStack[$key];
+ unset($classStack[$key]);
+ }
+ } // End line of a trait.
+ elseif (isset($this->endLines[$lineNumber]['traitName'])) {
+ unset($currentTrait);
+ } // End line of a method.
+ elseif (isset($this->endLines[$lineNumber]['methodName'])) {
+ unset($currentMethod);
+ } // End line of a function.
+ elseif (isset($this->endLines[$lineNumber]['functionName'])) {
+ unset($currentFunction);
+
+ if ($functionStack) {
+ end($functionStack);
+ $key = key($functionStack);
+ $currentFunction = &$functionStack[$key];
+ unset($functionStack[$key]);
+ }
+ }
+ }
+ }
+
+ foreach ($this->traits as &$trait) {
+ foreach ($trait['methods'] as &$method) {
+ if ($method['executableLines'] > 0) {
+ $method['coverage'] = ($method['executedLines'] /
+ $method['executableLines']) * 100;
+ } else {
+ $method['coverage'] = 100;
+ }
+
+ $method['crap'] = $this->crap(
+ $method['ccn'],
+ $method['coverage']
+ );
+
+ $trait['ccn'] += $method['ccn'];
+ }
+
+ if ($trait['executableLines'] > 0) {
+ $trait['coverage'] = ($trait['executedLines'] /
+ $trait['executableLines']) * 100;
+
+ if ($trait['coverage'] == 100) {
+ $this->numTestedClasses++;
+ }
+ } else {
+ $trait['coverage'] = 100;
+ }
+
+ $trait['crap'] = $this->crap(
+ $trait['ccn'],
+ $trait['coverage']
+ );
+ }
+
+ foreach ($this->classes as &$class) {
+ foreach ($class['methods'] as &$method) {
+ if ($method['executableLines'] > 0) {
+ $method['coverage'] = ($method['executedLines'] /
+ $method['executableLines']) * 100;
+ } else {
+ $method['coverage'] = 100;
+ }
+
+ $method['crap'] = $this->crap(
+ $method['ccn'],
+ $method['coverage']
+ );
+
+ $class['ccn'] += $method['ccn'];
+ }
+
+ if ($class['executableLines'] > 0) {
+ $class['coverage'] = ($class['executedLines'] /
+ $class['executableLines']) * 100;
+
+ if ($class['coverage'] == 100) {
+ $this->numTestedClasses++;
+ }
+ } else {
+ $class['coverage'] = 100;
+ }
+
+ $class['crap'] = $this->crap(
+ $class['ccn'],
+ $class['coverage']
+ );
+ }
+ }
+
+ /**
+ * @param \PHP_Token_Stream $tokens
+ */
+ protected function processClasses(\PHP_Token_Stream $tokens)
+ {
+ $classes = $tokens->getClasses();
+ unset($tokens);
+
+ $link = $this->getId() . '.html#';
+
+ foreach ($classes as $className => $class) {
+ $this->classes[$className] = [
+ 'className' => $className,
+ 'methods' => [],
+ 'startLine' => $class['startLine'],
+ 'executableLines' => 0,
+ 'executedLines' => 0,
+ 'ccn' => 0,
+ 'coverage' => 0,
+ 'crap' => 0,
+ 'package' => $class['package'],
+ 'link' => $link . $class['startLine']
+ ];
+
+ $this->startLines[$class['startLine']] = &$this->classes[$className];
+ $this->endLines[$class['endLine']] = &$this->classes[$className];
+
+ foreach ($class['methods'] as $methodName => $method) {
+ $this->classes[$className]['methods'][$methodName] = $this->newMethod($methodName, $method, $link);
+
+ $this->startLines[$method['startLine']] = &$this->classes[$className]['methods'][$methodName];
+ $this->endLines[$method['endLine']] = &$this->classes[$className]['methods'][$methodName];
+ }
+ }
+ }
+
+ /**
+ * @param \PHP_Token_Stream $tokens
+ */
+ protected function processTraits(\PHP_Token_Stream $tokens)
+ {
+ $traits = $tokens->getTraits();
+ unset($tokens);
+
+ $link = $this->getId() . '.html#';
+
+ foreach ($traits as $traitName => $trait) {
+ $this->traits[$traitName] = [
+ 'traitName' => $traitName,
+ 'methods' => [],
+ 'startLine' => $trait['startLine'],
+ 'executableLines' => 0,
+ 'executedLines' => 0,
+ 'ccn' => 0,
+ 'coverage' => 0,
+ 'crap' => 0,
+ 'package' => $trait['package'],
+ 'link' => $link . $trait['startLine']
+ ];
+
+ $this->startLines[$trait['startLine']] = &$this->traits[$traitName];
+ $this->endLines[$trait['endLine']] = &$this->traits[$traitName];
+
+ foreach ($trait['methods'] as $methodName => $method) {
+ $this->traits[$traitName]['methods'][$methodName] = $this->newMethod($methodName, $method, $link);
+
+ $this->startLines[$method['startLine']] = &$this->traits[$traitName]['methods'][$methodName];
+ $this->endLines[$method['endLine']] = &$this->traits[$traitName]['methods'][$methodName];
+ }
+ }
+ }
+
+ /**
+ * @param \PHP_Token_Stream $tokens
+ */
+ protected function processFunctions(\PHP_Token_Stream $tokens)
+ {
+ $functions = $tokens->getFunctions();
+ unset($tokens);
+
+ $link = $this->getId() . '.html#';
+
+ foreach ($functions as $functionName => $function) {
+ $this->functions[$functionName] = [
+ 'functionName' => $functionName,
+ 'signature' => $function['signature'],
+ 'startLine' => $function['startLine'],
+ 'executableLines' => 0,
+ 'executedLines' => 0,
+ 'ccn' => $function['ccn'],
+ 'coverage' => 0,
+ 'crap' => 0,
+ 'link' => $link . $function['startLine']
+ ];
+
+ $this->startLines[$function['startLine']] = &$this->functions[$functionName];
+ $this->endLines[$function['endLine']] = &$this->functions[$functionName];
+ }
+ }
+
+ /**
+ * Calculates the Change Risk Anti-Patterns (CRAP) index for a unit of code
+ * based on its cyclomatic complexity and percentage of code coverage.
+ *
+ * @param int $ccn
+ * @param float $coverage
+ *
+ * @return string
+ */
+ protected function crap($ccn, $coverage)
+ {
+ if ($coverage == 0) {
+ return (string) (pow($ccn, 2) + $ccn);
+ }
+
+ if ($coverage >= 95) {
+ return (string) $ccn;
+ }
+
+ return sprintf(
+ '%01.2F',
+ pow($ccn, 2) * pow(1 - $coverage/100, 3) + $ccn
+ );
+ }
+
+ /**
+ * @param string $methodName
+ * @param array $method
+ * @param string $link
+ *
+ * @return array
+ */
+ private function newMethod($methodName, array $method, $link)
+ {
+ return [
+ 'methodName' => $methodName,
+ 'visibility' => $method['visibility'],
+ 'signature' => $method['signature'],
+ 'startLine' => $method['startLine'],
+ 'endLine' => $method['endLine'],
+ 'executableLines' => 0,
+ 'executedLines' => 0,
+ 'ccn' => $method['ccn'],
+ 'coverage' => 0,
+ 'crap' => 0,
+ 'link' => $link . $method['startLine'],
+ ];
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Node/Iterator.php b/vendor/phpunit/php-code-coverage/src/Node/Iterator.php
new file mode 100644
index 0000000..e246380
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Node/Iterator.php
@@ -0,0 +1,103 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Node;
+
+/**
+ * Recursive iterator for node object graphs.
+ */
+class Iterator implements \RecursiveIterator
+{
+ /**
+ * @var int
+ */
+ private $position;
+
+ /**
+ * @var AbstractNode[]
+ */
+ private $nodes;
+
+ /**
+ * @param Directory $node
+ */
+ public function __construct(Directory $node)
+ {
+ $this->nodes = $node->getChildNodes();
+ }
+
+ /**
+ * Rewinds the Iterator to the first element.
+ */
+ public function rewind()
+ {
+ $this->position = 0;
+ }
+
+ /**
+ * Checks if there is a current element after calls to rewind() or next().
+ *
+ * @return bool
+ */
+ public function valid()
+ {
+ return $this->position < count($this->nodes);
+ }
+
+ /**
+ * Returns the key of the current element.
+ *
+ * @return int
+ */
+ public function key()
+ {
+ return $this->position;
+ }
+
+ /**
+ * Returns the current element.
+ *
+ * @return \PHPUnit_Framework_Test
+ */
+ public function current()
+ {
+ return $this->valid() ? $this->nodes[$this->position] : null;
+ }
+
+ /**
+ * Moves forward to next element.
+ */
+ public function next()
+ {
+ $this->position++;
+ }
+
+ /**
+ * Returns the sub iterator for the current element.
+ *
+ * @return Iterator
+ */
+ public function getChildren()
+ {
+ return new self(
+ $this->nodes[$this->position]
+ );
+ }
+
+ /**
+ * Checks whether the current element has children.
+ *
+ * @return bool
+ */
+ public function hasChildren()
+ {
+ return $this->nodes[$this->position] instanceof Directory;
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Clover.php b/vendor/phpunit/php-code-coverage/src/Report/Clover.php
new file mode 100644
index 0000000..054b1df
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Clover.php
@@ -0,0 +1,251 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report;
+
+use SebastianBergmann\CodeCoverage\CodeCoverage;
+use SebastianBergmann\CodeCoverage\Node\File;
+
+/**
+ * Generates a Clover XML logfile from a code coverage object.
+ */
+class Clover
+{
+ /**
+ * @param CodeCoverage $coverage
+ * @param string $target
+ * @param string $name
+ *
+ * @return string
+ */
+ public function process(CodeCoverage $coverage, $target = null, $name = null)
+ {
+ $xmlDocument = new \DOMDocument('1.0', 'UTF-8');
+ $xmlDocument->formatOutput = true;
+
+ $xmlCoverage = $xmlDocument->createElement('coverage');
+ $xmlCoverage->setAttribute('generated', (int) $_SERVER['REQUEST_TIME']);
+ $xmlDocument->appendChild($xmlCoverage);
+
+ $xmlProject = $xmlDocument->createElement('project');
+ $xmlProject->setAttribute('timestamp', (int) $_SERVER['REQUEST_TIME']);
+
+ if (is_string($name)) {
+ $xmlProject->setAttribute('name', $name);
+ }
+
+ $xmlCoverage->appendChild($xmlProject);
+
+ $packages = [];
+ $report = $coverage->getReport();
+ unset($coverage);
+
+ foreach ($report as $item) {
+ if (!$item instanceof File) {
+ continue;
+ }
+
+ /* @var File $item */
+
+ $xmlFile = $xmlDocument->createElement('file');
+ $xmlFile->setAttribute('name', $item->getPath());
+
+ $classes = $item->getClassesAndTraits();
+ $coverage = $item->getCoverageData();
+ $lines = [];
+ $namespace = 'global';
+
+ foreach ($classes as $className => $class) {
+ $classStatements = 0;
+ $coveredClassStatements = 0;
+ $coveredMethods = 0;
+ $classMethods = 0;
+
+ foreach ($class['methods'] as $methodName => $method) {
+ if ($method['executableLines'] == 0) {
+ continue;
+ }
+
+ $classMethods++;
+ $classStatements += $method['executableLines'];
+ $coveredClassStatements += $method['executedLines'];
+
+ if ($method['coverage'] == 100) {
+ $coveredMethods++;
+ }
+
+ $methodCount = 0;
+
+ foreach (range($method['startLine'], $method['endLine']) as $line) {
+ if (isset($coverage[$line]) && ($coverage[$line] !== null)) {
+ $methodCount = max($methodCount, count($coverage[$line]));
+ }
+ }
+
+ $lines[$method['startLine']] = [
+ 'ccn' => $method['ccn'],
+ 'count' => $methodCount,
+ 'crap' => $method['crap'],
+ 'type' => 'method',
+ 'visibility' => $method['visibility'],
+ 'name' => $methodName
+ ];
+ }
+
+ if (!empty($class['package']['namespace'])) {
+ $namespace = $class['package']['namespace'];
+ }
+
+ $xmlClass = $xmlDocument->createElement('class');
+ $xmlClass->setAttribute('name', $className);
+ $xmlClass->setAttribute('namespace', $namespace);
+
+ if (!empty($class['package']['fullPackage'])) {
+ $xmlClass->setAttribute(
+ 'fullPackage',
+ $class['package']['fullPackage']
+ );
+ }
+
+ if (!empty($class['package']['category'])) {
+ $xmlClass->setAttribute(
+ 'category',
+ $class['package']['category']
+ );
+ }
+
+ if (!empty($class['package']['package'])) {
+ $xmlClass->setAttribute(
+ 'package',
+ $class['package']['package']
+ );
+ }
+
+ if (!empty($class['package']['subpackage'])) {
+ $xmlClass->setAttribute(
+ 'subpackage',
+ $class['package']['subpackage']
+ );
+ }
+
+ $xmlFile->appendChild($xmlClass);
+
+ $xmlMetrics = $xmlDocument->createElement('metrics');
+ $xmlMetrics->setAttribute('complexity', $class['ccn']);
+ $xmlMetrics->setAttribute('methods', $classMethods);
+ $xmlMetrics->setAttribute('coveredmethods', $coveredMethods);
+ $xmlMetrics->setAttribute('conditionals', 0);
+ $xmlMetrics->setAttribute('coveredconditionals', 0);
+ $xmlMetrics->setAttribute('statements', $classStatements);
+ $xmlMetrics->setAttribute('coveredstatements', $coveredClassStatements);
+ $xmlMetrics->setAttribute('elements', $classMethods + $classStatements /* + conditionals */);
+ $xmlMetrics->setAttribute('coveredelements', $coveredMethods + $coveredClassStatements /* + coveredconditionals */);
+ $xmlClass->appendChild($xmlMetrics);
+ }
+
+ foreach ($coverage as $line => $data) {
+ if ($data === null || isset($lines[$line])) {
+ continue;
+ }
+
+ $lines[$line] = [
+ 'count' => count($data), 'type' => 'stmt'
+ ];
+ }
+
+ ksort($lines);
+
+ foreach ($lines as $line => $data) {
+ $xmlLine = $xmlDocument->createElement('line');
+ $xmlLine->setAttribute('num', $line);
+ $xmlLine->setAttribute('type', $data['type']);
+
+ if (isset($data['name'])) {
+ $xmlLine->setAttribute('name', $data['name']);
+ }
+
+ if (isset($data['visibility'])) {
+ $xmlLine->setAttribute('visibility', $data['visibility']);
+ }
+
+ if (isset($data['ccn'])) {
+ $xmlLine->setAttribute('complexity', $data['ccn']);
+ }
+
+ if (isset($data['crap'])) {
+ $xmlLine->setAttribute('crap', $data['crap']);
+ }
+
+ $xmlLine->setAttribute('count', $data['count']);
+ $xmlFile->appendChild($xmlLine);
+ }
+
+ $linesOfCode = $item->getLinesOfCode();
+
+ $xmlMetrics = $xmlDocument->createElement('metrics');
+ $xmlMetrics->setAttribute('loc', $linesOfCode['loc']);
+ $xmlMetrics->setAttribute('ncloc', $linesOfCode['ncloc']);
+ $xmlMetrics->setAttribute('classes', $item->getNumClassesAndTraits());
+ $xmlMetrics->setAttribute('methods', $item->getNumMethods());
+ $xmlMetrics->setAttribute('coveredmethods', $item->getNumTestedMethods());
+ $xmlMetrics->setAttribute('conditionals', 0);
+ $xmlMetrics->setAttribute('coveredconditionals', 0);
+ $xmlMetrics->setAttribute('statements', $item->getNumExecutableLines());
+ $xmlMetrics->setAttribute('coveredstatements', $item->getNumExecutedLines());
+ $xmlMetrics->setAttribute('elements', $item->getNumMethods() + $item->getNumExecutableLines() /* + conditionals */);
+ $xmlMetrics->setAttribute('coveredelements', $item->getNumTestedMethods() + $item->getNumExecutedLines() /* + coveredconditionals */);
+ $xmlFile->appendChild($xmlMetrics);
+
+ if ($namespace == 'global') {
+ $xmlProject->appendChild($xmlFile);
+ } else {
+ if (!isset($packages[$namespace])) {
+ $packages[$namespace] = $xmlDocument->createElement(
+ 'package'
+ );
+
+ $packages[$namespace]->setAttribute('name', $namespace);
+ $xmlProject->appendChild($packages[$namespace]);
+ }
+
+ $packages[$namespace]->appendChild($xmlFile);
+ }
+ }
+
+ $linesOfCode = $report->getLinesOfCode();
+
+ $xmlMetrics = $xmlDocument->createElement('metrics');
+ $xmlMetrics->setAttribute('files', count($report));
+ $xmlMetrics->setAttribute('loc', $linesOfCode['loc']);
+ $xmlMetrics->setAttribute('ncloc', $linesOfCode['ncloc']);
+ $xmlMetrics->setAttribute('classes', $report->getNumClassesAndTraits());
+ $xmlMetrics->setAttribute('methods', $report->getNumMethods());
+ $xmlMetrics->setAttribute('coveredmethods', $report->getNumTestedMethods());
+ $xmlMetrics->setAttribute('conditionals', 0);
+ $xmlMetrics->setAttribute('coveredconditionals', 0);
+ $xmlMetrics->setAttribute('statements', $report->getNumExecutableLines());
+ $xmlMetrics->setAttribute('coveredstatements', $report->getNumExecutedLines());
+ $xmlMetrics->setAttribute('elements', $report->getNumMethods() + $report->getNumExecutableLines() /* + conditionals */);
+ $xmlMetrics->setAttribute('coveredelements', $report->getNumTestedMethods() + $report->getNumExecutedLines() /* + coveredconditionals */);
+ $xmlProject->appendChild($xmlMetrics);
+
+ $buffer = $xmlDocument->saveXML();
+
+ if ($target !== null) {
+ if (!is_dir(dirname($target))) {
+ mkdir(dirname($target), 0777, true);
+ }
+
+ file_put_contents($target, $buffer);
+ }
+
+ return $buffer;
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Crap4j.php b/vendor/phpunit/php-code-coverage/src/Report/Crap4j.php
new file mode 100644
index 0000000..7adf78f
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Crap4j.php
@@ -0,0 +1,172 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report;
+
+use SebastianBergmann\CodeCoverage\CodeCoverage;
+use SebastianBergmann\CodeCoverage\Node\File;
+use SebastianBergmann\CodeCoverage\InvalidArgumentException;
+
+class Crap4j
+{
+ /**
+ * @var int
+ */
+ private $threshold;
+
+ /**
+ * @param int $threshold
+ */
+ public function __construct($threshold = 30)
+ {
+ if (!is_int($threshold)) {
+ throw InvalidArgumentException::create(
+ 1,
+ 'integer'
+ );
+ }
+
+ $this->threshold = $threshold;
+ }
+
+ /**
+ * @param CodeCoverage $coverage
+ * @param string $target
+ * @param string $name
+ *
+ * @return string
+ */
+ public function process(CodeCoverage $coverage, $target = null, $name = null)
+ {
+ $document = new \DOMDocument('1.0', 'UTF-8');
+ $document->formatOutput = true;
+
+ $root = $document->createElement('crap_result');
+ $document->appendChild($root);
+
+ $project = $document->createElement('project', is_string($name) ? $name : '');
+ $root->appendChild($project);
+ $root->appendChild($document->createElement('timestamp', date('Y-m-d H:i:s', (int) $_SERVER['REQUEST_TIME'])));
+
+ $stats = $document->createElement('stats');
+ $methodsNode = $document->createElement('methods');
+
+ $report = $coverage->getReport();
+ unset($coverage);
+
+ $fullMethodCount = 0;
+ $fullCrapMethodCount = 0;
+ $fullCrapLoad = 0;
+ $fullCrap = 0;
+
+ foreach ($report as $item) {
+ $namespace = 'global';
+
+ if (!$item instanceof File) {
+ continue;
+ }
+
+ $file = $document->createElement('file');
+ $file->setAttribute('name', $item->getPath());
+
+ $classes = $item->getClassesAndTraits();
+
+ foreach ($classes as $className => $class) {
+ foreach ($class['methods'] as $methodName => $method) {
+ $crapLoad = $this->getCrapLoad($method['crap'], $method['ccn'], $method['coverage']);
+
+ $fullCrap += $method['crap'];
+ $fullCrapLoad += $crapLoad;
+ $fullMethodCount++;
+
+ if ($method['crap'] >= $this->threshold) {
+ $fullCrapMethodCount++;
+ }
+
+ $methodNode = $document->createElement('method');
+
+ if (!empty($class['package']['namespace'])) {
+ $namespace = $class['package']['namespace'];
+ }
+
+ $methodNode->appendChild($document->createElement('package', $namespace));
+ $methodNode->appendChild($document->createElement('className', $className));
+ $methodNode->appendChild($document->createElement('methodName', $methodName));
+ $methodNode->appendChild($document->createElement('methodSignature', htmlspecialchars($method['signature'])));
+ $methodNode->appendChild($document->createElement('fullMethod', htmlspecialchars($method['signature'])));
+ $methodNode->appendChild($document->createElement('crap', $this->roundValue($method['crap'])));
+ $methodNode->appendChild($document->createElement('complexity', $method['ccn']));
+ $methodNode->appendChild($document->createElement('coverage', $this->roundValue($method['coverage'])));
+ $methodNode->appendChild($document->createElement('crapLoad', round($crapLoad)));
+
+ $methodsNode->appendChild($methodNode);
+ }
+ }
+ }
+
+ $stats->appendChild($document->createElement('name', 'Method Crap Stats'));
+ $stats->appendChild($document->createElement('methodCount', $fullMethodCount));
+ $stats->appendChild($document->createElement('crapMethodCount', $fullCrapMethodCount));
+ $stats->appendChild($document->createElement('crapLoad', round($fullCrapLoad)));
+ $stats->appendChild($document->createElement('totalCrap', $fullCrap));
+
+ if ($fullMethodCount > 0) {
+ $crapMethodPercent = $this->roundValue((100 * $fullCrapMethodCount) / $fullMethodCount);
+ } else {
+ $crapMethodPercent = 0;
+ }
+
+ $stats->appendChild($document->createElement('crapMethodPercent', $crapMethodPercent));
+
+ $root->appendChild($stats);
+ $root->appendChild($methodsNode);
+
+ $buffer = $document->saveXML();
+
+ if ($target !== null) {
+ if (!is_dir(dirname($target))) {
+ mkdir(dirname($target), 0777, true);
+ }
+
+ file_put_contents($target, $buffer);
+ }
+
+ return $buffer;
+ }
+
+ /**
+ * @param float $crapValue
+ * @param int $cyclomaticComplexity
+ * @param float $coveragePercent
+ *
+ * @return float
+ */
+ private function getCrapLoad($crapValue, $cyclomaticComplexity, $coveragePercent)
+ {
+ $crapLoad = 0;
+
+ if ($crapValue >= $this->threshold) {
+ $crapLoad += $cyclomaticComplexity * (1.0 - $coveragePercent / 100);
+ $crapLoad += $cyclomaticComplexity / $this->threshold;
+ }
+
+ return $crapLoad;
+ }
+
+ /**
+ * @param float $value
+ *
+ * @return float
+ */
+ private function roundValue($value)
+ {
+ return round($value, 2);
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Facade.php b/vendor/phpunit/php-code-coverage/src/Report/Html/Facade.php
new file mode 100644
index 0000000..adcfe42
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Facade.php
@@ -0,0 +1,179 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Html;
+
+use SebastianBergmann\CodeCoverage\CodeCoverage;
+use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
+use SebastianBergmann\CodeCoverage\RuntimeException;
+
+/**
+ * Generates an HTML report from a code coverage object.
+ */
+class Facade
+{
+ /**
+ * @var string
+ */
+ private $templatePath;
+
+ /**
+ * @var string
+ */
+ private $generator;
+
+ /**
+ * @var int
+ */
+ private $lowUpperBound;
+
+ /**
+ * @var int
+ */
+ private $highLowerBound;
+
+ /**
+ * Constructor.
+ *
+ * @param int $lowUpperBound
+ * @param int $highLowerBound
+ * @param string $generator
+ */
+ public function __construct($lowUpperBound = 50, $highLowerBound = 90, $generator = '')
+ {
+ $this->generator = $generator;
+ $this->highLowerBound = $highLowerBound;
+ $this->lowUpperBound = $lowUpperBound;
+ $this->templatePath = __DIR__ . '/Renderer/Template/';
+ }
+
+ /**
+ * @param CodeCoverage $coverage
+ * @param string $target
+ */
+ public function process(CodeCoverage $coverage, $target)
+ {
+ $target = $this->getDirectory($target);
+ $report = $coverage->getReport();
+ unset($coverage);
+
+ if (!isset($_SERVER['REQUEST_TIME'])) {
+ $_SERVER['REQUEST_TIME'] = time();
+ }
+
+ $date = date('D M j G:i:s T Y', $_SERVER['REQUEST_TIME']);
+
+ $dashboard = new Dashboard(
+ $this->templatePath,
+ $this->generator,
+ $date,
+ $this->lowUpperBound,
+ $this->highLowerBound
+ );
+
+ $directory = new Directory(
+ $this->templatePath,
+ $this->generator,
+ $date,
+ $this->lowUpperBound,
+ $this->highLowerBound
+ );
+
+ $file = new File(
+ $this->templatePath,
+ $this->generator,
+ $date,
+ $this->lowUpperBound,
+ $this->highLowerBound
+ );
+
+ $directory->render($report, $target . 'index.html');
+ $dashboard->render($report, $target . 'dashboard.html');
+
+ foreach ($report as $node) {
+ $id = $node->getId();
+
+ if ($node instanceof DirectoryNode) {
+ if (!file_exists($target . $id)) {
+ mkdir($target . $id, 0777, true);
+ }
+
+ $directory->render($node, $target . $id . '/index.html');
+ $dashboard->render($node, $target . $id . '/dashboard.html');
+ } else {
+ $dir = dirname($target . $id);
+
+ if (!file_exists($dir)) {
+ mkdir($dir, 0777, true);
+ }
+
+ $file->render($node, $target . $id . '.html');
+ }
+ }
+
+ $this->copyFiles($target);
+ }
+
+ /**
+ * @param string $target
+ */
+ private function copyFiles($target)
+ {
+ $dir = $this->getDirectory($target . 'css');
+ copy($this->templatePath . 'css/bootstrap.min.css', $dir . 'bootstrap.min.css');
+ copy($this->templatePath . 'css/nv.d3.min.css', $dir . 'nv.d3.min.css');
+ copy($this->templatePath . 'css/style.css', $dir . 'style.css');
+
+ $dir = $this->getDirectory($target . 'fonts');
+ copy($this->templatePath . 'fonts/glyphicons-halflings-regular.eot', $dir . 'glyphicons-halflings-regular.eot');
+ copy($this->templatePath . 'fonts/glyphicons-halflings-regular.svg', $dir . 'glyphicons-halflings-regular.svg');
+ copy($this->templatePath . 'fonts/glyphicons-halflings-regular.ttf', $dir . 'glyphicons-halflings-regular.ttf');
+ copy($this->templatePath . 'fonts/glyphicons-halflings-regular.woff', $dir . 'glyphicons-halflings-regular.woff');
+ copy($this->templatePath . 'fonts/glyphicons-halflings-regular.woff2', $dir . 'glyphicons-halflings-regular.woff2');
+
+ $dir = $this->getDirectory($target . 'js');
+ copy($this->templatePath . 'js/bootstrap.min.js', $dir . 'bootstrap.min.js');
+ copy($this->templatePath . 'js/d3.min.js', $dir . 'd3.min.js');
+ copy($this->templatePath . 'js/holder.min.js', $dir . 'holder.min.js');
+ copy($this->templatePath . 'js/html5shiv.min.js', $dir . 'html5shiv.min.js');
+ copy($this->templatePath . 'js/jquery.min.js', $dir . 'jquery.min.js');
+ copy($this->templatePath . 'js/nv.d3.min.js', $dir . 'nv.d3.min.js');
+ copy($this->templatePath . 'js/respond.min.js', $dir . 'respond.min.js');
+ }
+
+ /**
+ * @param string $directory
+ *
+ * @return string
+ *
+ * @throws RuntimeException
+ */
+ private function getDirectory($directory)
+ {
+ if (substr($directory, -1, 1) != DIRECTORY_SEPARATOR) {
+ $directory .= DIRECTORY_SEPARATOR;
+ }
+
+ if (is_dir($directory)) {
+ return $directory;
+ }
+
+ if (@mkdir($directory, 0777, true)) {
+ return $directory;
+ }
+
+ throw new RuntimeException(
+ sprintf(
+ 'Directory "%s" does not exist.',
+ $directory
+ )
+ );
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer.php b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer.php
new file mode 100644
index 0000000..da0937e
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer.php
@@ -0,0 +1,298 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Html;
+
+use SebastianBergmann\CodeCoverage\Node\AbstractNode;
+use SebastianBergmann\CodeCoverage\Node\File as FileNode;
+use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
+use SebastianBergmann\Environment\Runtime;
+use SebastianBergmann\Version;
+
+/**
+ * Base class for node renderers.
+ */
+abstract class Renderer
+{
+ /**
+ * @var string
+ */
+ protected $templatePath;
+
+ /**
+ * @var string
+ */
+ protected $generator;
+
+ /**
+ * @var string
+ */
+ protected $date;
+
+ /**
+ * @var int
+ */
+ protected $lowUpperBound;
+
+ /**
+ * @var int
+ */
+ protected $highLowerBound;
+
+ /**
+ * @var string
+ */
+ protected $version;
+
+ /**
+ * Constructor.
+ *
+ * @param string $templatePath
+ * @param string $generator
+ * @param string $date
+ * @param int $lowUpperBound
+ * @param int $highLowerBound
+ */
+ public function __construct($templatePath, $generator, $date, $lowUpperBound, $highLowerBound)
+ {
+ $version = new Version('4.0.8', dirname(dirname(dirname(dirname(__DIR__)))));
+
+ $this->templatePath = $templatePath;
+ $this->generator = $generator;
+ $this->date = $date;
+ $this->lowUpperBound = $lowUpperBound;
+ $this->highLowerBound = $highLowerBound;
+ $this->version = $version->getVersion();
+ }
+
+ /**
+ * @param \Text_Template $template
+ * @param array $data
+ *
+ * @return string
+ */
+ protected function renderItemTemplate(\Text_Template $template, array $data)
+ {
+ $numSeparator = '&nbsp;/&nbsp;';
+
+ if (isset($data['numClasses']) && $data['numClasses'] > 0) {
+ $classesLevel = $this->getColorLevel($data['testedClassesPercent']);
+
+ $classesNumber = $data['numTestedClasses'] . $numSeparator .
+ $data['numClasses'];
+
+ $classesBar = $this->getCoverageBar(
+ $data['testedClassesPercent']
+ );
+ } else {
+ $classesLevel = '';
+ $classesNumber = '0' . $numSeparator . '0';
+ $classesBar = '';
+ $data['testedClassesPercentAsString'] = 'n/a';
+ }
+
+ if ($data['numMethods'] > 0) {
+ $methodsLevel = $this->getColorLevel($data['testedMethodsPercent']);
+
+ $methodsNumber = $data['numTestedMethods'] . $numSeparator .
+ $data['numMethods'];
+
+ $methodsBar = $this->getCoverageBar(
+ $data['testedMethodsPercent']
+ );
+ } else {
+ $methodsLevel = '';
+ $methodsNumber = '0' . $numSeparator . '0';
+ $methodsBar = '';
+ $data['testedMethodsPercentAsString'] = 'n/a';
+ }
+
+ if ($data['numExecutableLines'] > 0) {
+ $linesLevel = $this->getColorLevel($data['linesExecutedPercent']);
+
+ $linesNumber = $data['numExecutedLines'] . $numSeparator .
+ $data['numExecutableLines'];
+
+ $linesBar = $this->getCoverageBar(
+ $data['linesExecutedPercent']
+ );
+ } else {
+ $linesLevel = '';
+ $linesNumber = '0' . $numSeparator . '0';
+ $linesBar = '';
+ $data['linesExecutedPercentAsString'] = 'n/a';
+ }
+
+ $template->setVar(
+ [
+ 'icon' => isset($data['icon']) ? $data['icon'] : '',
+ 'crap' => isset($data['crap']) ? $data['crap'] : '',
+ 'name' => $data['name'],
+ 'lines_bar' => $linesBar,
+ 'lines_executed_percent' => $data['linesExecutedPercentAsString'],
+ 'lines_level' => $linesLevel,
+ 'lines_number' => $linesNumber,
+ 'methods_bar' => $methodsBar,
+ 'methods_tested_percent' => $data['testedMethodsPercentAsString'],
+ 'methods_level' => $methodsLevel,
+ 'methods_number' => $methodsNumber,
+ 'classes_bar' => $classesBar,
+ 'classes_tested_percent' => isset($data['testedClassesPercentAsString']) ? $data['testedClassesPercentAsString'] : '',
+ 'classes_level' => $classesLevel,
+ 'classes_number' => $classesNumber
+ ]
+ );
+
+ return $template->render();
+ }
+
+ /**
+ * @param \Text_Template $template
+ * @param AbstractNode $node
+ */
+ protected function setCommonTemplateVariables(\Text_Template $template, AbstractNode $node)
+ {
+ $template->setVar(
+ [
+ 'id' => $node->getId(),
+ 'full_path' => $node->getPath(),
+ 'path_to_root' => $this->getPathToRoot($node),
+ 'breadcrumbs' => $this->getBreadcrumbs($node),
+ 'date' => $this->date,
+ 'version' => $this->version,
+ 'runtime' => $this->getRuntimeString(),
+ 'generator' => $this->generator,
+ 'low_upper_bound' => $this->lowUpperBound,
+ 'high_lower_bound' => $this->highLowerBound
+ ]
+ );
+ }
+
+ protected function getBreadcrumbs(AbstractNode $node)
+ {
+ $breadcrumbs = '';
+ $path = $node->getPathAsArray();
+ $pathToRoot = [];
+ $max = count($path);
+
+ if ($node instanceof FileNode) {
+ $max--;
+ }
+
+ for ($i = 0; $i < $max; $i++) {
+ $pathToRoot[] = str_repeat('../', $i);
+ }
+
+ foreach ($path as $step) {
+ if ($step !== $node) {
+ $breadcrumbs .= $this->getInactiveBreadcrumb(
+ $step,
+ array_pop($pathToRoot)
+ );
+ } else {
+ $breadcrumbs .= $this->getActiveBreadcrumb($step);
+ }
+ }
+
+ return $breadcrumbs;
+ }
+
+ protected function getActiveBreadcrumb(AbstractNode $node)
+ {
+ $buffer = sprintf(
+ ' <li class="active">%s</li>' . "\n",
+ $node->getName()
+ );
+
+ if ($node instanceof DirectoryNode) {
+ $buffer .= ' <li>(<a href="dashboard.html">Dashboard</a>)</li>' . "\n";
+ }
+
+ return $buffer;
+ }
+
+ protected function getInactiveBreadcrumb(AbstractNode $node, $pathToRoot)
+ {
+ return sprintf(
+ ' <li><a href="%sindex.html">%s</a></li>' . "\n",
+ $pathToRoot,
+ $node->getName()
+ );
+ }
+
+ protected function getPathToRoot(AbstractNode $node)
+ {
+ $id = $node->getId();
+ $depth = substr_count($id, '/');
+
+ if ($id != 'index' &&
+ $node instanceof DirectoryNode) {
+ $depth++;
+ }
+
+ return str_repeat('../', $depth);
+ }
+
+ protected function getCoverageBar($percent)
+ {
+ $level = $this->getColorLevel($percent);
+
+ $template = new \Text_Template(
+ $this->templatePath . 'coverage_bar.html',
+ '{{',
+ '}}'
+ );
+
+ $template->setVar(['level' => $level, 'percent' => sprintf('%.2F', $percent)]);
+
+ return $template->render();
+ }
+
+ /**
+ * @param int $percent
+ *
+ * @return string
+ */
+ protected function getColorLevel($percent)
+ {
+ if ($percent <= $this->lowUpperBound) {
+ return 'danger';
+ } elseif ($percent > $this->lowUpperBound &&
+ $percent < $this->highLowerBound) {
+ return 'warning';
+ } else {
+ return 'success';
+ }
+ }
+
+ /**
+ * @return string
+ */
+ private function getRuntimeString()
+ {
+ $runtime = new Runtime;
+
+ $buffer = sprintf(
+ '<a href="%s" target="_top">%s %s</a>',
+ $runtime->getVendorUrl(),
+ $runtime->getName(),
+ $runtime->getVersion()
+ );
+
+ if ($runtime->hasXdebug() && !$runtime->hasPHPDBGCodeCoverage()) {
+ $buffer .= sprintf(
+ ' with <a href="https://xdebug.org/">Xdebug %s</a>',
+ phpversion('xdebug')
+ );
+ }
+
+ return $buffer;
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php
new file mode 100644
index 0000000..7cde175
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php
@@ -0,0 +1,302 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Html;
+
+use SebastianBergmann\CodeCoverage\Node\AbstractNode;
+use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
+
+/**
+ * Renders the dashboard for a directory node.
+ */
+class Dashboard extends Renderer
+{
+ /**
+ * @param DirectoryNode $node
+ * @param string $file
+ */
+ public function render(DirectoryNode $node, $file)
+ {
+ $classes = $node->getClassesAndTraits();
+ $template = new \Text_Template(
+ $this->templatePath . 'dashboard.html',
+ '{{',
+ '}}'
+ );
+
+ $this->setCommonTemplateVariables($template, $node);
+
+ $baseLink = $node->getId() . '/';
+ $complexity = $this->complexity($classes, $baseLink);
+ $coverageDistribution = $this->coverageDistribution($classes);
+ $insufficientCoverage = $this->insufficientCoverage($classes, $baseLink);
+ $projectRisks = $this->projectRisks($classes, $baseLink);
+
+ $template->setVar(
+ [
+ 'insufficient_coverage_classes' => $insufficientCoverage['class'],
+ 'insufficient_coverage_methods' => $insufficientCoverage['method'],
+ 'project_risks_classes' => $projectRisks['class'],
+ 'project_risks_methods' => $projectRisks['method'],
+ 'complexity_class' => $complexity['class'],
+ 'complexity_method' => $complexity['method'],
+ 'class_coverage_distribution' => $coverageDistribution['class'],
+ 'method_coverage_distribution' => $coverageDistribution['method']
+ ]
+ );
+
+ $template->renderTo($file);
+ }
+
+ /**
+ * Returns the data for the Class/Method Complexity charts.
+ *
+ * @param array $classes
+ * @param string $baseLink
+ *
+ * @return array
+ */
+ protected function complexity(array $classes, $baseLink)
+ {
+ $result = ['class' => [], 'method' => []];
+
+ foreach ($classes as $className => $class) {
+ foreach ($class['methods'] as $methodName => $method) {
+ if ($className != '*') {
+ $methodName = $className . '::' . $methodName;
+ }
+
+ $result['method'][] = [
+ $method['coverage'],
+ $method['ccn'],
+ sprintf(
+ '<a href="%s">%s</a>',
+ str_replace($baseLink, '', $method['link']),
+ $methodName
+ )
+ ];
+ }
+
+ $result['class'][] = [
+ $class['coverage'],
+ $class['ccn'],
+ sprintf(
+ '<a href="%s">%s</a>',
+ str_replace($baseLink, '', $class['link']),
+ $className
+ )
+ ];
+ }
+
+ return [
+ 'class' => json_encode($result['class']),
+ 'method' => json_encode($result['method'])
+ ];
+ }
+
+ /**
+ * Returns the data for the Class / Method Coverage Distribution chart.
+ *
+ * @param array $classes
+ *
+ * @return array
+ */
+ protected function coverageDistribution(array $classes)
+ {
+ $result = [
+ 'class' => [
+ '0%' => 0,
+ '0-10%' => 0,
+ '10-20%' => 0,
+ '20-30%' => 0,
+ '30-40%' => 0,
+ '40-50%' => 0,
+ '50-60%' => 0,
+ '60-70%' => 0,
+ '70-80%' => 0,
+ '80-90%' => 0,
+ '90-100%' => 0,
+ '100%' => 0
+ ],
+ 'method' => [
+ '0%' => 0,
+ '0-10%' => 0,
+ '10-20%' => 0,
+ '20-30%' => 0,
+ '30-40%' => 0,
+ '40-50%' => 0,
+ '50-60%' => 0,
+ '60-70%' => 0,
+ '70-80%' => 0,
+ '80-90%' => 0,
+ '90-100%' => 0,
+ '100%' => 0
+ ]
+ ];
+
+ foreach ($classes as $class) {
+ foreach ($class['methods'] as $methodName => $method) {
+ if ($method['coverage'] == 0) {
+ $result['method']['0%']++;
+ } elseif ($method['coverage'] == 100) {
+ $result['method']['100%']++;
+ } else {
+ $key = floor($method['coverage'] / 10) * 10;
+ $key = $key . '-' . ($key + 10) . '%';
+ $result['method'][$key]++;
+ }
+ }
+
+ if ($class['coverage'] == 0) {
+ $result['class']['0%']++;
+ } elseif ($class['coverage'] == 100) {
+ $result['class']['100%']++;
+ } else {
+ $key = floor($class['coverage'] / 10) * 10;
+ $key = $key . '-' . ($key + 10) . '%';
+ $result['class'][$key]++;
+ }
+ }
+
+ return [
+ 'class' => json_encode(array_values($result['class'])),
+ 'method' => json_encode(array_values($result['method']))
+ ];
+ }
+
+ /**
+ * Returns the classes / methods with insufficient coverage.
+ *
+ * @param array $classes
+ * @param string $baseLink
+ *
+ * @return array
+ */
+ protected function insufficientCoverage(array $classes, $baseLink)
+ {
+ $leastTestedClasses = [];
+ $leastTestedMethods = [];
+ $result = ['class' => '', 'method' => ''];
+
+ foreach ($classes as $className => $class) {
+ foreach ($class['methods'] as $methodName => $method) {
+ if ($method['coverage'] < $this->highLowerBound) {
+ if ($className != '*') {
+ $key = $className . '::' . $methodName;
+ } else {
+ $key = $methodName;
+ }
+
+ $leastTestedMethods[$key] = $method['coverage'];
+ }
+ }
+
+ if ($class['coverage'] < $this->highLowerBound) {
+ $leastTestedClasses[$className] = $class['coverage'];
+ }
+ }
+
+ asort($leastTestedClasses);
+ asort($leastTestedMethods);
+
+ foreach ($leastTestedClasses as $className => $coverage) {
+ $result['class'] .= sprintf(
+ ' <tr><td><a href="%s">%s</a></td><td class="text-right">%d%%</td></tr>' . "\n",
+ str_replace($baseLink, '', $classes[$className]['link']),
+ $className,
+ $coverage
+ );
+ }
+
+ foreach ($leastTestedMethods as $methodName => $coverage) {
+ list($class, $method) = explode('::', $methodName);
+
+ $result['method'] .= sprintf(
+ ' <tr><td><a href="%s"><abbr title="%s">%s</abbr></a></td><td class="text-right">%d%%</td></tr>' . "\n",
+ str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']),
+ $methodName,
+ $method,
+ $coverage
+ );
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns the project risks according to the CRAP index.
+ *
+ * @param array $classes
+ * @param string $baseLink
+ *
+ * @return array
+ */
+ protected function projectRisks(array $classes, $baseLink)
+ {
+ $classRisks = [];
+ $methodRisks = [];
+ $result = ['class' => '', 'method' => ''];
+
+ foreach ($classes as $className => $class) {
+ foreach ($class['methods'] as $methodName => $method) {
+ if ($method['coverage'] < $this->highLowerBound &&
+ $method['ccn'] > 1) {
+ if ($className != '*') {
+ $key = $className . '::' . $methodName;
+ } else {
+ $key = $methodName;
+ }
+
+ $methodRisks[$key] = $method['crap'];
+ }
+ }
+
+ if ($class['coverage'] < $this->highLowerBound &&
+ $class['ccn'] > count($class['methods'])) {
+ $classRisks[$className] = $class['crap'];
+ }
+ }
+
+ arsort($classRisks);
+ arsort($methodRisks);
+
+ foreach ($classRisks as $className => $crap) {
+ $result['class'] .= sprintf(
+ ' <tr><td><a href="%s">%s</a></td><td class="text-right">%d</td></tr>' . "\n",
+ str_replace($baseLink, '', $classes[$className]['link']),
+ $className,
+ $crap
+ );
+ }
+
+ foreach ($methodRisks as $methodName => $crap) {
+ list($class, $method) = explode('::', $methodName);
+
+ $result['method'] .= sprintf(
+ ' <tr><td><a href="%s"><abbr title="%s">%s</abbr></a></td><td class="text-right">%d</td></tr>' . "\n",
+ str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']),
+ $methodName,
+ $method,
+ $crap
+ );
+ }
+
+ return $result;
+ }
+
+ protected function getActiveBreadcrumb(AbstractNode $node)
+ {
+ return sprintf(
+ ' <li><a href="index.html">%s</a></li>' . "\n" .
+ ' <li class="active">(Dashboard)</li>' . "\n",
+ $node->getName()
+ );
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php
new file mode 100644
index 0000000..a4b1b96
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php
@@ -0,0 +1,101 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Html;
+
+use SebastianBergmann\CodeCoverage\Node\AbstractNode as Node;
+use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
+
+/**
+ * Renders a directory node.
+ */
+class Directory extends Renderer
+{
+ /**
+ * @param DirectoryNode $node
+ * @param string $file
+ */
+ public function render(DirectoryNode $node, $file)
+ {
+ $template = new \Text_Template($this->templatePath . 'directory.html', '{{', '}}');
+
+ $this->setCommonTemplateVariables($template, $node);
+
+ $items = $this->renderItem($node, true);
+
+ foreach ($node->getDirectories() as $item) {
+ $items .= $this->renderItem($item);
+ }
+
+ foreach ($node->getFiles() as $item) {
+ $items .= $this->renderItem($item);
+ }
+
+ $template->setVar(
+ [
+ 'id' => $node->getId(),
+ 'items' => $items
+ ]
+ );
+
+ $template->renderTo($file);
+ }
+
+ /**
+ * @param Node $node
+ * @param bool $total
+ *
+ * @return string
+ */
+ protected function renderItem(Node $node, $total = false)
+ {
+ $data = [
+ 'numClasses' => $node->getNumClassesAndTraits(),
+ 'numTestedClasses' => $node->getNumTestedClassesAndTraits(),
+ 'numMethods' => $node->getNumMethods(),
+ 'numTestedMethods' => $node->getNumTestedMethods(),
+ 'linesExecutedPercent' => $node->getLineExecutedPercent(false),
+ 'linesExecutedPercentAsString' => $node->getLineExecutedPercent(),
+ 'numExecutedLines' => $node->getNumExecutedLines(),
+ 'numExecutableLines' => $node->getNumExecutableLines(),
+ 'testedMethodsPercent' => $node->getTestedMethodsPercent(false),
+ 'testedMethodsPercentAsString' => $node->getTestedMethodsPercent(),
+ 'testedClassesPercent' => $node->getTestedClassesAndTraitsPercent(false),
+ 'testedClassesPercentAsString' => $node->getTestedClassesAndTraitsPercent()
+ ];
+
+ if ($total) {
+ $data['name'] = 'Total';
+ } else {
+ if ($node instanceof DirectoryNode) {
+ $data['name'] = sprintf(
+ '<a href="%s/index.html">%s</a>',
+ $node->getName(),
+ $node->getName()
+ );
+
+ $data['icon'] = '<span class="glyphicon glyphicon-folder-open"></span> ';
+ } else {
+ $data['name'] = sprintf(
+ '<a href="%s.html">%s</a>',
+ $node->getName(),
+ $node->getName()
+ );
+
+ $data['icon'] = '<span class="glyphicon glyphicon-file"></span> ';
+ }
+ }
+
+ return $this->renderItemTemplate(
+ new \Text_Template($this->templatePath . 'directory_item.html', '{{', '}}'),
+ $data
+ );
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php
new file mode 100644
index 0000000..5461c9e
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php
@@ -0,0 +1,551 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Html;
+
+use SebastianBergmann\CodeCoverage\Node\File as FileNode;
+use SebastianBergmann\CodeCoverage\Util;
+
+/**
+ * Renders a file node.
+ */
+class File extends Renderer
+{
+ /**
+ * @var int
+ */
+ private $htmlspecialcharsFlags;
+
+ /**
+ * Constructor.
+ *
+ * @param string $templatePath
+ * @param string $generator
+ * @param string $date
+ * @param int $lowUpperBound
+ * @param int $highLowerBound
+ */
+ public function __construct($templatePath, $generator, $date, $lowUpperBound, $highLowerBound)
+ {
+ parent::__construct(
+ $templatePath,
+ $generator,
+ $date,
+ $lowUpperBound,
+ $highLowerBound
+ );
+
+ $this->htmlspecialcharsFlags = ENT_COMPAT;
+
+ $this->htmlspecialcharsFlags = $this->htmlspecialcharsFlags | ENT_HTML401 | ENT_SUBSTITUTE;
+ }
+
+ /**
+ * @param FileNode $node
+ * @param string $file
+ */
+ public function render(FileNode $node, $file)
+ {
+ $template = new \Text_Template($this->templatePath . 'file.html', '{{', '}}');
+
+ $template->setVar(
+ [
+ 'items' => $this->renderItems($node),
+ 'lines' => $this->renderSource($node)
+ ]
+ );
+
+ $this->setCommonTemplateVariables($template, $node);
+
+ $template->renderTo($file);
+ }
+
+ /**
+ * @param FileNode $node
+ *
+ * @return string
+ */
+ protected function renderItems(FileNode $node)
+ {
+ $template = new \Text_Template($this->templatePath . 'file_item.html', '{{', '}}');
+
+ $methodItemTemplate = new \Text_Template(
+ $this->templatePath . 'method_item.html',
+ '{{',
+ '}}'
+ );
+
+ $items = $this->renderItemTemplate(
+ $template,
+ [
+ 'name' => 'Total',
+ 'numClasses' => $node->getNumClassesAndTraits(),
+ 'numTestedClasses' => $node->getNumTestedClassesAndTraits(),
+ 'numMethods' => $node->getNumMethods(),
+ 'numTestedMethods' => $node->getNumTestedMethods(),
+ 'linesExecutedPercent' => $node->getLineExecutedPercent(false),
+ 'linesExecutedPercentAsString' => $node->getLineExecutedPercent(),
+ 'numExecutedLines' => $node->getNumExecutedLines(),
+ 'numExecutableLines' => $node->getNumExecutableLines(),
+ 'testedMethodsPercent' => $node->getTestedMethodsPercent(false),
+ 'testedMethodsPercentAsString' => $node->getTestedMethodsPercent(),
+ 'testedClassesPercent' => $node->getTestedClassesAndTraitsPercent(false),
+ 'testedClassesPercentAsString' => $node->getTestedClassesAndTraitsPercent(),
+ 'crap' => '<abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr>'
+ ]
+ );
+
+ $items .= $this->renderFunctionItems(
+ $node->getFunctions(),
+ $methodItemTemplate
+ );
+
+ $items .= $this->renderTraitOrClassItems(
+ $node->getTraits(),
+ $template,
+ $methodItemTemplate
+ );
+
+ $items .= $this->renderTraitOrClassItems(
+ $node->getClasses(),
+ $template,
+ $methodItemTemplate
+ );
+
+ return $items;
+ }
+
+ /**
+ * @param array $items
+ * @param \Text_Template $template
+ * @param \Text_Template $methodItemTemplate
+ *
+ * @return string
+ */
+ protected function renderTraitOrClassItems(array $items, \Text_Template $template, \Text_Template $methodItemTemplate)
+ {
+ if (empty($items)) {
+ return '';
+ }
+
+ $buffer = '';
+
+ foreach ($items as $name => $item) {
+ $numMethods = count($item['methods']);
+ $numTestedMethods = 0;
+
+ foreach ($item['methods'] as $method) {
+ if ($method['executedLines'] == $method['executableLines']) {
+ $numTestedMethods++;
+ }
+ }
+
+ if ($item['executableLines'] > 0) {
+ $numClasses = 1;
+ $numTestedClasses = $numTestedMethods == $numMethods ? 1 : 0;
+ $linesExecutedPercentAsString = Util::percent(
+ $item['executedLines'],
+ $item['executableLines'],
+ true
+ );
+ } else {
+ $numClasses = 'n/a';
+ $numTestedClasses = 'n/a';
+ $linesExecutedPercentAsString = 'n/a';
+ }
+
+ $buffer .= $this->renderItemTemplate(
+ $template,
+ [
+ 'name' => $name,
+ 'numClasses' => $numClasses,
+ 'numTestedClasses' => $numTestedClasses,
+ 'numMethods' => $numMethods,
+ 'numTestedMethods' => $numTestedMethods,
+ 'linesExecutedPercent' => Util::percent(
+ $item['executedLines'],
+ $item['executableLines'],
+ false
+ ),
+ 'linesExecutedPercentAsString' => $linesExecutedPercentAsString,
+ 'numExecutedLines' => $item['executedLines'],
+ 'numExecutableLines' => $item['executableLines'],
+ 'testedMethodsPercent' => Util::percent(
+ $numTestedMethods,
+ $numMethods,
+ false
+ ),
+ 'testedMethodsPercentAsString' => Util::percent(
+ $numTestedMethods,
+ $numMethods,
+ true
+ ),
+ 'testedClassesPercent' => Util::percent(
+ $numTestedMethods == $numMethods ? 1 : 0,
+ 1,
+ false
+ ),
+ 'testedClassesPercentAsString' => Util::percent(
+ $numTestedMethods == $numMethods ? 1 : 0,
+ 1,
+ true
+ ),
+ 'crap' => $item['crap']
+ ]
+ );
+
+ foreach ($item['methods'] as $method) {
+ $buffer .= $this->renderFunctionOrMethodItem(
+ $methodItemTemplate,
+ $method,
+ '&nbsp;'
+ );
+ }
+ }
+
+ return $buffer;
+ }
+
+ /**
+ * @param array $functions
+ * @param \Text_Template $template
+ *
+ * @return string
+ */
+ protected function renderFunctionItems(array $functions, \Text_Template $template)
+ {
+ if (empty($functions)) {
+ return '';
+ }
+
+ $buffer = '';
+
+ foreach ($functions as $function) {
+ $buffer .= $this->renderFunctionOrMethodItem(
+ $template,
+ $function
+ );
+ }
+
+ return $buffer;
+ }
+
+ /**
+ * @param \Text_Template $template
+ *
+ * @return string
+ */
+ protected function renderFunctionOrMethodItem(\Text_Template $template, array $item, $indent = '')
+ {
+ $numTestedItems = $item['executedLines'] == $item['executableLines'] ? 1 : 0;
+
+ return $this->renderItemTemplate(
+ $template,
+ [
+ 'name' => sprintf(
+ '%s<a href="#%d"><abbr title="%s">%s</abbr></a>',
+ $indent,
+ $item['startLine'],
+ htmlspecialchars($item['signature']),
+ isset($item['functionName']) ? $item['functionName'] : $item['methodName']
+ ),
+ 'numMethods' => 1,
+ 'numTestedMethods' => $numTestedItems,
+ 'linesExecutedPercent' => Util::percent(
+ $item['executedLines'],
+ $item['executableLines'],
+ false
+ ),
+ 'linesExecutedPercentAsString' => Util::percent(
+ $item['executedLines'],
+ $item['executableLines'],
+ true
+ ),
+ 'numExecutedLines' => $item['executedLines'],
+ 'numExecutableLines' => $item['executableLines'],
+ 'testedMethodsPercent' => Util::percent(
+ $numTestedItems,
+ 1,
+ false
+ ),
+ 'testedMethodsPercentAsString' => Util::percent(
+ $numTestedItems,
+ 1,
+ true
+ ),
+ 'crap' => $item['crap']
+ ]
+ );
+ }
+
+ /**
+ * @param FileNode $node
+ *
+ * @return string
+ */
+ protected function renderSource(FileNode $node)
+ {
+ $coverageData = $node->getCoverageData();
+ $testData = $node->getTestData();
+ $codeLines = $this->loadFile($node->getPath());
+ $lines = '';
+ $i = 1;
+
+ foreach ($codeLines as $line) {
+ $trClass = '';
+ $popoverContent = '';
+ $popoverTitle = '';
+
+ if (array_key_exists($i, $coverageData)) {
+ $numTests = count($coverageData[$i]);
+
+ if ($coverageData[$i] === null) {
+ $trClass = ' class="warning"';
+ } elseif ($numTests == 0) {
+ $trClass = ' class="danger"';
+ } else {
+ $lineCss = 'covered-by-large-tests';
+ $popoverContent = '<ul>';
+
+ if ($numTests > 1) {
+ $popoverTitle = $numTests . ' tests cover line ' . $i;
+ } else {
+ $popoverTitle = '1 test covers line ' . $i;
+ }
+
+ foreach ($coverageData[$i] as $test) {
+ if ($lineCss == 'covered-by-large-tests' && $testData[$test]['size'] == 'medium') {
+ $lineCss = 'covered-by-medium-tests';
+ } elseif ($testData[$test]['size'] == 'small') {
+ $lineCss = 'covered-by-small-tests';
+ }
+
+ switch ($testData[$test]['status']) {
+ case 0:
+ switch ($testData[$test]['size']) {
+ case 'small':
+ $testCSS = ' class="covered-by-small-tests"';
+ break;
+
+ case 'medium':
+ $testCSS = ' class="covered-by-medium-tests"';
+ break;
+
+ default:
+ $testCSS = ' class="covered-by-large-tests"';
+ break;
+ }
+ break;
+
+ case 1:
+ case 2:
+ $testCSS = ' class="warning"';
+ break;
+
+ case 3:
+ $testCSS = ' class="danger"';
+ break;
+
+ case 4:
+ $testCSS = ' class="danger"';
+ break;
+
+ default:
+ $testCSS = '';
+ }
+
+ $popoverContent .= sprintf(
+ '<li%s>%s</li>',
+ $testCSS,
+ htmlspecialchars($test)
+ );
+ }
+
+ $popoverContent .= '</ul>';
+ $trClass = ' class="' . $lineCss . ' popin"';
+ }
+ }
+
+ if (!empty($popoverTitle)) {
+ $popover = sprintf(
+ ' data-title="%s" data-content="%s" data-placement="bottom" data-html="true"',
+ $popoverTitle,
+ htmlspecialchars($popoverContent)
+ );
+ } else {
+ $popover = '';
+ }
+
+ $lines .= sprintf(
+ ' <tr%s%s><td><div align="right"><a name="%d"></a><a href="#%d">%d</a></div></td><td class="codeLine">%s</td></tr>' . "\n",
+ $trClass,
+ $popover,
+ $i,
+ $i,
+ $i,
+ $line
+ );
+
+ $i++;
+ }
+
+ return $lines;
+ }
+
+ /**
+ * @param string $file
+ *
+ * @return array
+ */
+ protected function loadFile($file)
+ {
+ $buffer = file_get_contents($file);
+ $tokens = token_get_all($buffer);
+ $result = [''];
+ $i = 0;
+ $stringFlag = false;
+ $fileEndsWithNewLine = substr($buffer, -1) == "\n";
+
+ unset($buffer);
+
+ foreach ($tokens as $j => $token) {
+ if (is_string($token)) {
+ if ($token === '"' && $tokens[$j - 1] !== '\\') {
+ $result[$i] .= sprintf(
+ '<span class="string">%s</span>',
+ htmlspecialchars($token)
+ );
+
+ $stringFlag = !$stringFlag;
+ } else {
+ $result[$i] .= sprintf(
+ '<span class="keyword">%s</span>',
+ htmlspecialchars($token)
+ );
+ }
+
+ continue;
+ }
+
+ list($token, $value) = $token;
+
+ $value = str_replace(
+ ["\t", ' '],
+ ['&nbsp;&nbsp;&nbsp;&nbsp;', '&nbsp;'],
+ htmlspecialchars($value, $this->htmlspecialcharsFlags)
+ );
+
+ if ($value === "\n") {
+ $result[++$i] = '';
+ } else {
+ $lines = explode("\n", $value);
+
+ foreach ($lines as $jj => $line) {
+ $line = trim($line);
+
+ if ($line !== '') {
+ if ($stringFlag) {
+ $colour = 'string';
+ } else {
+ switch ($token) {
+ case T_INLINE_HTML:
+ $colour = 'html';
+ break;
+
+ case T_COMMENT:
+ case T_DOC_COMMENT:
+ $colour = 'comment';
+ break;
+
+ case T_ABSTRACT:
+ case T_ARRAY:
+ case T_AS:
+ case T_BREAK:
+ case T_CALLABLE:
+ case T_CASE:
+ case T_CATCH:
+ case T_CLASS:
+ case T_CLONE:
+ case T_CONTINUE:
+ case T_DEFAULT:
+ case T_ECHO:
+ case T_ELSE:
+ case T_ELSEIF:
+ case T_EMPTY:
+ case T_ENDDECLARE:
+ case T_ENDFOR:
+ case T_ENDFOREACH:
+ case T_ENDIF:
+ case T_ENDSWITCH:
+ case T_ENDWHILE:
+ case T_EXIT:
+ case T_EXTENDS:
+ case T_FINAL:
+ case T_FINALLY:
+ case T_FOREACH:
+ case T_FUNCTION:
+ case T_GLOBAL:
+ case T_IF:
+ case T_IMPLEMENTS:
+ case T_INCLUDE:
+ case T_INCLUDE_ONCE:
+ case T_INSTANCEOF:
+ case T_INSTEADOF:
+ case T_INTERFACE:
+ case T_ISSET:
+ case T_LOGICAL_AND:
+ case T_LOGICAL_OR:
+ case T_LOGICAL_XOR:
+ case T_NAMESPACE:
+ case T_NEW:
+ case T_PRIVATE:
+ case T_PROTECTED:
+ case T_PUBLIC:
+ case T_REQUIRE:
+ case T_REQUIRE_ONCE:
+ case T_RETURN:
+ case T_STATIC:
+ case T_THROW:
+ case T_TRAIT:
+ case T_TRY:
+ case T_UNSET:
+ case T_USE:
+ case T_VAR:
+ case T_WHILE:
+ case T_YIELD:
+ $colour = 'keyword';
+ break;
+
+ default:
+ $colour = 'default';
+ }
+ }
+
+ $result[$i] .= sprintf(
+ '<span class="%s">%s</span>',
+ $colour,
+ $line
+ );
+ }
+
+ if (isset($lines[$jj + 1])) {
+ $result[++$i] = '';
+ }
+ }
+ }
+ }
+
+ if ($fileEndsWithNewLine) {
+ unset($result[count($result)-1]);
+ }
+
+ return $result;
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/coverage_bar.html.dist b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/coverage_bar.html.dist
new file mode 100644
index 0000000..5a09c35
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/coverage_bar.html.dist
@@ -0,0 +1,5 @@
+ <div class="progress">
+ <div class="progress-bar progress-bar-{{level}}" role="progressbar" aria-valuenow="{{percent}}" aria-valuemin="0" aria-valuemax="100" style="width: {{percent}}%">
+ <span class="sr-only">{{percent}}% covered ({{level}})</span>
+ </div>
+ </div>
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/bootstrap.min.css b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/bootstrap.min.css
new file mode 100644
index 0000000..ed3905e
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/bootstrap.min.css
@@ -0,0 +1,6 @@
+/*!
+ * Bootstrap v3.3.7 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}
+/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/nv.d3.min.css b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/nv.d3.min.css
new file mode 100644
index 0000000..7a6f7fe
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/nv.d3.min.css
@@ -0,0 +1 @@
+.nvd3 .nv-axis{pointer-events:none;opacity:1}.nvd3 .nv-axis path{fill:none;stroke:#000;stroke-opacity:.75;shape-rendering:crispEdges}.nvd3 .nv-axis path.domain{stroke-opacity:.75}.nvd3 .nv-axis.nv-x path.domain{stroke-opacity:0}.nvd3 .nv-axis line{fill:none;stroke:#e5e5e5;shape-rendering:crispEdges}.nvd3 .nv-axis .zero line,.nvd3 .nv-axis line.zero{stroke-opacity:.75}.nvd3 .nv-axis .nv-axisMaxMin text{font-weight:700}.nvd3 .x .nv-axis .nv-axisMaxMin text,.nvd3 .x2 .nv-axis .nv-axisMaxMin text,.nvd3 .x3 .nv-axis .nv-axisMaxMin text{text-anchor:middle}.nvd3 .nv-axis.nv-disabled{opacity:0}.nvd3 .nv-bars rect{fill-opacity:.75;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-bars rect.hover{fill-opacity:1}.nvd3 .nv-bars .hover rect{fill:#add8e6}.nvd3 .nv-bars text{fill:rgba(0,0,0,0)}.nvd3 .nv-bars .hover text{fill:rgba(0,0,0,1)}.nvd3 .nv-multibar .nv-groups rect,.nvd3 .nv-multibarHorizontal .nv-groups rect,.nvd3 .nv-discretebar .nv-groups rect{stroke-opacity:0;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-multibar .nv-groups rect:hover,.nvd3 .nv-multibarHorizontal .nv-groups rect:hover,.nvd3 .nv-candlestickBar .nv-ticks rect:hover,.nvd3 .nv-discretebar .nv-groups rect:hover{fill-opacity:1}.nvd3 .nv-discretebar .nv-groups text,.nvd3 .nv-multibarHorizontal .nv-groups text{font-weight:700;fill:rgba(0,0,0,1);stroke:rgba(0,0,0,0)}.nvd3 .nv-boxplot circle{fill-opacity:.5}.nvd3 .nv-boxplot circle:hover{fill-opacity:1}.nvd3 .nv-boxplot rect:hover{fill-opacity:1}.nvd3 line.nv-boxplot-median{stroke:#000}.nv-boxplot-tick:hover{stroke-width:2.5px}.nvd3.nv-bullet{font:10px sans-serif}.nvd3.nv-bullet .nv-measure{fill-opacity:.8}.nvd3.nv-bullet .nv-measure:hover{fill-opacity:1}.nvd3.nv-bullet .nv-marker{stroke:#000;stroke-width:2px}.nvd3.nv-bullet .nv-markerTriangle{stroke:#000;fill:#fff;stroke-width:1.5px}.nvd3.nv-bullet .nv-tick line{stroke:#666;stroke-width:.5px}.nvd3.nv-bullet .nv-range.nv-s0{fill:#eee}.nvd3.nv-bullet .nv-range.nv-s1{fill:#ddd}.nvd3.nv-bullet .nv-range.nv-s2{fill:#ccc}.nvd3.nv-bullet .nv-title{font-size:14px;font-weight:700}.nvd3.nv-bullet .nv-subtitle{fill:#999}.nvd3.nv-bullet .nv-range{fill:#bababa;fill-opacity:.4}.nvd3.nv-bullet .nv-range:hover{fill-opacity:.7}.nvd3.nv-candlestickBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect{stroke:#d62728;fill:#d62728}.with-transitions .nv-candlestickBar .nv-ticks .nv-tick{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-candlestickBar .nv-ticks line{stroke:#333}.nvd3 .nv-legend .nv-disabled rect{}.nvd3 .nv-check-box .nv-box{fill-opacity:0;stroke-width:2}.nvd3 .nv-check-box .nv-check{fill-opacity:0;stroke-width:4}.nvd3 .nv-series.nv-disabled .nv-check-box .nv-check{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-controlsWrap .nv-legend .nv-check-box .nv-check{opacity:0}.nvd3.nv-linePlusBar .nv-bar rect{fill-opacity:.75}.nvd3.nv-linePlusBar .nv-bar rect:hover{fill-opacity:1}.nvd3 .nv-groups path.nv-line{fill:none}.nvd3 .nv-groups path.nv-area{stroke:none}.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point{fill-opacity:0;stroke-opacity:0}.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point{fill-opacity:.5!important;stroke-opacity:.5!important}.with-transitions .nvd3 .nv-groups .nv-point{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-scatter .nv-groups .nv-point.hover,.nvd3 .nv-groups .nv-point.hover{stroke-width:7px;fill-opacity:.95!important;stroke-opacity:.95!important}.nvd3 .nv-point-paths path{stroke:#aaa;stroke-opacity:0;fill:#eee;fill-opacity:0}.nvd3 .nv-indexLine{cursor:ew-resize}svg.nvd3-svg{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-ms-user-select:none;-moz-user-select:none;user-select:none;display:block;width:100%;height:100%}.nvtooltip.with-3d-shadow,.with-3d-shadow .nvtooltip{-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nvd3 text{font:400 12px Arial}.nvd3 .title{font:700 14px Arial}.nvd3 .nv-background{fill:#fff;fill-opacity:0}.nvd3.nv-noData{font-size:18px;font-weight:700}.nv-brush .extent{fill-opacity:.125;shape-rendering:crispEdges}.nv-brush .resize path{fill:#eee;stroke:#666}.nvd3 .nv-legend .nv-series{cursor:pointer}.nvd3 .nv-legend .nv-disabled circle{fill-opacity:0}.nvd3 .nv-brush .extent{fill-opacity:0!important}.nvd3 .nv-brushBackground rect{stroke:#000;stroke-width:.4;fill:#fff;fill-opacity:.7}.nvd3.nv-ohlcBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive{stroke:#2ca02c}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative{stroke:#d62728}.nvd3 .background path{fill:none;stroke:#EEE;stroke-opacity:.4;shape-rendering:crispEdges}.nvd3 .foreground path{fill:none;stroke-opacity:.7}.nvd3 .nv-parallelCoordinates-brush .extent{fill:#fff;fill-opacity:.6;stroke:gray;shape-rendering:crispEdges}.nvd3 .nv-parallelCoordinates .hover{fill-opacity:1;stroke-width:3px}.nvd3 .missingValuesline line{fill:none;stroke:#000;stroke-width:1;stroke-opacity:1;stroke-dasharray:5,5}.nvd3.nv-pie path{stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-pie .nv-pie-title{font-size:24px;fill:rgba(19,196,249,.59)}.nvd3.nv-pie .nv-slice text{stroke:#000;stroke-width:0}.nvd3.nv-pie path{stroke:#fff;stroke-width:1px;stroke-opacity:1}.nvd3.nv-pie .hover path{fill-opacity:.7}.nvd3.nv-pie .nv-label{pointer-events:none}.nvd3.nv-pie .nv-label rect{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-groups .nv-point.hover{stroke-width:20px;stroke-opacity:.5}.nvd3 .nv-scatter .nv-point.hover{fill-opacity:1}.nv-noninteractive{pointer-events:none}.nv-distx,.nv-disty{pointer-events:none}.nvd3.nv-sparkline path{fill:none}.nvd3.nv-sparklineplus g.nv-hoverValue{pointer-events:none}.nvd3.nv-sparklineplus .nv-hoverValue line{stroke:#333;stroke-width:1.5px}.nvd3.nv-sparklineplus,.nvd3.nv-sparklineplus g{pointer-events:all}.nvd3 .nv-hoverArea{fill-opacity:0;stroke-opacity:0}.nvd3.nv-sparklineplus .nv-xValue,.nvd3.nv-sparklineplus .nv-yValue{stroke-width:0;font-size:.9em;font-weight:400}.nvd3.nv-sparklineplus .nv-yValue{stroke:#f66}.nvd3.nv-sparklineplus .nv-maxValue{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-sparklineplus .nv-minValue{stroke:#d62728;fill:#d62728}.nvd3.nv-sparklineplus .nv-currentValue{font-weight:700;font-size:1.1em}.nvd3.nv-stackedarea path.nv-area{fill-opacity:.7;stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-stackedarea path.nv-area.hover{fill-opacity:.9}.nvd3.nv-stackedarea .nv-groups .nv-point{stroke-opacity:0;fill-opacity:0}.nvtooltip{position:absolute;background-color:rgba(255,255,255,1);color:rgba(0,0,0,1);padding:1px;border:1px solid rgba(0,0,0,.2);z-index:10000;display:block;font-family:Arial;font-size:13px;text-align:left;pointer-events:none;white-space:nowrap;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.nvtooltip{background:rgba(255,255,255,.8);border:1px solid rgba(0,0,0,.5);border-radius:4px}.nvtooltip.with-transitions,.with-transitions .nvtooltip{transition:opacity 50ms linear;-moz-transition:opacity 50ms linear;-webkit-transition:opacity 50ms linear;transition-delay:200ms;-moz-transition-delay:200ms;-webkit-transition-delay:200ms}.nvtooltip.x-nvtooltip,.nvtooltip.y-nvtooltip{padding:8px}.nvtooltip h3{margin:0;padding:4px 14px;line-height:18px;font-weight:400;background-color:rgba(247,247,247,.75);color:rgba(0,0,0,1);text-align:center;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.nvtooltip p{margin:0;padding:5px 14px;text-align:center}.nvtooltip span{display:inline-block;margin:2px 0}.nvtooltip table{margin:6px;border-spacing:0}.nvtooltip table td{padding:2px 9px 2px 0;vertical-align:middle}.nvtooltip table td.key{font-weight:400}.nvtooltip table td.value{text-align:right;font-weight:700}.nvtooltip table tr.highlight td{padding:1px 9px 1px 0;border-bottom-style:solid;border-bottom-width:1px;border-top-style:solid;border-top-width:1px}.nvtooltip table td.legend-color-guide div{width:8px;height:8px;vertical-align:middle}.nvtooltip table td.legend-color-guide div{width:12px;height:12px;border:1px solid #999}.nvtooltip .footer{padding:3px;text-align:center}.nvtooltip-pending-removal{pointer-events:none;display:none}.nvd3 .nv-interactiveGuideLine{pointer-events:none}.nvd3 line.nv-guideline{stroke:#ccc} \ No newline at end of file
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/style.css b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/style.css
new file mode 100644
index 0000000..824fb31
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/style.css
@@ -0,0 +1,122 @@
+body {
+ padding-top: 10px;
+}
+
+.popover {
+ max-width: none;
+}
+
+.glyphicon {
+ margin-right:.25em;
+}
+
+.table-bordered>thead>tr>td {
+ border-bottom-width: 1px;
+}
+
+.table tbody>tr>td, .table thead>tr>td {
+ padding-top: 3px;
+ padding-bottom: 3px;
+}
+
+.table-condensed tbody>tr>td {
+ padding-top: 0;
+ padding-bottom: 0;
+}
+
+.table .progress {
+ margin-bottom: inherit;
+}
+
+.table-borderless th, .table-borderless td {
+ border: 0 !important;
+}
+
+.table tbody tr.covered-by-large-tests, li.covered-by-large-tests, tr.success, td.success, li.success, span.success {
+ background-color: #dff0d8;
+}
+
+.table tbody tr.covered-by-medium-tests, li.covered-by-medium-tests {
+ background-color: #c3e3b5;
+}
+
+.table tbody tr.covered-by-small-tests, li.covered-by-small-tests {
+ background-color: #99cb84;
+}
+
+.table tbody tr.danger, .table tbody td.danger, li.danger, span.danger {
+ background-color: #f2dede;
+}
+
+.table tbody td.warning, li.warning, span.warning {
+ background-color: #fcf8e3;
+}
+
+.table tbody td.info {
+ background-color: #d9edf7;
+}
+
+td.big {
+ width: 117px;
+}
+
+td.small {
+}
+
+td.codeLine {
+ font-family: monospace;
+ white-space: pre;
+}
+
+td span.comment {
+ color: #888a85;
+}
+
+td span.default {
+ color: #2e3436;
+}
+
+td span.html {
+ color: #888a85;
+}
+
+td span.keyword {
+ color: #2e3436;
+ font-weight: bold;
+}
+
+pre span.string {
+ color: #2e3436;
+}
+
+span.success, span.warning, span.danger {
+ margin-right: 2px;
+ padding-left: 10px;
+ padding-right: 10px;
+ text-align: center;
+}
+
+#classCoverageDistribution, #classComplexity {
+ height: 200px;
+ width: 475px;
+}
+
+#toplink {
+ position: fixed;
+ left: 5px;
+ bottom: 5px;
+ outline: 0;
+}
+
+svg text {
+ font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif;
+ font-size: 11px;
+ color: #666;
+ fill: #666;
+}
+
+.scrollbox {
+ height:245px;
+ overflow-x:hidden;
+ overflow-y:scroll;
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/dashboard.html.dist b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/dashboard.html.dist
new file mode 100644
index 0000000..8bdf04d
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/dashboard.html.dist
@@ -0,0 +1,284 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <title>Dashboard for {{full_path}}</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link href="{{path_to_root}}css/bootstrap.min.css" rel="stylesheet">
+ <link href="{{path_to_root}}css/nv.d3.min.css" rel="stylesheet">
+ <link href="{{path_to_root}}css/style.css" rel="stylesheet">
+ <!--[if lt IE 9]>
+ <script src="{{path_to_root}}js/html5shiv.min.js"></script>
+ <script src="{{path_to_root}}js/respond.min.js"></script>
+ <![endif]-->
+ </head>
+ <body>
+ <header>
+ <div class="container">
+ <div class="row">
+ <div class="col-md-12">
+ <ol class="breadcrumb">
+{{breadcrumbs}}
+ </ol>
+ </div>
+ </div>
+ </div>
+ </header>
+ <div class="container">
+ <div class="row">
+ <div class="col-md-12">
+ <h2>Classes</h2>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <h3>Coverage Distribution</h3>
+ <div id="classCoverageDistribution" style="height: 300px;">
+ <svg></svg>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <h3>Complexity</h3>
+ <div id="classComplexity" style="height: 300px;">
+ <svg></svg>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <h3>Insufficient Coverage</h3>
+ <div class="scrollbox">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Class</th>
+ <th class="text-right">Coverage</th>
+ </tr>
+ </thead>
+ <tbody>
+{{insufficient_coverage_classes}}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <h3>Project Risks</h3>
+ <div class="scrollbox">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Class</th>
+ <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
+ </tr>
+ </thead>
+ <tbody>
+{{project_risks_classes}}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-12">
+ <h2>Methods</h2>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <h3>Coverage Distribution</h3>
+ <div id="methodCoverageDistribution" style="height: 300px;">
+ <svg></svg>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <h3>Complexity</h3>
+ <div id="methodComplexity" style="height: 300px;">
+ <svg></svg>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <h3>Insufficient Coverage</h3>
+ <div class="scrollbox">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Method</th>
+ <th class="text-right">Coverage</th>
+ </tr>
+ </thead>
+ <tbody>
+{{insufficient_coverage_methods}}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <h3>Project Risks</h3>
+ <div class="scrollbox">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Method</th>
+ <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
+ </tr>
+ </thead>
+ <tbody>
+{{project_risks_methods}}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ <footer>
+ <hr/>
+ <p>
+ <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
+ </p>
+ </footer>
+ </div>
+ <script src="{{path_to_root}}js/jquery.min.js" type="text/javascript"></script>
+ <script src="{{path_to_root}}js/bootstrap.min.js" type="text/javascript"></script>
+ <script src="{{path_to_root}}js/holder.min.js" type="text/javascript"></script>
+ <script src="{{path_to_root}}js/d3.min.js" type="text/javascript"></script>
+ <script src="{{path_to_root}}js/nv.d3.min.js" type="text/javascript"></script>
+ <script type="text/javascript">
+$(document).ready(function() {
+ nv.addGraph(function() {
+ var chart = nv.models.multiBarChart();
+ chart.tooltips(false)
+ .showControls(false)
+ .showLegend(false)
+ .reduceXTicks(false)
+ .staggerLabels(true)
+ .yAxis.tickFormat(d3.format('d'));
+
+ d3.select('#classCoverageDistribution svg')
+ .datum(getCoverageDistributionData({{class_coverage_distribution}}, "Class Coverage"))
+ .transition().duration(500).call(chart);
+
+ nv.utils.windowResize(chart.update);
+
+ return chart;
+ });
+
+ nv.addGraph(function() {
+ var chart = nv.models.multiBarChart();
+ chart.tooltips(false)
+ .showControls(false)
+ .showLegend(false)
+ .reduceXTicks(false)
+ .staggerLabels(true)
+ .yAxis.tickFormat(d3.format('d'));
+
+ d3.select('#methodCoverageDistribution svg')
+ .datum(getCoverageDistributionData({{method_coverage_distribution}}, "Method Coverage"))
+ .transition().duration(500).call(chart);
+
+ nv.utils.windowResize(chart.update);
+
+ return chart;
+ });
+
+ function getCoverageDistributionData(data, label) {
+ var labels = [
+ '0%',
+ '0-10%',
+ '10-20%',
+ '20-30%',
+ '30-40%',
+ '40-50%',
+ '50-60%',
+ '60-70%',
+ '70-80%',
+ '80-90%',
+ '90-100%',
+ '100%'
+ ];
+ var values = [];
+ $.each(labels, function(key) {
+ values.push({x: labels[key], y: data[key]});
+ });
+
+ return [
+ {
+ key: label,
+ values: values,
+ color: "#4572A7"
+ }
+ ];
+ }
+ nv.addGraph(function() {
+ var chart = nv.models.scatterChart()
+ .showDistX(true)
+ .showDistY(true)
+ .showLegend(false)
+ .forceX([0, 100]);
+ chart.tooltipContent(function(graph) {
+ return '<p>' + graph.point.class + '</p>';
+ });
+
+ chart.xAxis.axisLabel('Code Coverage (in percent)');
+ chart.yAxis.axisLabel('Cyclomatic Complexity');
+
+ d3.select('#classComplexity svg')
+ .datum(getComplexityData({{complexity_class}}, 'Class Complexity'))
+ .transition()
+ .duration(500)
+ .call(chart);
+
+ nv.utils.windowResize(chart.update);
+
+ return chart;
+ });
+
+ nv.addGraph(function() {
+ var chart = nv.models.scatterChart()
+ .showDistX(true)
+ .showDistY(true)
+ .showLegend(false)
+ .forceX([0, 100]);
+ chart.tooltipContent(function(graph) {
+ return '<p>' + graph.point.class + '</p>';
+ });
+
+ chart.xAxis.axisLabel('Code Coverage (in percent)');
+ chart.yAxis.axisLabel('Method Complexity');
+
+ d3.select('#methodComplexity svg')
+ .datum(getComplexityData({{complexity_method}}, 'Method Complexity'))
+ .transition()
+ .duration(500)
+ .call(chart);
+
+ nv.utils.windowResize(chart.update);
+
+ return chart;
+ });
+
+ function getComplexityData(data, label) {
+ var values = [];
+ $.each(data, function(key) {
+ var value = Math.round(data[key][0]*100) / 100;
+ values.push({
+ x: value,
+ y: data[key][1],
+ class: data[key][2],
+ size: 0.05,
+ shape: 'diamond'
+ });
+ });
+
+ return [
+ {
+ key: label,
+ values: values,
+ color: "#4572A7"
+ }
+ ];
+ }
+});
+ </script>
+ </body>
+</html>
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory.html.dist b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory.html.dist
new file mode 100644
index 0000000..29fbf23
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory.html.dist
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <title>Code Coverage for {{full_path}}</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link href="{{path_to_root}}css/bootstrap.min.css" rel="stylesheet">
+ <link href="{{path_to_root}}css/style.css" rel="stylesheet">
+ <!--[if lt IE 9]>
+ <script src="{{path_to_root}}js/html5shiv.min.js"></script>
+ <script src="{{path_to_root}}js/respond.min.js"></script>
+ <![endif]-->
+ </head>
+ <body>
+ <header>
+ <div class="container">
+ <div class="row">
+ <div class="col-md-12">
+ <ol class="breadcrumb">
+{{breadcrumbs}}
+ </ol>
+ </div>
+ </div>
+ </div>
+ </header>
+ <div class="container">
+ <table class="table table-bordered">
+ <thead>
+ <tr>
+ <td>&nbsp;</td>
+ <td colspan="9"><div align="center"><strong>Code Coverage</strong></div></td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
+ <td colspan="3"><div align="center"><strong>Functions and Methods</strong></div></td>
+ <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
+ </tr>
+ </thead>
+ <tbody>
+{{items}}
+ </tbody>
+ </table>
+ <footer>
+ <hr/>
+ <h4>Legend</h4>
+ <p>
+ <span class="danger"><strong>Low</strong>: 0% to {{low_upper_bound}}%</span>
+ <span class="warning"><strong>Medium</strong>: {{low_upper_bound}}% to {{high_lower_bound}}%</span>
+ <span class="success"><strong>High</strong>: {{high_lower_bound}}% to 100%</span>
+ </p>
+ <p>
+ <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
+ </p>
+ </footer>
+ </div>
+ <script src="{{path_to_root}}js/jquery.min.js" type="text/javascript"></script>
+ <script src="{{path_to_root}}js/bootstrap.min.js" type="text/javascript"></script>
+ <script src="{{path_to_root}}js/holder.min.js" type="text/javascript"></script>
+ </body>
+</html>
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory_item.html.dist b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory_item.html.dist
new file mode 100644
index 0000000..78dbb35
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory_item.html.dist
@@ -0,0 +1,13 @@
+ <tr>
+ <td class="{{lines_level}}">{{icon}}{{name}}</td>
+ <td class="{{lines_level}} big">{{lines_bar}}</td>
+ <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
+ <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
+ <td class="{{methods_level}} big">{{methods_bar}}</td>
+ <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
+ <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
+ <td class="{{classes_level}} big">{{classes_bar}}</td>
+ <td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
+ <td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
+ </tr>
+
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file.html.dist b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file.html.dist
new file mode 100644
index 0000000..8c42d4e
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file.html.dist
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <title>Code Coverage for {{full_path}}</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link href="{{path_to_root}}css/bootstrap.min.css" rel="stylesheet">
+ <link href="{{path_to_root}}css/style.css" rel="stylesheet">
+ <!--[if lt IE 9]>
+ <script src="{{path_to_root}}js/html5shiv.min.js"></script>
+ <script src="{{path_to_root}}js/respond.min.js"></script>
+ <![endif]-->
+ </head>
+ <body>
+ <header>
+ <div class="container">
+ <div class="row">
+ <div class="col-md-12">
+ <ol class="breadcrumb">
+{{breadcrumbs}}
+ </ol>
+ </div>
+ </div>
+ </div>
+ </header>
+ <div class="container">
+ <table class="table table-bordered">
+ <thead>
+ <tr>
+ <td>&nbsp;</td>
+ <td colspan="10"><div align="center"><strong>Code Coverage</strong></div></td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
+ <td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
+ <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
+ </tr>
+ </thead>
+ <tbody>
+{{items}}
+ </tbody>
+ </table>
+ <table id="code" class="table table-borderless table-condensed">
+ <tbody>
+{{lines}}
+ </tbody>
+ </table>
+ <footer>
+ <hr/>
+ <h4>Legend</h4>
+ <p>
+ <span class="success"><strong>Executed</strong></span>
+ <span class="danger"><strong>Not Executed</strong></span>
+ <span class="warning"><strong>Dead Code</strong></span>
+ </p>
+ <p>
+ <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage {{version}}</a> using {{runtime}}{{generator}} at {{date}}.</small>
+ </p>
+ <a title="Back to the top" id="toplink" href="#"><span class="glyphicon glyphicon-arrow-up"></span></a>
+ </footer>
+ </div>
+ <script src="{{path_to_root}}js/jquery.min.js" type="text/javascript"></script>
+ <script src="{{path_to_root}}js/bootstrap.min.js" type="text/javascript"></script>
+ <script src="{{path_to_root}}js/holder.min.js" type="text/javascript"></script>
+ <script type="text/javascript">
+ $(function() {
+ var $window = $(window)
+ , $top_link = $('#toplink')
+ , $body = $('body, html')
+ , offset = $('#code').offset().top;
+
+ $top_link.hide().click(function(event) {
+ event.preventDefault();
+ $body.animate({scrollTop:0}, 800);
+ });
+
+ $window.scroll(function() {
+ if($window.scrollTop() > offset) {
+ $top_link.fadeIn();
+ } else {
+ $top_link.fadeOut();
+ }
+ }).scroll();
+
+ $('.popin').popover({trigger: 'hover'});
+ });
+ </script>
+ </body>
+</html>
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file_item.html.dist b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file_item.html.dist
new file mode 100644
index 0000000..756fdd6
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file_item.html.dist
@@ -0,0 +1,14 @@
+ <tr>
+ <td class="{{classes_level}}">{{name}}</td>
+ <td class="{{classes_level}} big">{{classes_bar}}</td>
+ <td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
+ <td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
+ <td class="{{methods_level}} big">{{methods_bar}}</td>
+ <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
+ <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
+ <td class="{{methods_level}} small">{{crap}}</td>
+ <td class="{{lines_level}} big">{{lines_bar}}</td>
+ <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
+ <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
+ </tr>
+
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.eot b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.eot
new file mode 100644
index 0000000..b93a495
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.eot
Binary files differ
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.svg b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.svg
new file mode 100644
index 0000000..94fb549
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.svg
@@ -0,0 +1,288 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
+<font-face units-per-em="1200" ascent="960" descent="-240" />
+<missing-glyph horiz-adv-x="500" />
+<glyph horiz-adv-x="0" />
+<glyph horiz-adv-x="400" />
+<glyph unicode=" " />
+<glyph unicode="*" d="M600 1100q15 0 34 -1.5t30 -3.5l11 -1q10 -2 17.5 -10.5t7.5 -18.5v-224l158 158q7 7 18 8t19 -6l106 -106q7 -8 6 -19t-8 -18l-158 -158h224q10 0 18.5 -7.5t10.5 -17.5q6 -41 6 -75q0 -15 -1.5 -34t-3.5 -30l-1 -11q-2 -10 -10.5 -17.5t-18.5 -7.5h-224l158 -158 q7 -7 8 -18t-6 -19l-106 -106q-8 -7 -19 -6t-18 8l-158 158v-224q0 -10 -7.5 -18.5t-17.5 -10.5q-41 -6 -75 -6q-15 0 -34 1.5t-30 3.5l-11 1q-10 2 -17.5 10.5t-7.5 18.5v224l-158 -158q-7 -7 -18 -8t-19 6l-106 106q-7 8 -6 19t8 18l158 158h-224q-10 0 -18.5 7.5 t-10.5 17.5q-6 41 -6 75q0 15 1.5 34t3.5 30l1 11q2 10 10.5 17.5t18.5 7.5h224l-158 158q-7 7 -8 18t6 19l106 106q8 7 19 6t18 -8l158 -158v224q0 10 7.5 18.5t17.5 10.5q41 6 75 6z" />
+<glyph unicode="+" d="M450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-350h350q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-350v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v350h-350q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5 h350v350q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xa0;" />
+<glyph unicode="&#xa5;" d="M825 1100h250q10 0 12.5 -5t-5.5 -13l-364 -364q-6 -6 -11 -18h268q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-100h275q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-174q0 -11 -7.5 -18.5t-18.5 -7.5h-148q-11 0 -18.5 7.5t-7.5 18.5v174 h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h125v100h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h118q-5 12 -11 18l-364 364q-8 8 -5.5 13t12.5 5h250q25 0 43 -18l164 -164q8 -8 18 -8t18 8l164 164q18 18 43 18z" />
+<glyph unicode="&#x2000;" horiz-adv-x="650" />
+<glyph unicode="&#x2001;" horiz-adv-x="1300" />
+<glyph unicode="&#x2002;" horiz-adv-x="650" />
+<glyph unicode="&#x2003;" horiz-adv-x="1300" />
+<glyph unicode="&#x2004;" horiz-adv-x="433" />
+<glyph unicode="&#x2005;" horiz-adv-x="325" />
+<glyph unicode="&#x2006;" horiz-adv-x="216" />
+<glyph unicode="&#x2007;" horiz-adv-x="216" />
+<glyph unicode="&#x2008;" horiz-adv-x="162" />
+<glyph unicode="&#x2009;" horiz-adv-x="260" />
+<glyph unicode="&#x200a;" horiz-adv-x="72" />
+<glyph unicode="&#x202f;" horiz-adv-x="260" />
+<glyph unicode="&#x205f;" horiz-adv-x="325" />
+<glyph unicode="&#x20ac;" d="M744 1198q242 0 354 -189q60 -104 66 -209h-181q0 45 -17.5 82.5t-43.5 61.5t-58 40.5t-60.5 24t-51.5 7.5q-19 0 -40.5 -5.5t-49.5 -20.5t-53 -38t-49 -62.5t-39 -89.5h379l-100 -100h-300q-6 -50 -6 -100h406l-100 -100h-300q9 -74 33 -132t52.5 -91t61.5 -54.5t59 -29 t47 -7.5q22 0 50.5 7.5t60.5 24.5t58 41t43.5 61t17.5 80h174q-30 -171 -128 -278q-107 -117 -274 -117q-206 0 -324 158q-36 48 -69 133t-45 204h-217l100 100h112q1 47 6 100h-218l100 100h134q20 87 51 153.5t62 103.5q117 141 297 141z" />
+<glyph unicode="&#x20bd;" d="M428 1200h350q67 0 120 -13t86 -31t57 -49.5t35 -56.5t17 -64.5t6.5 -60.5t0.5 -57v-16.5v-16.5q0 -36 -0.5 -57t-6.5 -61t-17 -65t-35 -57t-57 -50.5t-86 -31.5t-120 -13h-178l-2 -100h288q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-138v-175q0 -11 -5.5 -18 t-15.5 -7h-149q-10 0 -17.5 7.5t-7.5 17.5v175h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v100h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v475q0 10 7.5 17.5t17.5 7.5zM600 1000v-300h203q64 0 86.5 33t22.5 119q0 84 -22.5 116t-86.5 32h-203z" />
+<glyph unicode="&#x2212;" d="M250 700h800q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#x231b;" d="M1000 1200v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-50v-100q0 -91 -49.5 -165.5t-130.5 -109.5q81 -35 130.5 -109.5t49.5 -165.5v-150h50q21 0 35.5 -14.5t14.5 -35.5v-150h-800v150q0 21 14.5 35.5t35.5 14.5h50v150q0 91 49.5 165.5t130.5 109.5q-81 35 -130.5 109.5 t-49.5 165.5v100h-50q-21 0 -35.5 14.5t-14.5 35.5v150h800zM400 1000v-100q0 -60 32.5 -109.5t87.5 -73.5q28 -12 44 -37t16 -55t-16 -55t-44 -37q-55 -24 -87.5 -73.5t-32.5 -109.5v-150h400v150q0 60 -32.5 109.5t-87.5 73.5q-28 12 -44 37t-16 55t16 55t44 37 q55 24 87.5 73.5t32.5 109.5v100h-400z" />
+<glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" />
+<glyph unicode="&#x2601;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -206.5q0 -121 -85 -207.5t-205 -86.5h-750q-79 0 -135.5 57t-56.5 137q0 69 42.5 122.5t108.5 67.5q-2 12 -2 37q0 153 108 260.5t260 107.5z" />
+<glyph unicode="&#x26fa;" d="M774 1193.5q16 -9.5 20.5 -27t-5.5 -33.5l-136 -187l467 -746h30q20 0 35 -18.5t15 -39.5v-42h-1200v42q0 21 15 39.5t35 18.5h30l468 746l-135 183q-10 16 -5.5 34t20.5 28t34 5.5t28 -20.5l111 -148l112 150q9 16 27 20.5t34 -5zM600 200h377l-182 112l-195 534v-646z " />
+<glyph unicode="&#x2709;" d="M25 1100h1150q10 0 12.5 -5t-5.5 -13l-564 -567q-8 -8 -18 -8t-18 8l-564 567q-8 8 -5.5 13t12.5 5zM18 882l264 -264q8 -8 8 -18t-8 -18l-264 -264q-8 -8 -13 -5.5t-5 12.5v550q0 10 5 12.5t13 -5.5zM918 618l264 264q8 8 13 5.5t5 -12.5v-550q0 -10 -5 -12.5t-13 5.5 l-264 264q-8 8 -8 18t8 18zM818 482l364 -364q8 -8 5.5 -13t-12.5 -5h-1150q-10 0 -12.5 5t5.5 13l364 364q8 8 18 8t18 -8l164 -164q8 -8 18 -8t18 8l164 164q8 8 18 8t18 -8z" />
+<glyph unicode="&#x270f;" d="M1011 1210q19 0 33 -13l153 -153q13 -14 13 -33t-13 -33l-99 -92l-214 214l95 96q13 14 32 14zM1013 800l-615 -614l-214 214l614 614zM317 96l-333 -112l110 335z" />
+<glyph unicode="&#xe001;" d="M700 650v-550h250q21 0 35.5 -14.5t14.5 -35.5v-50h-800v50q0 21 14.5 35.5t35.5 14.5h250v550l-500 550h1200z" />
+<glyph unicode="&#xe002;" d="M368 1017l645 163q39 15 63 0t24 -49v-831q0 -55 -41.5 -95.5t-111.5 -63.5q-79 -25 -147 -4.5t-86 75t25.5 111.5t122.5 82q72 24 138 8v521l-600 -155v-606q0 -42 -44 -90t-109 -69q-79 -26 -147 -5.5t-86 75.5t25.5 111.5t122.5 82.5q72 24 138 7v639q0 38 14.5 59 t53.5 34z" />
+<glyph unicode="&#xe003;" d="M500 1191q100 0 191 -39t156.5 -104.5t104.5 -156.5t39 -191l-1 -2l1 -5q0 -141 -78 -262l275 -274q23 -26 22.5 -44.5t-22.5 -42.5l-59 -58q-26 -20 -46.5 -20t-39.5 20l-275 274q-119 -77 -261 -77l-5 1l-2 -1q-100 0 -191 39t-156.5 104.5t-104.5 156.5t-39 191 t39 191t104.5 156.5t156.5 104.5t191 39zM500 1022q-88 0 -162 -43t-117 -117t-43 -162t43 -162t117 -117t162 -43t162 43t117 117t43 162t-43 162t-117 117t-162 43z" />
+<glyph unicode="&#xe005;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104z" />
+<glyph unicode="&#xe006;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429z" />
+<glyph unicode="&#xe007;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429zM477 700h-240l197 -142l-74 -226 l193 139l195 -140l-74 229l192 140h-234l-78 211z" />
+<glyph unicode="&#xe008;" d="M600 1200q124 0 212 -88t88 -212v-250q0 -46 -31 -98t-69 -52v-75q0 -10 6 -21.5t15 -17.5l358 -230q9 -5 15 -16.5t6 -21.5v-93q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v93q0 10 6 21.5t15 16.5l358 230q9 6 15 17.5t6 21.5v75q-38 0 -69 52 t-31 98v250q0 124 88 212t212 88z" />
+<glyph unicode="&#xe009;" d="M25 1100h1150q10 0 17.5 -7.5t7.5 -17.5v-1050q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v1050q0 10 7.5 17.5t17.5 7.5zM100 1000v-100h100v100h-100zM875 1000h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5t17.5 -7.5h550 q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM1000 1000v-100h100v100h-100zM100 800v-100h100v100h-100zM1000 800v-100h100v100h-100zM100 600v-100h100v100h-100zM1000 600v-100h100v100h-100zM875 500h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5 t17.5 -7.5h550q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM100 400v-100h100v100h-100zM1000 400v-100h100v100h-100zM100 200v-100h100v100h-100zM1000 200v-100h100v100h-100z" />
+<glyph unicode="&#xe010;" d="M50 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM50 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe011;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM850 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 700h200q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5 t35.5 14.5z" />
+<glyph unicode="&#xe012;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h700q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe013;" d="M465 477l571 571q8 8 18 8t17 -8l177 -177q8 -7 8 -17t-8 -18l-783 -784q-7 -8 -17.5 -8t-17.5 8l-384 384q-8 8 -8 18t8 17l177 177q7 8 17 8t18 -8l171 -171q7 -7 18 -7t18 7z" />
+<glyph unicode="&#xe014;" d="M904 1083l178 -179q8 -8 8 -18.5t-8 -17.5l-267 -268l267 -268q8 -7 8 -17.5t-8 -18.5l-178 -178q-8 -8 -18.5 -8t-17.5 8l-268 267l-268 -267q-7 -8 -17.5 -8t-18.5 8l-178 178q-8 8 -8 18.5t8 17.5l267 268l-267 268q-8 7 -8 17.5t8 18.5l178 178q8 8 18.5 8t17.5 -8 l268 -267l268 268q7 7 17.5 7t18.5 -7z" />
+<glyph unicode="&#xe015;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM425 900h150q10 0 17.5 -7.5t7.5 -17.5v-75h75q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5 t-17.5 -7.5h-75v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-75q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v75q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe016;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM325 800h350q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-350q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe017;" d="M550 1200h100q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM800 975v166q167 -62 272 -209.5t105 -331.5q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5 t-184.5 123t-123 184.5t-45.5 224q0 184 105 331.5t272 209.5v-166q-103 -55 -165 -155t-62 -220q0 -116 57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5q0 120 -62 220t-165 155z" />
+<glyph unicode="&#xe018;" d="M1025 1200h150q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM725 800h150q10 0 17.5 -7.5t7.5 -17.5v-750q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v750 q0 10 7.5 17.5t17.5 7.5zM425 500h150q10 0 17.5 -7.5t7.5 -17.5v-450q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v450q0 10 7.5 17.5t17.5 7.5zM125 300h150q10 0 17.5 -7.5t7.5 -17.5v-250q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5 v250q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe019;" d="M600 1174q33 0 74 -5l38 -152l5 -1q49 -14 94 -39l5 -2l134 80q61 -48 104 -105l-80 -134l3 -5q25 -44 39 -93l1 -6l152 -38q5 -43 5 -73q0 -34 -5 -74l-152 -38l-1 -6q-15 -49 -39 -93l-3 -5l80 -134q-48 -61 -104 -105l-134 81l-5 -3q-44 -25 -94 -39l-5 -2l-38 -151 q-43 -5 -74 -5q-33 0 -74 5l-38 151l-5 2q-49 14 -94 39l-5 3l-134 -81q-60 48 -104 105l80 134l-3 5q-25 45 -38 93l-2 6l-151 38q-6 42 -6 74q0 33 6 73l151 38l2 6q13 48 38 93l3 5l-80 134q47 61 105 105l133 -80l5 2q45 25 94 39l5 1l38 152q43 5 74 5zM600 815 q-89 0 -152 -63t-63 -151.5t63 -151.5t152 -63t152 63t63 151.5t-63 151.5t-152 63z" />
+<glyph unicode="&#xe020;" d="M500 1300h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-75h-1100v75q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5zM500 1200v-100h300v100h-300zM1100 900v-800q0 -41 -29.5 -70.5t-70.5 -29.5h-700q-41 0 -70.5 29.5t-29.5 70.5 v800h900zM300 800v-700h100v700h-100zM500 800v-700h100v700h-100zM700 800v-700h100v700h-100zM900 800v-700h100v700h-100z" />
+<glyph unicode="&#xe021;" d="M18 618l620 608q8 7 18.5 7t17.5 -7l608 -608q8 -8 5.5 -13t-12.5 -5h-175v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v375h-300v-375q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v575h-175q-10 0 -12.5 5t5.5 13z" />
+<glyph unicode="&#xe022;" d="M600 1200v-400q0 -41 29.5 -70.5t70.5 -29.5h300v-650q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5h450zM1000 800h-250q-21 0 -35.5 14.5t-14.5 35.5v250z" />
+<glyph unicode="&#xe023;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h50q10 0 17.5 -7.5t7.5 -17.5v-275h175q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe024;" d="M1300 0h-538l-41 400h-242l-41 -400h-538l431 1200h209l-21 -300h162l-20 300h208zM515 800l-27 -300h224l-27 300h-170z" />
+<glyph unicode="&#xe025;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-450h191q20 0 25.5 -11.5t-7.5 -27.5l-327 -400q-13 -16 -32 -16t-32 16l-327 400q-13 16 -7.5 27.5t25.5 11.5h191v450q0 21 14.5 35.5t35.5 14.5zM1125 400h50q10 0 17.5 -7.5t7.5 -17.5v-350q0 -10 -7.5 -17.5t-17.5 -7.5 h-1050q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h50q10 0 17.5 -7.5t7.5 -17.5v-175h900v175q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe026;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -275q-13 -16 -32 -16t-32 16l-223 275q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z " />
+<glyph unicode="&#xe027;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM632 914l223 -275q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5l223 275q13 16 32 16 t32 -16z" />
+<glyph unicode="&#xe028;" d="M225 1200h750q10 0 19.5 -7t12.5 -17l186 -652q7 -24 7 -49v-425q0 -12 -4 -27t-9 -17q-12 -6 -37 -6h-1100q-12 0 -27 4t-17 8q-6 13 -6 38l1 425q0 25 7 49l185 652q3 10 12.5 17t19.5 7zM878 1000h-556q-10 0 -19 -7t-11 -18l-87 -450q-2 -11 4 -18t16 -7h150 q10 0 19.5 -7t11.5 -17l38 -152q2 -10 11.5 -17t19.5 -7h250q10 0 19.5 7t11.5 17l38 152q2 10 11.5 17t19.5 7h150q10 0 16 7t4 18l-87 450q-2 11 -11 18t-19 7z" />
+<glyph unicode="&#xe029;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM540 820l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
+<glyph unicode="&#xe030;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-362q0 -10 -7.5 -17.5t-17.5 -7.5h-362q-11 0 -13 5.5t5 12.5l133 133q-109 76 -238 76q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5h150q0 -117 -45.5 -224 t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117z" />
+<glyph unicode="&#xe031;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-361q0 -11 -7.5 -18.5t-18.5 -7.5h-361q-11 0 -13 5.5t5 12.5l134 134q-110 75 -239 75q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5h-150q0 117 45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117zM1027 600h150 q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5q-192 0 -348 118l-134 -134q-7 -8 -12.5 -5.5t-5.5 12.5v360q0 11 7.5 18.5t18.5 7.5h360q10 0 12.5 -5.5t-5.5 -12.5l-133 -133q110 -76 240 -76q116 0 214.5 57t155.5 155.5t57 214.5z" />
+<glyph unicode="&#xe032;" d="M125 1200h1050q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-1050q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM1075 1000h-850q-10 0 -17.5 -7.5t-7.5 -17.5v-850q0 -10 7.5 -17.5t17.5 -7.5h850q10 0 17.5 7.5t7.5 17.5v850 q0 10 -7.5 17.5t-17.5 7.5zM325 900h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 900h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 700h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 700h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 500h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 500h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 300h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 300h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe033;" d="M900 800v200q0 83 -58.5 141.5t-141.5 58.5h-300q-82 0 -141 -59t-59 -141v-200h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h900q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-100zM400 800v150q0 21 15 35.5t35 14.5h200 q20 0 35 -14.5t15 -35.5v-150h-300z" />
+<glyph unicode="&#xe034;" d="M125 1100h50q10 0 17.5 -7.5t7.5 -17.5v-1075h-100v1075q0 10 7.5 17.5t17.5 7.5zM1075 1052q4 0 9 -2q16 -6 16 -23v-421q0 -6 -3 -12q-33 -59 -66.5 -99t-65.5 -58t-56.5 -24.5t-52.5 -6.5q-26 0 -57.5 6.5t-52.5 13.5t-60 21q-41 15 -63 22.5t-57.5 15t-65.5 7.5 q-85 0 -160 -57q-7 -5 -15 -5q-6 0 -11 3q-14 7 -14 22v438q22 55 82 98.5t119 46.5q23 2 43 0.5t43 -7t32.5 -8.5t38 -13t32.5 -11q41 -14 63.5 -21t57 -14t63.5 -7q103 0 183 87q7 8 18 8z" />
+<glyph unicode="&#xe035;" d="M600 1175q116 0 227 -49.5t192.5 -131t131 -192.5t49.5 -227v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v300q0 127 -70.5 231.5t-184.5 161.5t-245 57t-245 -57t-184.5 -161.5t-70.5 -231.5v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50 q-10 0 -17.5 7.5t-7.5 17.5v300q0 116 49.5 227t131 192.5t192.5 131t227 49.5zM220 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460q0 8 6 14t14 6zM820 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460 q0 8 6 14t14 6z" />
+<glyph unicode="&#xe036;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM900 668l120 120q7 7 17 7t17 -7l34 -34q7 -7 7 -17t-7 -17l-120 -120l120 -120q7 -7 7 -17 t-7 -17l-34 -34q-7 -7 -17 -7t-17 7l-120 119l-120 -119q-7 -7 -17 -7t-17 7l-34 34q-7 7 -7 17t7 17l119 120l-119 120q-7 7 -7 17t7 17l34 34q7 8 17 8t17 -8z" />
+<glyph unicode="&#xe037;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6 l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238q-6 8 -4.5 18t9.5 17l29 22q7 5 15 5z" />
+<glyph unicode="&#xe038;" d="M967 1004h3q11 -1 17 -10q135 -179 135 -396q0 -105 -34 -206.5t-98 -185.5q-7 -9 -17 -10h-3q-9 0 -16 6l-42 34q-8 6 -9 16t5 18q111 150 111 328q0 90 -29.5 176t-84.5 157q-6 9 -5 19t10 16l42 33q7 5 15 5zM321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5 t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238 q-6 8 -4.5 18.5t9.5 16.5l29 22q7 5 15 5z" />
+<glyph unicode="&#xe039;" d="M500 900h100v-100h-100v-100h-400v-100h-100v600h500v-300zM1200 700h-200v-100h200v-200h-300v300h-200v300h-100v200h600v-500zM100 1100v-300h300v300h-300zM800 1100v-300h300v300h-300zM300 900h-100v100h100v-100zM1000 900h-100v100h100v-100zM300 500h200v-500 h-500v500h200v100h100v-100zM800 300h200v-100h-100v-100h-200v100h-100v100h100v200h-200v100h300v-300zM100 400v-300h300v300h-300zM300 200h-100v100h100v-100zM1200 200h-100v100h100v-100zM700 0h-100v100h100v-100zM1200 0h-300v100h300v-100z" />
+<glyph unicode="&#xe040;" d="M100 200h-100v1000h100v-1000zM300 200h-100v1000h100v-1000zM700 200h-200v1000h200v-1000zM900 200h-100v1000h100v-1000zM1200 200h-200v1000h200v-1000zM400 0h-300v100h300v-100zM600 0h-100v91h100v-91zM800 0h-100v91h100v-91zM1100 0h-200v91h200v-91z" />
+<glyph unicode="&#xe041;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
+<glyph unicode="&#xe042;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM800 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-56 56l424 426l-700 700h150zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5 t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
+<glyph unicode="&#xe043;" d="M300 1200h825q75 0 75 -75v-900q0 -25 -18 -43l-64 -64q-8 -8 -13 -5.5t-5 12.5v950q0 10 -7.5 17.5t-17.5 7.5h-700q-25 0 -43 -18l-64 -64q-8 -8 -5.5 -13t12.5 -5h700q10 0 17.5 -7.5t7.5 -17.5v-950q0 -10 -7.5 -17.5t-17.5 -7.5h-850q-10 0 -17.5 7.5t-7.5 17.5v975 q0 25 18 43l139 139q18 18 43 18z" />
+<glyph unicode="&#xe044;" d="M250 1200h800q21 0 35.5 -14.5t14.5 -35.5v-1150l-450 444l-450 -445v1151q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe045;" d="M822 1200h-444q-11 0 -19 -7.5t-9 -17.5l-78 -301q-7 -24 7 -45l57 -108q6 -9 17.5 -15t21.5 -6h450q10 0 21.5 6t17.5 15l62 108q14 21 7 45l-83 301q-1 10 -9 17.5t-19 7.5zM1175 800h-150q-10 0 -21 -6.5t-15 -15.5l-78 -156q-4 -9 -15 -15.5t-21 -6.5h-550 q-10 0 -21 6.5t-15 15.5l-78 156q-4 9 -15 15.5t-21 6.5h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-650q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h750q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5 t7.5 17.5v650q0 10 -7.5 17.5t-17.5 7.5zM850 200h-500q-10 0 -19.5 -7t-11.5 -17l-38 -152q-2 -10 3.5 -17t15.5 -7h600q10 0 15.5 7t3.5 17l-38 152q-2 10 -11.5 17t-19.5 7z" />
+<glyph unicode="&#xe046;" d="M500 1100h200q56 0 102.5 -20.5t72.5 -50t44 -59t25 -50.5l6 -20h150q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5h150q2 8 6.5 21.5t24 48t45 61t72 48t102.5 21.5zM900 800v-100 h100v100h-100zM600 730q-95 0 -162.5 -67.5t-67.5 -162.5t67.5 -162.5t162.5 -67.5t162.5 67.5t67.5 162.5t-67.5 162.5t-162.5 67.5zM600 603q43 0 73 -30t30 -73t-30 -73t-73 -30t-73 30t-30 73t30 73t73 30z" />
+<glyph unicode="&#xe047;" d="M681 1199l385 -998q20 -50 60 -92q18 -19 36.5 -29.5t27.5 -11.5l10 -2v-66h-417v66q53 0 75 43.5t5 88.5l-82 222h-391q-58 -145 -92 -234q-11 -34 -6.5 -57t25.5 -37t46 -20t55 -6v-66h-365v66q56 24 84 52q12 12 25 30.5t20 31.5l7 13l399 1006h93zM416 521h340 l-162 457z" />
+<glyph unicode="&#xe048;" d="M753 641q5 -1 14.5 -4.5t36 -15.5t50.5 -26.5t53.5 -40t50.5 -54.5t35.5 -70t14.5 -87q0 -67 -27.5 -125.5t-71.5 -97.5t-98.5 -66.5t-108.5 -40.5t-102 -13h-500v89q41 7 70.5 32.5t29.5 65.5v827q0 24 -0.5 34t-3.5 24t-8.5 19.5t-17 13.5t-28 12.5t-42.5 11.5v71 l471 -1q57 0 115.5 -20.5t108 -57t80.5 -94t31 -124.5q0 -51 -15.5 -96.5t-38 -74.5t-45 -50.5t-38.5 -30.5zM400 700h139q78 0 130.5 48.5t52.5 122.5q0 41 -8.5 70.5t-29.5 55.5t-62.5 39.5t-103.5 13.5h-118v-350zM400 200h216q80 0 121 50.5t41 130.5q0 90 -62.5 154.5 t-156.5 64.5h-159v-400z" />
+<glyph unicode="&#xe049;" d="M877 1200l2 -57q-83 -19 -116 -45.5t-40 -66.5l-132 -839q-9 -49 13 -69t96 -26v-97h-500v97q186 16 200 98l173 832q3 17 3 30t-1.5 22.5t-9 17.5t-13.5 12.5t-21.5 10t-26 8.5t-33.5 10q-13 3 -19 5v57h425z" />
+<glyph unicode="&#xe050;" d="M1300 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM175 1000h-75v-800h75l-125 -167l-125 167h75v800h-75l125 167z" />
+<glyph unicode="&#xe051;" d="M1100 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-650q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v650h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM1167 50l-167 -125v75h-800v-75l-167 125l167 125v-75h800v75z" />
+<glyph unicode="&#xe052;" d="M50 1100h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe053;" d="M250 1100h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM250 500h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe054;" d="M500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000 q-21 0 -35.5 14.5t-14.5 35.5zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5zM0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe055;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe056;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 1100h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 800h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 500h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 500h800q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 200h800 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe057;" d="M400 0h-100v1100h100v-1100zM550 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM267 550l-167 -125v75h-200v100h200v75zM550 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe058;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM900 0h-100v1100h100v-1100zM50 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM1100 600h200v-100h-200v-75l-167 125l167 125v-75zM50 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe059;" d="M75 1000h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53v650q0 31 22 53t53 22zM1200 300l-300 300l300 300v-600z" />
+<glyph unicode="&#xe060;" d="M44 1100h1112q18 0 31 -13t13 -31v-1012q0 -18 -13 -31t-31 -13h-1112q-18 0 -31 13t-13 31v1012q0 18 13 31t31 13zM100 1000v-737l247 182l298 -131l-74 156l293 318l236 -288v500h-1000zM342 884q56 0 95 -39t39 -94.5t-39 -95t-95 -39.5t-95 39.5t-39 95t39 94.5 t95 39z" />
+<glyph unicode="&#xe062;" d="M648 1169q117 0 216 -60t156.5 -161t57.5 -218q0 -115 -70 -258q-69 -109 -158 -225.5t-143 -179.5l-54 -62q-9 8 -25.5 24.5t-63.5 67.5t-91 103t-98.5 128t-95.5 148q-60 132 -60 249q0 88 34 169.5t91.5 142t137 96.5t166.5 36zM652.5 974q-91.5 0 -156.5 -65 t-65 -157t65 -156.5t156.5 -64.5t156.5 64.5t65 156.5t-65 157t-156.5 65z" />
+<glyph unicode="&#xe063;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 173v854q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57z" />
+<glyph unicode="&#xe064;" d="M554 1295q21 -72 57.5 -143.5t76 -130t83 -118t82.5 -117t70 -116t49.5 -126t18.5 -136.5q0 -71 -25.5 -135t-68.5 -111t-99 -82t-118.5 -54t-125.5 -23q-84 5 -161.5 34t-139.5 78.5t-99 125t-37 164.5q0 69 18 136.5t49.5 126.5t69.5 116.5t81.5 117.5t83.5 119 t76.5 131t58.5 143zM344 710q-23 -33 -43.5 -70.5t-40.5 -102.5t-17 -123q1 -37 14.5 -69.5t30 -52t41 -37t38.5 -24.5t33 -15q21 -7 32 -1t13 22l6 34q2 10 -2.5 22t-13.5 19q-5 4 -14 12t-29.5 40.5t-32.5 73.5q-26 89 6 271q2 11 -6 11q-8 1 -15 -10z" />
+<glyph unicode="&#xe065;" d="M1000 1013l108 115q2 1 5 2t13 2t20.5 -1t25 -9.5t28.5 -21.5q22 -22 27 -43t0 -32l-6 -10l-108 -115zM350 1100h400q50 0 105 -13l-187 -187h-368q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v182l200 200v-332 q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM1009 803l-362 -362l-161 -50l55 170l355 355z" />
+<glyph unicode="&#xe066;" d="M350 1100h361q-164 -146 -216 -200h-195q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-103q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M824 1073l339 -301q8 -7 8 -17.5t-8 -17.5l-340 -306q-7 -6 -12.5 -4t-6.5 11v203q-26 1 -54.5 0t-78.5 -7.5t-92 -17.5t-86 -35t-70 -57q10 59 33 108t51.5 81.5t65 58.5t68.5 40.5t67 24.5t56 13.5t40 4.5v210q1 10 6.5 12.5t13.5 -4.5z" />
+<glyph unicode="&#xe067;" d="M350 1100h350q60 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-219q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M643 639l395 395q7 7 17.5 7t17.5 -7l101 -101q7 -7 7 -17.5t-7 -17.5l-531 -532q-7 -7 -17.5 -7t-17.5 7l-248 248q-7 7 -7 17.5t7 17.5l101 101q7 7 17.5 7t17.5 -7l111 -111q8 -7 18 -7t18 7z" />
+<glyph unicode="&#xe068;" d="M318 918l264 264q8 8 18 8t18 -8l260 -264q7 -8 4.5 -13t-12.5 -5h-170v-200h200v173q0 10 5 12t13 -5l264 -260q8 -7 8 -17.5t-8 -17.5l-264 -265q-8 -7 -13 -5t-5 12v173h-200v-200h170q10 0 12.5 -5t-4.5 -13l-260 -264q-8 -8 -18 -8t-18 8l-264 264q-8 8 -5.5 13 t12.5 5h175v200h-200v-173q0 -10 -5 -12t-13 5l-264 265q-8 7 -8 17.5t8 17.5l264 260q8 7 13 5t5 -12v-173h200v200h-175q-10 0 -12.5 5t5.5 13z" />
+<glyph unicode="&#xe069;" d="M250 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe070;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5 t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe071;" d="M1200 1050v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-492 480q-15 14 -15 35t15 35l492 480q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25z" />
+<glyph unicode="&#xe072;" d="M243 1074l814 -498q18 -11 18 -26t-18 -26l-814 -498q-18 -11 -30.5 -4t-12.5 28v1000q0 21 12.5 28t30.5 -4z" />
+<glyph unicode="&#xe073;" d="M250 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM650 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800 q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe074;" d="M1100 950v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5z" />
+<glyph unicode="&#xe075;" d="M500 612v438q0 21 10.5 25t25.5 -10l492 -480q15 -14 15 -35t-15 -35l-492 -480q-15 -14 -25.5 -10t-10.5 25v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10z" />
+<glyph unicode="&#xe076;" d="M1048 1102l100 1q20 0 35 -14.5t15 -35.5l5 -1000q0 -21 -14.5 -35.5t-35.5 -14.5l-100 -1q-21 0 -35.5 14.5t-14.5 35.5l-2 437l-463 -454q-14 -15 -24.5 -10.5t-10.5 25.5l-2 437l-462 -455q-15 -14 -25.5 -9.5t-10.5 24.5l-5 1000q0 21 10.5 25.5t25.5 -10.5l466 -450 l-2 438q0 20 10.5 24.5t25.5 -9.5l466 -451l-2 438q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe077;" d="M850 1100h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10l464 -453v438q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe078;" d="M686 1081l501 -540q15 -15 10.5 -26t-26.5 -11h-1042q-22 0 -26.5 11t10.5 26l501 540q15 15 36 15t36 -15zM150 400h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe079;" d="M885 900l-352 -353l352 -353l-197 -198l-552 552l552 550z" />
+<glyph unicode="&#xe080;" d="M1064 547l-551 -551l-198 198l353 353l-353 353l198 198z" />
+<glyph unicode="&#xe081;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM650 900h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-150 q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5h150v-150q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v150h150q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-150v150q0 21 -14.5 35.5t-35.5 14.5z" />
+<glyph unicode="&#xe082;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM850 700h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5 t35.5 -14.5h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5z" />
+<glyph unicode="&#xe083;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM741.5 913q-12.5 0 -21.5 -9l-120 -120l-120 120q-9 9 -21.5 9 t-21.5 -9l-141 -141q-9 -9 -9 -21.5t9 -21.5l120 -120l-120 -120q-9 -9 -9 -21.5t9 -21.5l141 -141q9 -9 21.5 -9t21.5 9l120 120l120 -120q9 -9 21.5 -9t21.5 9l141 141q9 9 9 21.5t-9 21.5l-120 120l120 120q9 9 9 21.5t-9 21.5l-141 141q-9 9 -21.5 9z" />
+<glyph unicode="&#xe084;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM546 623l-84 85q-7 7 -17.5 7t-18.5 -7l-139 -139q-7 -8 -7 -18t7 -18 l242 -241q7 -8 17.5 -8t17.5 8l375 375q7 7 7 17.5t-7 18.5l-139 139q-7 7 -17.5 7t-17.5 -7z" />
+<glyph unicode="&#xe085;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM588 941q-29 0 -59 -5.5t-63 -20.5t-58 -38.5t-41.5 -63t-16.5 -89.5 q0 -25 20 -25h131q30 -5 35 11q6 20 20.5 28t45.5 8q20 0 31.5 -10.5t11.5 -28.5q0 -23 -7 -34t-26 -18q-1 0 -13.5 -4t-19.5 -7.5t-20 -10.5t-22 -17t-18.5 -24t-15.5 -35t-8 -46q-1 -8 5.5 -16.5t20.5 -8.5h173q7 0 22 8t35 28t37.5 48t29.5 74t12 100q0 47 -17 83 t-42.5 57t-59.5 34.5t-64 18t-59 4.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe086;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM675 1000h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5 t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5zM675 700h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h75v-200h-75q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h350q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5 t-17.5 7.5h-75v275q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe087;" d="M525 1200h150q10 0 17.5 -7.5t7.5 -17.5v-194q103 -27 178.5 -102.5t102.5 -178.5h194q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-194q-27 -103 -102.5 -178.5t-178.5 -102.5v-194q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v194 q-103 27 -178.5 102.5t-102.5 178.5h-194q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h194q27 103 102.5 178.5t178.5 102.5v194q0 10 7.5 17.5t17.5 7.5zM700 893v-168q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v168q-68 -23 -119 -74 t-74 -119h168q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-168q23 -68 74 -119t119 -74v168q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-168q68 23 119 74t74 119h-168q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h168 q-23 68 -74 119t-119 74z" />
+<glyph unicode="&#xe088;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM759 823l64 -64q7 -7 7 -17.5t-7 -17.5l-124 -124l124 -124q7 -7 7 -17.5t-7 -17.5l-64 -64q-7 -7 -17.5 -7t-17.5 7l-124 124l-124 -124q-7 -7 -17.5 -7t-17.5 7l-64 64 q-7 7 -7 17.5t7 17.5l124 124l-124 124q-7 7 -7 17.5t7 17.5l64 64q7 7 17.5 7t17.5 -7l124 -124l124 124q7 7 17.5 7t17.5 -7z" />
+<glyph unicode="&#xe089;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM782 788l106 -106q7 -7 7 -17.5t-7 -17.5l-320 -321q-8 -7 -18 -7t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l197 197q7 7 17.5 7t17.5 -7z" />
+<glyph unicode="&#xe090;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5q0 -120 65 -225 l587 587q-105 65 -225 65zM965 819l-584 -584q104 -62 219 -62q116 0 214.5 57t155.5 155.5t57 214.5q0 115 -62 219z" />
+<glyph unicode="&#xe091;" d="M39 582l522 427q16 13 27.5 8t11.5 -26v-291h550q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-550v-291q0 -21 -11.5 -26t-27.5 8l-522 427q-16 13 -16 32t16 32z" />
+<glyph unicode="&#xe092;" d="M639 1009l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291h-550q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h550v291q0 21 11.5 26t27.5 -8z" />
+<glyph unicode="&#xe093;" d="M682 1161l427 -522q13 -16 8 -27.5t-26 -11.5h-291v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v550h-291q-21 0 -26 11.5t8 27.5l427 522q13 16 32 16t32 -16z" />
+<glyph unicode="&#xe094;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-550h291q21 0 26 -11.5t-8 -27.5l-427 -522q-13 -16 -32 -16t-32 16l-427 522q-13 16 -8 27.5t26 11.5h291v550q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe095;" d="M639 1109l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291q-94 -2 -182 -20t-170.5 -52t-147 -92.5t-100.5 -135.5q5 105 27 193.5t67.5 167t113 135t167 91.5t225.5 42v262q0 21 11.5 26t27.5 -8z" />
+<glyph unicode="&#xe096;" d="M850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5zM350 0h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249 q8 7 18 7t18 -7l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5z" />
+<glyph unicode="&#xe097;" d="M1014 1120l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249q8 7 18 7t18 -7zM250 600h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5z" />
+<glyph unicode="&#xe101;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM704 900h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5 t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe102;" d="M260 1200q9 0 19 -2t15 -4l5 -2q22 -10 44 -23l196 -118q21 -13 36 -24q29 -21 37 -12q11 13 49 35l196 118q22 13 45 23q17 7 38 7q23 0 47 -16.5t37 -33.5l13 -16q14 -21 18 -45l25 -123l8 -44q1 -9 8.5 -14.5t17.5 -5.5h61q10 0 17.5 -7.5t7.5 -17.5v-50 q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 -7.5t-7.5 -17.5v-175h-400v300h-200v-300h-400v175q0 10 -7.5 17.5t-17.5 7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5h61q11 0 18 3t7 8q0 4 9 52l25 128q5 25 19 45q2 3 5 7t13.5 15t21.5 19.5t26.5 15.5 t29.5 7zM915 1079l-166 -162q-7 -7 -5 -12t12 -5h219q10 0 15 7t2 17l-51 149q-3 10 -11 12t-15 -6zM463 917l-177 157q-8 7 -16 5t-11 -12l-51 -143q-3 -10 2 -17t15 -7h231q11 0 12.5 5t-5.5 12zM500 0h-375q-10 0 -17.5 7.5t-7.5 17.5v375h400v-400zM1100 400v-375 q0 -10 -7.5 -17.5t-17.5 -7.5h-375v400h400z" />
+<glyph unicode="&#xe103;" d="M1165 1190q8 3 21 -6.5t13 -17.5q-2 -178 -24.5 -323.5t-55.5 -245.5t-87 -174.5t-102.5 -118.5t-118 -68.5t-118.5 -33t-120 -4.5t-105 9.5t-90 16.5q-61 12 -78 11q-4 1 -12.5 0t-34 -14.5t-52.5 -40.5l-153 -153q-26 -24 -37 -14.5t-11 43.5q0 64 42 102q8 8 50.5 45 t66.5 58q19 17 35 47t13 61q-9 55 -10 102.5t7 111t37 130t78 129.5q39 51 80 88t89.5 63.5t94.5 45t113.5 36t129 31t157.5 37t182 47.5zM1116 1098q-8 9 -22.5 -3t-45.5 -50q-38 -47 -119 -103.5t-142 -89.5l-62 -33q-56 -30 -102 -57t-104 -68t-102.5 -80.5t-85.5 -91 t-64 -104.5q-24 -56 -31 -86t2 -32t31.5 17.5t55.5 59.5q25 30 94 75.5t125.5 77.5t147.5 81q70 37 118.5 69t102 79.5t99 111t86.5 148.5q22 50 24 60t-6 19z" />
+<glyph unicode="&#xe104;" d="M653 1231q-39 -67 -54.5 -131t-10.5 -114.5t24.5 -96.5t47.5 -80t63.5 -62.5t68.5 -46.5t65 -30q-4 7 -17.5 35t-18.5 39.5t-17 39.5t-17 43t-13 42t-9.5 44.5t-2 42t4 43t13.5 39t23 38.5q96 -42 165 -107.5t105 -138t52 -156t13 -159t-19 -149.5q-13 -55 -44 -106.5 t-68 -87t-78.5 -64.5t-72.5 -45t-53 -22q-72 -22 -127 -11q-31 6 -13 19q6 3 17 7q13 5 32.5 21t41 44t38.5 63.5t21.5 81.5t-6.5 94.5t-50 107t-104 115.5q10 -104 -0.5 -189t-37 -140.5t-65 -93t-84 -52t-93.5 -11t-95 24.5q-80 36 -131.5 114t-53.5 171q-2 23 0 49.5 t4.5 52.5t13.5 56t27.5 60t46 64.5t69.5 68.5q-8 -53 -5 -102.5t17.5 -90t34 -68.5t44.5 -39t49 -2q31 13 38.5 36t-4.5 55t-29 64.5t-36 75t-26 75.5q-15 85 2 161.5t53.5 128.5t85.5 92.5t93.5 61t81.5 25.5z" />
+<glyph unicode="&#xe105;" d="M600 1094q82 0 160.5 -22.5t140 -59t116.5 -82.5t94.5 -95t68 -95t42.5 -82.5t14 -57.5t-14 -57.5t-43 -82.5t-68.5 -95t-94.5 -95t-116.5 -82.5t-140 -59t-159.5 -22.5t-159.5 22.5t-140 59t-116.5 82.5t-94.5 95t-68.5 95t-43 82.5t-14 57.5t14 57.5t42.5 82.5t68 95 t94.5 95t116.5 82.5t140 59t160.5 22.5zM888 829q-15 15 -18 12t5 -22q25 -57 25 -119q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 59 23 114q8 19 4.5 22t-17.5 -12q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q22 -36 47 -71t70 -82t92.5 -81t113 -58.5t133.5 -24.5 t133.5 24t113 58.5t92.5 81.5t70 81.5t47 70.5q11 18 9 42.5t-14 41.5q-90 117 -163 189zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l35 34q14 15 12.5 33.5t-16.5 33.5q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
+<glyph unicode="&#xe106;" d="M592 0h-148l31 120q-91 20 -175.5 68.5t-143.5 106.5t-103.5 119t-66.5 110t-22 76q0 21 14 57.5t42.5 82.5t68 95t94.5 95t116.5 82.5t140 59t160.5 22.5q61 0 126 -15l32 121h148zM944 770l47 181q108 -85 176.5 -192t68.5 -159q0 -26 -19.5 -71t-59.5 -102t-93 -112 t-129 -104.5t-158 -75.5l46 173q77 49 136 117t97 131q11 18 9 42.5t-14 41.5q-54 70 -107 130zM310 824q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q18 -30 39 -60t57 -70.5t74 -73t90 -61t105 -41.5l41 154q-107 18 -178.5 101.5t-71.5 193.5q0 59 23 114q8 19 4.5 22 t-17.5 -12zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l12 11l22 86l-3 4q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
+<glyph unicode="&#xe107;" d="M-90 100l642 1066q20 31 48 28.5t48 -35.5l642 -1056q21 -32 7.5 -67.5t-50.5 -35.5h-1294q-37 0 -50.5 34t7.5 66zM155 200h345v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h345l-445 723zM496 700h208q20 0 32 -14.5t8 -34.5l-58 -252 q-4 -20 -21.5 -34.5t-37.5 -14.5h-54q-20 0 -37.5 14.5t-21.5 34.5l-58 252q-4 20 8 34.5t32 14.5z" />
+<glyph unicode="&#xe108;" d="M650 1200q62 0 106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -93 100 -113v-64q0 -21 -13 -29t-32 1l-205 128l-205 -128q-19 -9 -32 -1t-13 29v64q0 20 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5v41 q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44z" />
+<glyph unicode="&#xe109;" d="M850 1200h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-150h-1100v150q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-50h500v50q0 21 14.5 35.5t35.5 14.5zM1100 800v-750q0 -21 -14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v750h1100zM100 600v-100h100v100h-100zM300 600v-100h100v100h-100zM500 600v-100h100v100h-100zM700 600v-100h100v100h-100zM900 600v-100h100v100h-100zM100 400v-100h100v100h-100zM300 400v-100h100v100h-100zM500 400 v-100h100v100h-100zM700 400v-100h100v100h-100zM900 400v-100h100v100h-100zM100 200v-100h100v100h-100zM300 200v-100h100v100h-100zM500 200v-100h100v100h-100zM700 200v-100h100v100h-100zM900 200v-100h100v100h-100z" />
+<glyph unicode="&#xe110;" d="M1135 1165l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-159l-600 -600h-291q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h209l600 600h241v150q0 21 10.5 25t24.5 -10zM522 819l-141 -141l-122 122h-209q-21 0 -35.5 14.5 t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h291zM1135 565l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-241l-181 181l141 141l122 -122h159v150q0 21 10.5 25t24.5 -10z" />
+<glyph unicode="&#xe111;" d="M100 1100h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5z" />
+<glyph unicode="&#xe112;" d="M150 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM850 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM1100 800v-300q0 -41 -3 -77.5t-15 -89.5t-32 -96t-58 -89t-89 -77t-129 -51t-174 -20t-174 20 t-129 51t-89 77t-58 89t-32 96t-15 89.5t-3 77.5v300h300v-250v-27v-42.5t1.5 -41t5 -38t10 -35t16.5 -30t25.5 -24.5t35 -19t46.5 -12t60 -4t60 4.5t46.5 12.5t35 19.5t25 25.5t17 30.5t10 35t5 38t2 40.5t-0.5 42v25v250h300z" />
+<glyph unicode="&#xe113;" d="M1100 411l-198 -199l-353 353l-353 -353l-197 199l551 551z" />
+<glyph unicode="&#xe114;" d="M1101 789l-550 -551l-551 551l198 199l353 -353l353 353z" />
+<glyph unicode="&#xe115;" d="M404 1000h746q21 0 35.5 -14.5t14.5 -35.5v-551h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v401h-381zM135 984l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-400h385l215 -200h-750q-21 0 -35.5 14.5 t-14.5 35.5v550h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
+<glyph unicode="&#xe116;" d="M56 1200h94q17 0 31 -11t18 -27l38 -162h896q24 0 39 -18.5t10 -42.5l-100 -475q-5 -21 -27 -42.5t-55 -21.5h-633l48 -200h535q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-50q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-300v-50 q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-31q-18 0 -32.5 10t-20.5 19l-5 10l-201 961h-54q-20 0 -35 14.5t-15 35.5t15 35.5t35 14.5z" />
+<glyph unicode="&#xe117;" d="M1200 1000v-100h-1200v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500zM0 800h1200v-800h-1200v800z" />
+<glyph unicode="&#xe118;" d="M200 800l-200 -400v600h200q0 41 29.5 70.5t70.5 29.5h300q42 0 71 -29.5t29 -70.5h500v-200h-1000zM1500 700l-300 -700h-1200l300 700h1200z" />
+<glyph unicode="&#xe119;" d="M635 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-601h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v601h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
+<glyph unicode="&#xe120;" d="M936 864l249 -229q14 -15 14 -35.5t-14 -35.5l-249 -229q-15 -15 -25.5 -10.5t-10.5 24.5v151h-600v-151q0 -20 -10.5 -24.5t-25.5 10.5l-249 229q-14 15 -14 35.5t14 35.5l249 229q15 15 25.5 10.5t10.5 -25.5v-149h600v149q0 21 10.5 25.5t25.5 -10.5z" />
+<glyph unicode="&#xe121;" d="M1169 400l-172 732q-5 23 -23 45.5t-38 22.5h-672q-20 0 -38 -20t-23 -41l-172 -739h1138zM1100 300h-1000q-41 0 -70.5 -29.5t-29.5 -70.5v-100q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v100q0 41 -29.5 70.5t-70.5 29.5zM800 100v100h100v-100h-100 zM1000 100v100h100v-100h-100z" />
+<glyph unicode="&#xe122;" d="M1150 1100q21 0 35.5 -14.5t14.5 -35.5v-850q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v850q0 21 14.5 35.5t35.5 14.5zM1000 200l-675 200h-38l47 -276q3 -16 -5.5 -20t-29.5 -4h-7h-84q-20 0 -34.5 14t-18.5 35q-55 337 -55 351v250v6q0 16 1 23.5t6.5 14 t17.5 6.5h200l675 250v-850zM0 750v-250q-4 0 -11 0.5t-24 6t-30 15t-24 30t-11 48.5v50q0 26 10.5 46t25 30t29 16t25.5 7z" />
+<glyph unicode="&#xe123;" d="M553 1200h94q20 0 29 -10.5t3 -29.5l-18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q19 0 33 -14.5t14 -35t-13 -40.5t-31 -27q-8 -4 -23 -9.5t-65 -19.5t-103 -25t-132.5 -20t-158.5 -9q-57 0 -115 5t-104 12t-88.5 15.5t-73.5 17.5t-54.5 16t-35.5 12l-11 4 q-18 8 -31 28t-13 40.5t14 35t33 14.5h17l118 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3.5 32t28.5 13zM498 110q50 -6 102 -6q53 0 102 6q-12 -49 -39.5 -79.5t-62.5 -30.5t-63 30.5t-39 79.5z" />
+<glyph unicode="&#xe124;" d="M800 946l224 78l-78 -224l234 -45l-180 -155l180 -155l-234 -45l78 -224l-224 78l-45 -234l-155 180l-155 -180l-45 234l-224 -78l78 224l-234 45l180 155l-180 155l234 45l-78 224l224 -78l45 234l155 -180l155 180z" />
+<glyph unicode="&#xe125;" d="M650 1200h50q40 0 70 -40.5t30 -84.5v-150l-28 -125h328q40 0 70 -40.5t30 -84.5v-100q0 -45 -29 -74l-238 -344q-16 -24 -38 -40.5t-45 -16.5h-250q-7 0 -42 25t-66 50l-31 25h-61q-45 0 -72.5 18t-27.5 57v400q0 36 20 63l145 196l96 198q13 28 37.5 48t51.5 20z M650 1100l-100 -212l-150 -213v-375h100l136 -100h214l250 375v125h-450l50 225v175h-50zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe126;" d="M600 1100h250q23 0 45 -16.5t38 -40.5l238 -344q29 -29 29 -74v-100q0 -44 -30 -84.5t-70 -40.5h-328q28 -118 28 -125v-150q0 -44 -30 -84.5t-70 -40.5h-50q-27 0 -51.5 20t-37.5 48l-96 198l-145 196q-20 27 -20 63v400q0 39 27.5 57t72.5 18h61q124 100 139 100z M50 1000h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM636 1000l-136 -100h-100v-375l150 -213l100 -212h50v175l-50 225h450v125l-250 375h-214z" />
+<glyph unicode="&#xe127;" d="M356 873l363 230q31 16 53 -6l110 -112q13 -13 13.5 -32t-11.5 -34l-84 -121h302q84 0 138 -38t54 -110t-55 -111t-139 -39h-106l-131 -339q-6 -21 -19.5 -41t-28.5 -20h-342q-7 0 -90 81t-83 94v525q0 17 14 35.5t28 28.5zM400 792v-503l100 -89h293l131 339 q6 21 19.5 41t28.5 20h203q21 0 30.5 25t0.5 50t-31 25h-456h-7h-6h-5.5t-6 0.5t-5 1.5t-5 2t-4 2.5t-4 4t-2.5 4.5q-12 25 5 47l146 183l-86 83zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500 q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe128;" d="M475 1103l366 -230q2 -1 6 -3.5t14 -10.5t18 -16.5t14.5 -20t6.5 -22.5v-525q0 -13 -86 -94t-93 -81h-342q-15 0 -28.5 20t-19.5 41l-131 339h-106q-85 0 -139.5 39t-54.5 111t54 110t138 38h302l-85 121q-11 15 -10.5 34t13.5 32l110 112q22 22 53 6zM370 945l146 -183 q17 -22 5 -47q-2 -2 -3.5 -4.5t-4 -4t-4 -2.5t-5 -2t-5 -1.5t-6 -0.5h-6h-6.5h-6h-475v-100h221q15 0 29 -20t20 -41l130 -339h294l106 89v503l-342 236zM1050 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5 v500q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe129;" d="M550 1294q72 0 111 -55t39 -139v-106l339 -131q21 -6 41 -19.5t20 -28.5v-342q0 -7 -81 -90t-94 -83h-525q-17 0 -35.5 14t-28.5 28l-9 14l-230 363q-16 31 6 53l112 110q13 13 32 13.5t34 -11.5l121 -84v302q0 84 38 138t110 54zM600 972v203q0 21 -25 30.5t-50 0.5 t-25 -31v-456v-7v-6v-5.5t-0.5 -6t-1.5 -5t-2 -5t-2.5 -4t-4 -4t-4.5 -2.5q-25 -12 -47 5l-183 146l-83 -86l236 -339h503l89 100v293l-339 131q-21 6 -41 19.5t-20 28.5zM450 200h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe130;" d="M350 1100h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5zM600 306v-106q0 -84 -39 -139t-111 -55t-110 54t-38 138v302l-121 -84q-15 -12 -34 -11.5t-32 13.5l-112 110 q-22 22 -6 53l230 363q1 2 3.5 6t10.5 13.5t16.5 17t20 13.5t22.5 6h525q13 0 94 -83t81 -90v-342q0 -15 -20 -28.5t-41 -19.5zM308 900l-236 -339l83 -86l183 146q22 17 47 5q2 -1 4.5 -2.5t4 -4t2.5 -4t2 -5t1.5 -5t0.5 -6v-5.5v-6v-7v-456q0 -22 25 -31t50 0.5t25 30.5 v203q0 15 20 28.5t41 19.5l339 131v293l-89 100h-503z" />
+<glyph unicode="&#xe131;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM914 632l-275 223q-16 13 -27.5 8t-11.5 -26v-137h-275 q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h275v-137q0 -21 11.5 -26t27.5 8l275 223q16 13 16 32t-16 32z" />
+<glyph unicode="&#xe132;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM561 855l-275 -223q-16 -13 -16 -32t16 -32l275 -223q16 -13 27.5 -8 t11.5 26v137h275q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5h-275v137q0 21 -11.5 26t-27.5 -8z" />
+<glyph unicode="&#xe133;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM855 639l-223 275q-13 16 -32 16t-32 -16l-223 -275q-13 -16 -8 -27.5 t26 -11.5h137v-275q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v275h137q21 0 26 11.5t-8 27.5z" />
+<glyph unicode="&#xe134;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM675 900h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-275h-137q-21 0 -26 -11.5 t8 -27.5l223 -275q13 -16 32 -16t32 16l223 275q13 16 8 27.5t-26 11.5h-137v275q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe135;" d="M600 1176q116 0 222.5 -46t184 -123.5t123.5 -184t46 -222.5t-46 -222.5t-123.5 -184t-184 -123.5t-222.5 -46t-222.5 46t-184 123.5t-123.5 184t-46 222.5t46 222.5t123.5 184t184 123.5t222.5 46zM627 1101q-15 -12 -36.5 -20.5t-35.5 -12t-43 -8t-39 -6.5 q-15 -3 -45.5 0t-45.5 -2q-20 -7 -51.5 -26.5t-34.5 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -91t-29.5 -79q-9 -34 5 -93t8 -87q0 -9 17 -44.5t16 -59.5q12 0 23 -5t23.5 -15t19.5 -14q16 -8 33 -15t40.5 -15t34.5 -12q21 -9 52.5 -32t60 -38t57.5 -11 q7 -15 -3 -34t-22.5 -40t-9.5 -38q13 -21 23 -34.5t27.5 -27.5t36.5 -18q0 -7 -3.5 -16t-3.5 -14t5 -17q104 -2 221 112q30 29 46.5 47t34.5 49t21 63q-13 8 -37 8.5t-36 7.5q-15 7 -49.5 15t-51.5 19q-18 0 -41 -0.5t-43 -1.5t-42 -6.5t-38 -16.5q-51 -35 -66 -12 q-4 1 -3.5 25.5t0.5 25.5q-6 13 -26.5 17.5t-24.5 6.5q1 15 -0.5 30.5t-7 28t-18.5 11.5t-31 -21q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q7 -12 18 -24t21.5 -20.5t20 -15t15.5 -10.5l5 -3q2 12 7.5 30.5t8 34.5t-0.5 32q-3 18 3.5 29 t18 22.5t15.5 24.5q6 14 10.5 35t8 31t15.5 22.5t34 22.5q-6 18 10 36q8 0 24 -1.5t24.5 -1.5t20 4.5t20.5 15.5q-10 23 -31 42.5t-37.5 29.5t-49 27t-43.5 23q0 1 2 8t3 11.5t1.5 10.5t-1 9.5t-4.5 4.5q31 -13 58.5 -14.5t38.5 2.5l12 5q5 28 -9.5 46t-36.5 24t-50 15 t-41 20q-18 -4 -37 0zM613 994q0 -17 8 -42t17 -45t9 -23q-8 1 -39.5 5.5t-52.5 10t-37 16.5q3 11 16 29.5t16 25.5q10 -10 19 -10t14 6t13.5 14.5t16.5 12.5z" />
+<glyph unicode="&#xe136;" d="M756 1157q164 92 306 -9l-259 -138l145 -232l251 126q6 -89 -34 -156.5t-117 -110.5q-60 -34 -127 -39.5t-126 16.5l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5t15 37.5l600 599q-34 101 5.5 201.5t135.5 154.5z" />
+<glyph unicode="&#xe137;" horiz-adv-x="1220" d="M100 1196h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 1096h-200v-100h200v100zM100 796h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 696h-500v-100h500v100zM100 396h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 296h-300v-100h300v100z " />
+<glyph unicode="&#xe138;" d="M150 1200h900q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM700 500v-300l-200 -200v500l-350 500h900z" />
+<glyph unicode="&#xe139;" d="M500 1200h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5zM500 1100v-100h200v100h-200zM1200 400v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v200h1200z" />
+<glyph unicode="&#xe140;" d="M50 1200h300q21 0 25 -10.5t-10 -24.5l-94 -94l199 -199q7 -8 7 -18t-7 -18l-106 -106q-8 -7 -18 -7t-18 7l-199 199l-94 -94q-14 -14 -24.5 -10t-10.5 25v300q0 21 14.5 35.5t35.5 14.5zM850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-199 -199q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l199 199l-94 94q-14 14 -10 24.5t25 10.5zM364 470l106 -106q7 -8 7 -18t-7 -18l-199 -199l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l199 199 q8 7 18 7t18 -7zM1071 271l94 94q14 14 24.5 10t10.5 -25v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -25 10.5t10 24.5l94 94l-199 199q-7 8 -7 18t7 18l106 106q8 7 18 7t18 -7z" />
+<glyph unicode="&#xe141;" d="M596 1192q121 0 231.5 -47.5t190 -127t127 -190t47.5 -231.5t-47.5 -231.5t-127 -190.5t-190 -127t-231.5 -47t-231.5 47t-190.5 127t-127 190.5t-47 231.5t47 231.5t127 190t190.5 127t231.5 47.5zM596 1010q-112 0 -207.5 -55.5t-151 -151t-55.5 -207.5t55.5 -207.5 t151 -151t207.5 -55.5t207.5 55.5t151 151t55.5 207.5t-55.5 207.5t-151 151t-207.5 55.5zM454.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38.5 -16.5t-38.5 16.5t-16 39t16 38.5t38.5 16zM754.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38 -16.5q-14 0 -29 10l-55 -145 q17 -23 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 23 16 39t38.5 16zM345.5 709q22.5 0 38.5 -16t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16zM854.5 709q22.5 0 38.5 -16 t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16z" />
+<glyph unicode="&#xe142;" d="M546 173l469 470q91 91 99 192q7 98 -52 175.5t-154 94.5q-22 4 -47 4q-34 0 -66.5 -10t-56.5 -23t-55.5 -38t-48 -41.5t-48.5 -47.5q-376 -375 -391 -390q-30 -27 -45 -41.5t-37.5 -41t-32 -46.5t-16 -47.5t-1.5 -56.5q9 -62 53.5 -95t99.5 -33q74 0 125 51l548 548 q36 36 20 75q-7 16 -21.5 26t-32.5 10q-26 0 -50 -23q-13 -12 -39 -38l-341 -338q-15 -15 -35.5 -15.5t-34.5 13.5t-14 34.5t14 34.5q327 333 361 367q35 35 67.5 51.5t78.5 16.5q14 0 29 -1q44 -8 74.5 -35.5t43.5 -68.5q14 -47 2 -96.5t-47 -84.5q-12 -11 -32 -32 t-79.5 -81t-114.5 -115t-124.5 -123.5t-123 -119.5t-96.5 -89t-57 -45q-56 -27 -120 -27q-70 0 -129 32t-93 89q-48 78 -35 173t81 163l511 511q71 72 111 96q91 55 198 55q80 0 152 -33q78 -36 129.5 -103t66.5 -154q17 -93 -11 -183.5t-94 -156.5l-482 -476 q-15 -15 -36 -16t-37 14t-17.5 34t14.5 35z" />
+<glyph unicode="&#xe143;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104zM896 972q-33 0 -64.5 -19t-56.5 -46t-47.5 -53.5t-43.5 -45.5t-37.5 -19t-36 19t-40 45.5t-43 53.5t-54 46t-65.5 19q-67 0 -122.5 -55.5t-55.5 -132.5q0 -23 13.5 -51t46 -65t57.5 -63t76 -75l22 -22q15 -14 44 -44t50.5 -51t46 -44t41 -35t23 -12 t23.5 12t42.5 36t46 44t52.5 52t44 43q4 4 12 13q43 41 63.5 62t52 55t46 55t26 46t11.5 44q0 79 -53 133.5t-120 54.5z" />
+<glyph unicode="&#xe144;" d="M776.5 1214q93.5 0 159.5 -66l141 -141q66 -66 66 -160q0 -42 -28 -95.5t-62 -87.5l-29 -29q-31 53 -77 99l-18 18l95 95l-247 248l-389 -389l212 -212l-105 -106l-19 18l-141 141q-66 66 -66 159t66 159l283 283q65 66 158.5 66zM600 706l105 105q10 -8 19 -17l141 -141 q66 -66 66 -159t-66 -159l-283 -283q-66 -66 -159 -66t-159 66l-141 141q-66 66 -66 159.5t66 159.5l55 55q29 -55 75 -102l18 -17l-95 -95l247 -248l389 389z" />
+<glyph unicode="&#xe145;" d="M603 1200q85 0 162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5v953q0 21 30 46.5t81 48t129 37.5t163 15zM300 1000v-700h600v700h-600zM600 254q-43 0 -73.5 -30.5t-30.5 -73.5t30.5 -73.5t73.5 -30.5t73.5 30.5 t30.5 73.5t-30.5 73.5t-73.5 30.5z" />
+<glyph unicode="&#xe146;" d="M902 1185l283 -282q15 -15 15 -36t-14.5 -35.5t-35.5 -14.5t-35 15l-36 35l-279 -267v-300l-212 210l-308 -307l-280 -203l203 280l307 308l-210 212h300l267 279l-35 36q-15 14 -15 35t14.5 35.5t35.5 14.5t35 -15z" />
+<glyph unicode="&#xe148;" d="M700 1248v-78q38 -5 72.5 -14.5t75.5 -31.5t71 -53.5t52 -84t24 -118.5h-159q-4 36 -10.5 59t-21 45t-40 35.5t-64.5 20.5v-307l64 -13q34 -7 64 -16.5t70 -32t67.5 -52.5t47.5 -80t20 -112q0 -139 -89 -224t-244 -97v-77h-100v79q-150 16 -237 103q-40 40 -52.5 93.5 t-15.5 139.5h139q5 -77 48.5 -126t117.5 -65v335l-27 8q-46 14 -79 26.5t-72 36t-63 52t-40 72.5t-16 98q0 70 25 126t67.5 92t94.5 57t110 27v77h100zM600 754v274q-29 -4 -50 -11t-42 -21.5t-31.5 -41.5t-10.5 -65q0 -29 7 -50.5t16.5 -34t28.5 -22.5t31.5 -14t37.5 -10 q9 -3 13 -4zM700 547v-310q22 2 42.5 6.5t45 15.5t41.5 27t29 42t12 59.5t-12.5 59.5t-38 44.5t-53 31t-66.5 24.5z" />
+<glyph unicode="&#xe149;" d="M561 1197q84 0 160.5 -40t123.5 -109.5t47 -147.5h-153q0 40 -19.5 71.5t-49.5 48.5t-59.5 26t-55.5 9q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -26 13.5 -63t26.5 -61t37 -66q6 -9 9 -14h241v-100h-197q8 -50 -2.5 -115t-31.5 -95q-45 -62 -99 -112 q34 10 83 17.5t71 7.5q32 1 102 -16t104 -17q83 0 136 30l50 -147q-31 -19 -58 -30.5t-55 -15.5t-42 -4.5t-46 -0.5q-23 0 -76 17t-111 32.5t-96 11.5q-39 -3 -82 -16t-67 -25l-23 -11l-55 145q4 3 16 11t15.5 10.5t13 9t15.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221v100h166q-23 47 -44 104q-7 20 -12 41.5t-6 55.5t6 66.5t29.5 70.5t58.5 71q97 88 263 88z" />
+<glyph unicode="&#xe150;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM935 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-900h-200v900h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
+<glyph unicode="&#xe151;" d="M1000 700h-100v100h-100v-100h-100v500h300v-500zM400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM801 1100v-200h100v200h-100zM1000 350l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150z " />
+<glyph unicode="&#xe152;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 1050l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150zM1000 0h-100v100h-100v-100h-100v500h300v-500zM801 400v-200h100v200h-100z " />
+<glyph unicode="&#xe153;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 700h-100v400h-100v100h200v-500zM1100 0h-100v100h-200v400h300v-500zM901 400v-200h100v200h-100z" />
+<glyph unicode="&#xe154;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1100 700h-100v100h-200v400h300v-500zM901 1100v-200h100v200h-100zM1000 0h-100v400h-100v100h200v-500z" />
+<glyph unicode="&#xe155;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM900 1000h-200v200h200v-200zM1000 700h-300v200h300v-200zM1100 400h-400v200h400v-200zM1200 100h-500v200h500v-200z" />
+<glyph unicode="&#xe156;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1200 1000h-500v200h500v-200zM1100 700h-400v200h400v-200zM1000 400h-300v200h300v-200zM900 100h-200v200h200v-200z" />
+<glyph unicode="&#xe157;" d="M350 1100h400q162 0 256 -93.5t94 -256.5v-400q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5z" />
+<glyph unicode="&#xe158;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-163 0 -256.5 92.5t-93.5 257.5v400q0 163 94 256.5t256 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM440 770l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
+<glyph unicode="&#xe159;" d="M350 1100h400q163 0 256.5 -94t93.5 -256v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 163 92.5 256.5t257.5 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM350 700h400q21 0 26.5 -12t-6.5 -28l-190 -253q-12 -17 -30 -17t-30 17l-190 253q-12 16 -6.5 28t26.5 12z" />
+<glyph unicode="&#xe160;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -163 -92.5 -256.5t-257.5 -93.5h-400q-163 0 -256.5 94t-93.5 256v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM580 693l190 -253q12 -16 6.5 -28t-26.5 -12h-400q-21 0 -26.5 12t6.5 28l190 253q12 17 30 17t30 -17z" />
+<glyph unicode="&#xe161;" d="M550 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h450q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-450q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM338 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
+<glyph unicode="&#xe162;" d="M793 1182l9 -9q8 -10 5 -27q-3 -11 -79 -225.5t-78 -221.5l300 1q24 0 32.5 -17.5t-5.5 -35.5q-1 0 -133.5 -155t-267 -312.5t-138.5 -162.5q-12 -15 -26 -15h-9l-9 8q-9 11 -4 32q2 9 42 123.5t79 224.5l39 110h-302q-23 0 -31 19q-10 21 6 41q75 86 209.5 237.5 t228 257t98.5 111.5q9 16 25 16h9z" />
+<glyph unicode="&#xe163;" d="M350 1100h400q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-450q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h450q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400 q0 165 92.5 257.5t257.5 92.5zM938 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
+<glyph unicode="&#xe164;" d="M750 1200h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -10.5 -25t-24.5 10l-109 109l-312 -312q-15 -15 -35.5 -15t-35.5 15l-141 141q-15 15 -15 35.5t15 35.5l312 312l-109 109q-14 14 -10 24.5t25 10.5zM456 900h-156q-41 0 -70.5 -29.5t-29.5 -70.5v-500 q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v148l200 200v-298q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5h300z" />
+<glyph unicode="&#xe165;" d="M600 1186q119 0 227.5 -46.5t187 -125t125 -187t46.5 -227.5t-46.5 -227.5t-125 -187t-187 -125t-227.5 -46.5t-227.5 46.5t-187 125t-125 187t-46.5 227.5t46.5 227.5t125 187t187 125t227.5 46.5zM600 1022q-115 0 -212 -56.5t-153.5 -153.5t-56.5 -212t56.5 -212 t153.5 -153.5t212 -56.5t212 56.5t153.5 153.5t56.5 212t-56.5 212t-153.5 153.5t-212 56.5zM600 794q80 0 137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137t57 137t137 57z" />
+<glyph unicode="&#xe166;" d="M450 1200h200q21 0 35.5 -14.5t14.5 -35.5v-350h245q20 0 25 -11t-9 -26l-383 -426q-14 -15 -33.5 -15t-32.5 15l-379 426q-13 15 -8.5 26t25.5 11h250v350q0 21 14.5 35.5t35.5 14.5zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
+<glyph unicode="&#xe167;" d="M583 1182l378 -435q14 -15 9 -31t-26 -16h-244v-250q0 -20 -17 -35t-39 -15h-200q-20 0 -32 14.5t-12 35.5v250h-250q-20 0 -25.5 16.5t8.5 31.5l383 431q14 16 33.5 17t33.5 -14zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
+<glyph unicode="&#xe168;" d="M396 723l369 369q7 7 17.5 7t17.5 -7l139 -139q7 -8 7 -18.5t-7 -17.5l-525 -525q-7 -8 -17.5 -8t-17.5 8l-292 291q-7 8 -7 18t7 18l139 139q8 7 18.5 7t17.5 -7zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50 h-100z" />
+<glyph unicode="&#xe169;" d="M135 1023l142 142q14 14 35 14t35 -14l77 -77l-212 -212l-77 76q-14 15 -14 36t14 35zM655 855l210 210q14 14 24.5 10t10.5 -25l-2 -599q-1 -20 -15.5 -35t-35.5 -15l-597 -1q-21 0 -25 10.5t10 24.5l208 208l-154 155l212 212zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5 v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
+<glyph unicode="&#xe170;" d="M350 1200l599 -2q20 -1 35 -15.5t15 -35.5l1 -597q0 -21 -10.5 -25t-24.5 10l-208 208l-155 -154l-212 212l155 154l-210 210q-14 14 -10 24.5t25 10.5zM524 512l-76 -77q-15 -14 -36 -14t-35 14l-142 142q-14 14 -14 35t14 35l77 77zM50 300h1000q21 0 35.5 -14.5 t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
+<glyph unicode="&#xe171;" d="M1200 103l-483 276l-314 -399v423h-399l1196 796v-1096zM483 424v-230l683 953z" />
+<glyph unicode="&#xe172;" d="M1100 1000v-850q0 -21 -14.5 -35.5t-35.5 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200z" />
+<glyph unicode="&#xe173;" d="M1100 1000l-2 -149l-299 -299l-95 95q-9 9 -21.5 9t-21.5 -9l-149 -147h-312v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1132 638l106 -106q7 -7 7 -17.5t-7 -17.5l-420 -421q-8 -7 -18 -7 t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l297 297q7 7 17.5 7t17.5 -7z" />
+<glyph unicode="&#xe174;" d="M1100 1000v-269l-103 -103l-134 134q-15 15 -33.5 16.5t-34.5 -12.5l-266 -266h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1202 572l70 -70q15 -15 15 -35.5t-15 -35.5l-131 -131 l131 -131q15 -15 15 -35.5t-15 -35.5l-70 -70q-15 -15 -35.5 -15t-35.5 15l-131 131l-131 -131q-15 -15 -35.5 -15t-35.5 15l-70 70q-15 15 -15 35.5t15 35.5l131 131l-131 131q-15 15 -15 35.5t15 35.5l70 70q15 15 35.5 15t35.5 -15l131 -131l131 131q15 15 35.5 15 t35.5 -15z" />
+<glyph unicode="&#xe175;" d="M1100 1000v-300h-350q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM850 600h100q21 0 35.5 -14.5t14.5 -35.5v-250h150q21 0 25 -10.5t-10 -24.5 l-230 -230q-14 -14 -35 -14t-35 14l-230 230q-14 14 -10 24.5t25 10.5h150v250q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe176;" d="M1100 1000v-400l-165 165q-14 15 -35 15t-35 -15l-263 -265h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM935 565l230 -229q14 -15 10 -25.5t-25 -10.5h-150v-250q0 -20 -14.5 -35 t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35v250h-150q-21 0 -25 10.5t10 25.5l230 229q14 15 35 15t35 -15z" />
+<glyph unicode="&#xe177;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-150h-1200v150q0 21 14.5 35.5t35.5 14.5zM1200 800v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v550h1200zM100 500v-200h400v200h-400z" />
+<glyph unicode="&#xe178;" d="M935 1165l248 -230q14 -14 14 -35t-14 -35l-248 -230q-14 -14 -24.5 -10t-10.5 25v150h-400v200h400v150q0 21 10.5 25t24.5 -10zM200 800h-50q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v-200zM400 800h-100v200h100v-200zM18 435l247 230 q14 14 24.5 10t10.5 -25v-150h400v-200h-400v-150q0 -21 -10.5 -25t-24.5 10l-247 230q-15 14 -15 35t15 35zM900 300h-100v200h100v-200zM1000 500h51q20 0 34.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-34.5 -14.5h-51v200z" />
+<glyph unicode="&#xe179;" d="M862 1073l276 116q25 18 43.5 8t18.5 -41v-1106q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v397q-4 1 -11 5t-24 17.5t-30 29t-24 42t-11 56.5v359q0 31 18.5 65t43.5 52zM550 1200q22 0 34.5 -12.5t14.5 -24.5l1 -13v-450q0 -28 -10.5 -59.5 t-25 -56t-29 -45t-25.5 -31.5l-10 -11v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447q-4 4 -11 11.5t-24 30.5t-30 46t-24 55t-11 60v450q0 2 0.5 5.5t4 12t8.5 15t14.5 12t22.5 5.5q20 0 32.5 -12.5t14.5 -24.5l3 -13v-350h100v350v5.5t2.5 12 t7 15t15 12t25.5 5.5q23 0 35.5 -12.5t13.5 -24.5l1 -13v-350h100v350q0 2 0.5 5.5t3 12t7 15t15 12t24.5 5.5z" />
+<glyph unicode="&#xe180;" d="M1200 1100v-56q-4 0 -11 -0.5t-24 -3t-30 -7.5t-24 -15t-11 -24v-888q0 -22 25 -34.5t50 -13.5l25 -2v-56h-400v56q75 0 87.5 6.5t12.5 43.5v394h-500v-394q0 -37 12.5 -43.5t87.5 -6.5v-56h-400v56q4 0 11 0.5t24 3t30 7.5t24 15t11 24v888q0 22 -25 34.5t-50 13.5 l-25 2v56h400v-56q-75 0 -87.5 -6.5t-12.5 -43.5v-394h500v394q0 37 -12.5 43.5t-87.5 6.5v56h400z" />
+<glyph unicode="&#xe181;" d="M675 1000h375q21 0 35.5 -14.5t14.5 -35.5v-150h-105l-295 -98v98l-200 200h-400l100 100h375zM100 900h300q41 0 70.5 -29.5t29.5 -70.5v-500q0 -41 -29.5 -70.5t-70.5 -29.5h-300q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5zM100 800v-200h300v200 h-300zM1100 535l-400 -133v163l400 133v-163zM100 500v-200h300v200h-300zM1100 398v-248q0 -21 -14.5 -35.5t-35.5 -14.5h-375l-100 -100h-375l-100 100h400l200 200h105z" />
+<glyph unicode="&#xe182;" d="M17 1007l162 162q17 17 40 14t37 -22l139 -194q14 -20 11 -44.5t-20 -41.5l-119 -118q102 -142 228 -268t267 -227l119 118q17 17 42.5 19t44.5 -12l192 -136q19 -14 22.5 -37.5t-13.5 -40.5l-163 -162q-3 -1 -9.5 -1t-29.5 2t-47.5 6t-62.5 14.5t-77.5 26.5t-90 42.5 t-101.5 60t-111 83t-119 108.5q-74 74 -133.5 150.5t-94.5 138.5t-60 119.5t-34.5 100t-15 74.5t-4.5 48z" />
+<glyph unicode="&#xe183;" d="M600 1100q92 0 175 -10.5t141.5 -27t108.5 -36.5t81.5 -40t53.5 -37t31 -27l9 -10v-200q0 -21 -14.5 -33t-34.5 -9l-202 34q-20 3 -34.5 20t-14.5 38v146q-141 24 -300 24t-300 -24v-146q0 -21 -14.5 -38t-34.5 -20l-202 -34q-20 -3 -34.5 9t-14.5 33v200q3 4 9.5 10.5 t31 26t54 37.5t80.5 39.5t109 37.5t141 26.5t175 10.5zM600 795q56 0 97 -9.5t60 -23.5t30 -28t12 -24l1 -10v-50l365 -303q14 -15 24.5 -40t10.5 -45v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v212q0 20 10.5 45t24.5 40l365 303v50 q0 4 1 10.5t12 23t30 29t60 22.5t97 10z" />
+<glyph unicode="&#xe184;" d="M1100 700l-200 -200h-600l-200 200v500h200v-200h200v200h200v-200h200v200h200v-500zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5 t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe185;" d="M700 1100h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-1000h300v1000q0 41 -29.5 70.5t-70.5 29.5zM1100 800h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-700h300v700q0 41 -29.5 70.5t-70.5 29.5zM400 0h-300v400q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-400z " />
+<glyph unicode="&#xe186;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
+<glyph unicode="&#xe187;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 300h-100v200h-100v-200h-100v500h100v-200h100v200h100v-500zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
+<glyph unicode="&#xe188;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-300h200v-100h-300v500h300v-100zM900 700h-200v-300h200v-100h-300v500h300v-100z" />
+<glyph unicode="&#xe189;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 400l-300 150l300 150v-300zM900 550l-300 -150v300z" />
+<glyph unicode="&#xe190;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM900 300h-700v500h700v-500zM800 700h-130q-38 0 -66.5 -43t-28.5 -108t27 -107t68 -42h130v300zM300 700v-300 h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130z" />
+<glyph unicode="&#xe191;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 300h-100v400h-100v100h200v-500z M700 300h-100v100h100v-100z" />
+<glyph unicode="&#xe192;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM300 700h200v-400h-300v500h100v-100zM900 300h-100v400h-100v100h200v-500zM300 600v-200h100v200h-100z M700 300h-100v100h100v-100z" />
+<glyph unicode="&#xe193;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 500l-199 -200h-100v50l199 200v150h-200v100h300v-300zM900 300h-100v400h-100v100h200v-500zM701 300h-100 v100h100v-100z" />
+<glyph unicode="&#xe194;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700h-300v-200h300v-100h-300l-100 100v200l100 100h300v-100z" />
+<glyph unicode="&#xe195;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700v-100l-50 -50l100 -100v-50h-100l-100 100h-150v-100h-100v400h300zM500 700v-100h200v100h-200z" />
+<glyph unicode="&#xe197;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -207t-85 -207t-205 -86.5h-128v250q0 21 -14.5 35.5t-35.5 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-250h-222q-80 0 -136 57.5t-56 136.5q0 69 43 122.5t108 67.5q-2 19 -2 37q0 100 49 185 t134 134t185 49zM525 500h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -244q-13 -16 -32 -16t-32 16l-223 244q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe198;" d="M502 1089q110 0 201 -59.5t135 -156.5q43 15 89 15q121 0 206 -86.5t86 -206.5q0 -99 -60 -181t-150 -110l-378 360q-13 16 -31.5 16t-31.5 -16l-381 -365h-9q-79 0 -135.5 57.5t-56.5 136.5q0 69 43 122.5t108 67.5q-2 19 -2 38q0 100 49 184.5t133.5 134t184.5 49.5z M632 467l223 -228q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5q199 204 223 228q19 19 31.5 19t32.5 -19z" />
+<glyph unicode="&#xe199;" d="M700 100v100h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170l-270 -300h400v-100h-50q-21 0 -35.5 -14.5t-14.5 -35.5v-50h400v50q0 21 -14.5 35.5t-35.5 14.5h-50z" />
+<glyph unicode="&#xe200;" d="M600 1179q94 0 167.5 -56.5t99.5 -145.5q89 -6 150.5 -71.5t61.5 -155.5q0 -61 -29.5 -112.5t-79.5 -82.5q9 -29 9 -55q0 -74 -52.5 -126.5t-126.5 -52.5q-55 0 -100 30v-251q21 0 35.5 -14.5t14.5 -35.5v-50h-300v50q0 21 14.5 35.5t35.5 14.5v251q-45 -30 -100 -30 q-74 0 -126.5 52.5t-52.5 126.5q0 18 4 38q-47 21 -75.5 65t-28.5 97q0 74 52.5 126.5t126.5 52.5q5 0 23 -2q0 2 -1 10t-1 13q0 116 81.5 197.5t197.5 81.5z" />
+<glyph unicode="&#xe201;" d="M1010 1010q111 -111 150.5 -260.5t0 -299t-150.5 -260.5q-83 -83 -191.5 -126.5t-218.5 -43.5t-218.5 43.5t-191.5 126.5q-111 111 -150.5 260.5t0 299t150.5 260.5q83 83 191.5 126.5t218.5 43.5t218.5 -43.5t191.5 -126.5zM476 1065q-4 0 -8 -1q-121 -34 -209.5 -122.5 t-122.5 -209.5q-4 -12 2.5 -23t18.5 -14l36 -9q3 -1 7 -1q23 0 29 22q27 96 98 166q70 71 166 98q11 3 17.5 13.5t3.5 22.5l-9 35q-3 13 -14 19q-7 4 -15 4zM512 920q-4 0 -9 -2q-80 -24 -138.5 -82.5t-82.5 -138.5q-4 -13 2 -24t19 -14l34 -9q4 -1 8 -1q22 0 28 21 q18 58 58.5 98.5t97.5 58.5q12 3 18 13.5t3 21.5l-9 35q-3 12 -14 19q-7 4 -15 4zM719.5 719.5q-49.5 49.5 -119.5 49.5t-119.5 -49.5t-49.5 -119.5t49.5 -119.5t119.5 -49.5t119.5 49.5t49.5 119.5t-49.5 119.5zM855 551q-22 0 -28 -21q-18 -58 -58.5 -98.5t-98.5 -57.5 q-11 -4 -17 -14.5t-3 -21.5l9 -35q3 -12 14 -19q7 -4 15 -4q4 0 9 2q80 24 138.5 82.5t82.5 138.5q4 13 -2.5 24t-18.5 14l-34 9q-4 1 -8 1zM1000 515q-23 0 -29 -22q-27 -96 -98 -166q-70 -71 -166 -98q-11 -3 -17.5 -13.5t-3.5 -22.5l9 -35q3 -13 14 -19q7 -4 15 -4 q4 0 8 1q121 34 209.5 122.5t122.5 209.5q4 12 -2.5 23t-18.5 14l-36 9q-3 1 -7 1z" />
+<glyph unicode="&#xe202;" d="M700 800h300v-380h-180v200h-340v-200h-380v755q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM700 300h162l-212 -212l-212 212h162v200h100v-200zM520 0h-395q-10 0 -17.5 7.5t-7.5 17.5v395zM1000 220v-195q0 -10 -7.5 -17.5t-17.5 -7.5h-195z" />
+<glyph unicode="&#xe203;" d="M700 800h300v-520l-350 350l-550 -550v1095q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM862 200h-162v-200h-100v200h-162l212 212zM480 0h-355q-10 0 -17.5 7.5t-7.5 17.5v55h380v-80zM1000 80v-55q0 -10 -7.5 -17.5t-17.5 -7.5h-155v80h180z" />
+<glyph unicode="&#xe204;" d="M1162 800h-162v-200h100l100 -100h-300v300h-162l212 212zM200 800h200q27 0 40 -2t29.5 -10.5t23.5 -30t7 -57.5h300v-100h-600l-200 -350v450h100q0 36 7 57.5t23.5 30t29.5 10.5t40 2zM800 400h240l-240 -400h-800l300 500h500v-100z" />
+<glyph unicode="&#xe205;" d="M650 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM1000 850v150q41 0 70.5 -29.5t29.5 -70.5v-800 q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-1 0 -20 4l246 246l-326 326v324q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM412 250l-212 -212v162h-200v100h200v162z" />
+<glyph unicode="&#xe206;" d="M450 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM800 850v150q41 0 70.5 -29.5t29.5 -70.5v-500 h-200v-300h200q0 -36 -7 -57.5t-23.5 -30t-29.5 -10.5t-40 -2h-600q-41 0 -70.5 29.5t-29.5 70.5v800q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM1212 250l-212 -212v162h-200v100h200v162z" />
+<glyph unicode="&#xe209;" d="M658 1197l637 -1104q23 -38 7 -65.5t-60 -27.5h-1276q-44 0 -60 27.5t7 65.5l637 1104q22 39 54 39t54 -39zM704 800h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM500 300v-100h200 v100h-200z" />
+<glyph unicode="&#xe210;" d="M425 1100h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM825 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM25 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5zM425 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5 v150q0 10 7.5 17.5t17.5 7.5zM25 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe211;" d="M700 1200h100v-200h-100v-100h350q62 0 86.5 -39.5t-3.5 -94.5l-66 -132q-41 -83 -81 -134h-772q-40 51 -81 134l-66 132q-28 55 -3.5 94.5t86.5 39.5h350v100h-100v200h100v100h200v-100zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100 h-950l138 100h-13q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe212;" d="M600 1300q40 0 68.5 -29.5t28.5 -70.5h-194q0 41 28.5 70.5t68.5 29.5zM443 1100h314q18 -37 18 -75q0 -8 -3 -25h328q41 0 44.5 -16.5t-30.5 -38.5l-175 -145h-678l-178 145q-34 22 -29 38.5t46 16.5h328q-3 17 -3 25q0 38 18 75zM250 700h700q21 0 35.5 -14.5 t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-150v-200l275 -200h-950l275 200v200h-150q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe213;" d="M600 1181q75 0 128 -53t53 -128t-53 -128t-128 -53t-128 53t-53 128t53 128t128 53zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13 l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe214;" d="M600 1300q47 0 92.5 -53.5t71 -123t25.5 -123.5q0 -78 -55.5 -133.5t-133.5 -55.5t-133.5 55.5t-55.5 133.5q0 62 34 143l144 -143l111 111l-163 163q34 26 63 26zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45 zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe215;" d="M600 1200l300 -161v-139h-300q0 -57 18.5 -108t50 -91.5t63 -72t70 -67.5t57.5 -61h-530q-60 83 -90.5 177.5t-30.5 178.5t33 164.5t87.5 139.5t126 96.5t145.5 41.5v-98zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100 h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe216;" d="M600 1300q41 0 70.5 -29.5t29.5 -70.5v-78q46 -26 73 -72t27 -100v-50h-400v50q0 54 27 100t73 72v78q0 41 29.5 70.5t70.5 29.5zM400 800h400q54 0 100 -27t72 -73h-172v-100h200v-100h-200v-100h200v-100h-200v-100h200q0 -83 -58.5 -141.5t-141.5 -58.5h-400 q-83 0 -141.5 58.5t-58.5 141.5v400q0 83 58.5 141.5t141.5 58.5z" />
+<glyph unicode="&#xe218;" d="M150 1100h900q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM125 400h950q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-283l224 -224q13 -13 13 -31.5t-13 -32 t-31.5 -13.5t-31.5 13l-88 88h-524l-87 -88q-13 -13 -32 -13t-32 13.5t-13 32t13 31.5l224 224h-289q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM541 300l-100 -100h324l-100 100h-124z" />
+<glyph unicode="&#xe219;" d="M200 1100h800q83 0 141.5 -58.5t58.5 -141.5v-200h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100v200q0 83 58.5 141.5t141.5 58.5zM100 600h1000q41 0 70.5 -29.5 t29.5 -70.5v-300h-1200v300q0 41 29.5 70.5t70.5 29.5zM300 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200zM1100 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200z" />
+<glyph unicode="&#xe221;" d="M480 1165l682 -683q31 -31 31 -75.5t-31 -75.5l-131 -131h-481l-517 518q-32 31 -32 75.5t32 75.5l295 296q31 31 75.5 31t76.5 -31zM108 794l342 -342l303 304l-341 341zM250 100h800q21 0 35.5 -14.5t14.5 -35.5v-50h-900v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe223;" d="M1057 647l-189 506q-8 19 -27.5 33t-40.5 14h-400q-21 0 -40.5 -14t-27.5 -33l-189 -506q-8 -19 1.5 -33t30.5 -14h625v-150q0 -21 14.5 -35.5t35.5 -14.5t35.5 14.5t14.5 35.5v150h125q21 0 30.5 14t1.5 33zM897 0h-595v50q0 21 14.5 35.5t35.5 14.5h50v50 q0 21 14.5 35.5t35.5 14.5h48v300h200v-300h47q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-50z" />
+<glyph unicode="&#xe224;" d="M900 800h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-375v591l-300 300v84q0 10 7.5 17.5t17.5 7.5h375v-400zM1200 900h-200v200zM400 600h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-650q-10 0 -17.5 7.5t-7.5 17.5v950q0 10 7.5 17.5t17.5 7.5h375v-400zM700 700h-200v200z " />
+<glyph unicode="&#xe225;" d="M484 1095h195q75 0 146 -32.5t124 -86t89.5 -122.5t48.5 -142q18 -14 35 -20q31 -10 64.5 6.5t43.5 48.5q10 34 -15 71q-19 27 -9 43q5 8 12.5 11t19 -1t23.5 -16q41 -44 39 -105q-3 -63 -46 -106.5t-104 -43.5h-62q-7 -55 -35 -117t-56 -100l-39 -234q-3 -20 -20 -34.5 t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l12 70q-49 -14 -91 -14h-195q-24 0 -65 8l-11 -64q-3 -20 -20 -34.5t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l26 157q-84 74 -128 175l-159 53q-19 7 -33 26t-14 40v50q0 21 14.5 35.5t35.5 14.5h124q11 87 56 166l-111 95 q-16 14 -12.5 23.5t24.5 9.5h203q116 101 250 101zM675 1000h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h250q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe226;" d="M641 900l423 247q19 8 42 2.5t37 -21.5l32 -38q14 -15 12.5 -36t-17.5 -34l-139 -120h-390zM50 1100h106q67 0 103 -17t66 -71l102 -212h823q21 0 35.5 -14.5t14.5 -35.5v-50q0 -21 -14 -40t-33 -26l-737 -132q-23 -4 -40 6t-26 25q-42 67 -100 67h-300q-62 0 -106 44 t-44 106v200q0 62 44 106t106 44zM173 928h-80q-19 0 -28 -14t-9 -35v-56q0 -51 42 -51h134q16 0 21.5 8t5.5 24q0 11 -16 45t-27 51q-18 28 -43 28zM550 727q-32 0 -54.5 -22.5t-22.5 -54.5t22.5 -54.5t54.5 -22.5t54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5zM130 389 l152 130q18 19 34 24t31 -3.5t24.5 -17.5t25.5 -28q28 -35 50.5 -51t48.5 -13l63 5l48 -179q13 -61 -3.5 -97.5t-67.5 -79.5l-80 -69q-47 -40 -109 -35.5t-103 51.5l-130 151q-40 47 -35.5 109.5t51.5 102.5zM380 377l-102 -88q-31 -27 2 -65l37 -43q13 -15 27.5 -19.5 t31.5 6.5l61 53q19 16 14 49q-2 20 -12 56t-17 45q-11 12 -19 14t-23 -8z" />
+<glyph unicode="&#xe227;" d="M625 1200h150q10 0 17.5 -7.5t7.5 -17.5v-109q79 -33 131 -87.5t53 -128.5q1 -46 -15 -84.5t-39 -61t-46 -38t-39 -21.5l-17 -6q6 0 15 -1.5t35 -9t50 -17.5t53 -30t50 -45t35.5 -64t14.5 -84q0 -59 -11.5 -105.5t-28.5 -76.5t-44 -51t-49.5 -31.5t-54.5 -16t-49.5 -6.5 t-43.5 -1v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-100v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-175q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v600h-75q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5h175v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h100v75q0 10 7.5 17.5t17.5 7.5zM400 900v-200h263q28 0 48.5 10.5t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-263zM400 500v-200h363q28 0 48.5 10.5 t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-363z" />
+<glyph unicode="&#xe230;" d="M212 1198h780q86 0 147 -61t61 -147v-416q0 -51 -18 -142.5t-36 -157.5l-18 -66q-29 -87 -93.5 -146.5t-146.5 -59.5h-572q-82 0 -147 59t-93 147q-8 28 -20 73t-32 143.5t-20 149.5v416q0 86 61 147t147 61zM600 1045q-70 0 -132.5 -11.5t-105.5 -30.5t-78.5 -41.5 t-57 -45t-36 -41t-20.5 -30.5l-6 -12l156 -243h560l156 243q-2 5 -6 12.5t-20 29.5t-36.5 42t-57 44.5t-79 42t-105 29.5t-132.5 12zM762 703h-157l195 261z" />
+<glyph unicode="&#xe231;" d="M475 1300h150q103 0 189 -86t86 -189v-500q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
+<glyph unicode="&#xe232;" d="M475 1300h96q0 -150 89.5 -239.5t239.5 -89.5v-446q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
+<glyph unicode="&#xe233;" d="M1294 767l-638 -283l-378 170l-78 -60v-224l100 -150v-199l-150 148l-150 -149v200l100 150v250q0 4 -0.5 10.5t0 9.5t1 8t3 8t6.5 6l47 40l-147 65l642 283zM1000 380l-350 -166l-350 166v147l350 -165l350 165v-147z" />
+<glyph unicode="&#xe234;" d="M250 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM650 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM1050 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
+<glyph unicode="&#xe235;" d="M550 1100q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 700q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 300q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
+<glyph unicode="&#xe236;" d="M125 1100h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM125 700h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM125 300h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe237;" d="M350 1200h500q162 0 256 -93.5t94 -256.5v-500q0 -165 -93.5 -257.5t-256.5 -92.5h-500q-165 0 -257.5 92.5t-92.5 257.5v500q0 165 92.5 257.5t257.5 92.5zM900 1000h-600q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h600q41 0 70.5 29.5 t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5zM350 900h500q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-500q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 14.5 35.5t35.5 14.5zM400 800v-200h400v200h-400z" />
+<glyph unicode="&#xe238;" d="M150 1100h1000q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe239;" d="M650 1187q87 -67 118.5 -156t0 -178t-118.5 -155q-87 66 -118.5 155t0 178t118.5 156zM300 800q124 0 212 -88t88 -212q-124 0 -212 88t-88 212zM1000 800q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM300 500q124 0 212 -88t88 -212q-124 0 -212 88t-88 212z M1000 500q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM700 199v-144q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v142q40 -4 43 -4q17 0 57 6z" />
+<glyph unicode="&#xe240;" d="M745 878l69 19q25 6 45 -12l298 -295q11 -11 15 -26.5t-2 -30.5q-5 -14 -18 -23.5t-28 -9.5h-8q1 0 1 -13q0 -29 -2 -56t-8.5 -62t-20 -63t-33 -53t-51 -39t-72.5 -14h-146q-184 0 -184 288q0 24 10 47q-20 4 -62 4t-63 -4q11 -24 11 -47q0 -288 -184 -288h-142 q-48 0 -84.5 21t-56 51t-32 71.5t-16 75t-3.5 68.5q0 13 2 13h-7q-15 0 -27.5 9.5t-18.5 23.5q-6 15 -2 30.5t15 25.5l298 296q20 18 46 11l76 -19q20 -5 30.5 -22.5t5.5 -37.5t-22.5 -31t-37.5 -5l-51 12l-182 -193h891l-182 193l-44 -12q-20 -5 -37.5 6t-22.5 31t6 37.5 t31 22.5z" />
+<glyph unicode="&#xe241;" d="M1200 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM500 450h-25q0 15 -4 24.5t-9 14.5t-17 7.5t-20 3t-25 0.5h-100v-425q0 -11 12.5 -17.5t25.5 -7.5h12v-50h-200v50q50 0 50 25v425h-100q-17 0 -25 -0.5t-20 -3t-17 -7.5t-9 -14.5t-4 -24.5h-25v150h500v-150z" />
+<glyph unicode="&#xe242;" d="M1000 300v50q-25 0 -55 32q-14 14 -25 31t-16 27l-4 11l-289 747h-69l-300 -754q-18 -35 -39 -56q-9 -9 -24.5 -18.5t-26.5 -14.5l-11 -5v-50h273v50q-49 0 -78.5 21.5t-11.5 67.5l69 176h293l61 -166q13 -34 -3.5 -66.5t-55.5 -32.5v-50h312zM412 691l134 342l121 -342 h-255zM1100 150v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5z" />
+<glyph unicode="&#xe243;" d="M50 1200h1100q21 0 35.5 -14.5t14.5 -35.5v-1100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5zM611 1118h-70q-13 0 -18 -12l-299 -753q-17 -32 -35 -51q-18 -18 -56 -34q-12 -5 -12 -18v-50q0 -8 5.5 -14t14.5 -6 h273q8 0 14 6t6 14v50q0 8 -6 14t-14 6q-55 0 -71 23q-10 14 0 39l63 163h266l57 -153q11 -31 -6 -55q-12 -17 -36 -17q-8 0 -14 -6t-6 -14v-50q0 -8 6 -14t14 -6h313q8 0 14 6t6 14v50q0 7 -5.5 13t-13.5 7q-17 0 -42 25q-25 27 -40 63h-1l-288 748q-5 12 -19 12zM639 611 h-197l103 264z" />
+<glyph unicode="&#xe244;" d="M1200 1100h-1200v100h1200v-100zM50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 1000h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM700 900v-300h300v300h-300z" />
+<glyph unicode="&#xe245;" d="M50 1200h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 700h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM700 600v-300h300v300h-300zM1200 0h-1200v100h1200v-100z" />
+<glyph unicode="&#xe246;" d="M50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-350h100v150q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-150h100v-100h-100v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v150h-100v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM700 700v-300h300v300h-300z" />
+<glyph unicode="&#xe247;" d="M100 0h-100v1200h100v-1200zM250 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM300 1000v-300h300v300h-300zM250 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe248;" d="M600 1100h150q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-100h450q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h350v100h-150q-21 0 -35.5 14.5 t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h150v100h100v-100zM400 1000v-300h300v300h-300z" />
+<glyph unicode="&#xe249;" d="M1200 0h-100v1200h100v-1200zM550 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM600 1000v-300h300v300h-300zM50 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe250;" d="M865 565l-494 -494q-23 -23 -41 -23q-14 0 -22 13.5t-8 38.5v1000q0 25 8 38.5t22 13.5q18 0 41 -23l494 -494q14 -14 14 -35t-14 -35z" />
+<glyph unicode="&#xe251;" d="M335 635l494 494q29 29 50 20.5t21 -49.5v-1000q0 -41 -21 -49.5t-50 20.5l-494 494q-14 14 -14 35t14 35z" />
+<glyph unicode="&#xe252;" d="M100 900h1000q41 0 49.5 -21t-20.5 -50l-494 -494q-14 -14 -35 -14t-35 14l-494 494q-29 29 -20.5 50t49.5 21z" />
+<glyph unicode="&#xe253;" d="M635 865l494 -494q29 -29 20.5 -50t-49.5 -21h-1000q-41 0 -49.5 21t20.5 50l494 494q14 14 35 14t35 -14z" />
+<glyph unicode="&#xe254;" d="M700 741v-182l-692 -323v221l413 193l-413 193v221zM1200 0h-800v200h800v-200z" />
+<glyph unicode="&#xe255;" d="M1200 900h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300zM0 700h50q0 21 4 37t9.5 26.5t18 17.5t22 11t28.5 5.5t31 2t37 0.5h100v-550q0 -22 -25 -34.5t-50 -13.5l-25 -2v-100h400v100q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v550h100q25 0 37 -0.5t31 -2 t28.5 -5.5t22 -11t18 -17.5t9.5 -26.5t4 -37h50v300h-800v-300z" />
+<glyph unicode="&#xe256;" d="M800 700h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-100v-550q0 -22 25 -34.5t50 -14.5l25 -1v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v550h-100q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h800v-300zM1100 200h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300z" />
+<glyph unicode="&#xe257;" d="M701 1098h160q16 0 21 -11t-7 -23l-464 -464l464 -464q12 -12 7 -23t-21 -11h-160q-13 0 -23 9l-471 471q-7 8 -7 18t7 18l471 471q10 9 23 9z" />
+<glyph unicode="&#xe258;" d="M339 1098h160q13 0 23 -9l471 -471q7 -8 7 -18t-7 -18l-471 -471q-10 -9 -23 -9h-160q-16 0 -21 11t7 23l464 464l-464 464q-12 12 -7 23t21 11z" />
+<glyph unicode="&#xe259;" d="M1087 882q11 -5 11 -21v-160q0 -13 -9 -23l-471 -471q-8 -7 -18 -7t-18 7l-471 471q-9 10 -9 23v160q0 16 11 21t23 -7l464 -464l464 464q12 12 23 7z" />
+<glyph unicode="&#xe260;" d="M618 993l471 -471q9 -10 9 -23v-160q0 -16 -11 -21t-23 7l-464 464l-464 -464q-12 -12 -23 -7t-11 21v160q0 13 9 23l471 471q8 7 18 7t18 -7z" />
+<glyph unicode="&#xf8ff;" d="M1000 1200q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM450 1000h100q21 0 40 -14t26 -33l79 -194q5 1 16 3q34 6 54 9.5t60 7t65.5 1t61 -10t56.5 -23t42.5 -42t29 -64t5 -92t-19.5 -121.5q-1 -7 -3 -19.5t-11 -50t-20.5 -73t-32.5 -81.5t-46.5 -83t-64 -70 t-82.5 -50q-13 -5 -42 -5t-65.5 2.5t-47.5 2.5q-14 0 -49.5 -3.5t-63 -3.5t-43.5 7q-57 25 -104.5 78.5t-75 111.5t-46.5 112t-26 90l-7 35q-15 63 -18 115t4.5 88.5t26 64t39.5 43.5t52 25.5t58.5 13t62.5 2t59.5 -4.5t55.5 -8l-147 192q-12 18 -5.5 30t27.5 12z" />
+<glyph unicode="&#x1f511;" d="M250 1200h600q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-500l-255 -178q-19 -9 -32 -1t-13 29v650h-150q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM400 1100v-100h300v100h-300z" />
+<glyph unicode="&#x1f6aa;" d="M250 1200h750q39 0 69.5 -40.5t30.5 -84.5v-933l-700 -117v950l600 125h-700v-1000h-100v1025q0 23 15.5 49t34.5 26zM500 525v-100l100 20v100z" />
+</font>
+</defs></svg> \ No newline at end of file
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.ttf b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.ttf
new file mode 100644
index 0000000..1413fc6
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.ttf
Binary files differ
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.woff b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.woff
new file mode 100644
index 0000000..9e61285
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.woff
Binary files differ
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.woff2 b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.woff2
new file mode 100644
index 0000000..64539b5
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.woff2
Binary files differ
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/bootstrap.min.js b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/bootstrap.min.js
new file mode 100644
index 0000000..9bcd2fc
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/bootstrap.min.js
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v3.3.7 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under the MIT license
+ */
+if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",c).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",".dropdown-menu",g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in"),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){document===a.target||this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a(document.createElement("div")).addClass("modal-backdrop "+e).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",a,b)};c.VERSION="3.3.7",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-m<o.top?"bottom":"right"==h&&k.right+l>o.width?"left":"left"==h&&k.left-l<o.left?"right":h,f.removeClass(n).addClass(h)}var p=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(p,h);var q=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",q).emulateTransitionEnd(c.TRANSITION_DURATION):q()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top+=g,b.left+=h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element&&e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);if(this.$element.trigger(g),!g.isDefaultPrevented())return f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=window.SVGElement&&c instanceof window.SVGElement,g=d?{top:0,left:0}:f?null:b.offset(),h={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},i=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,h,i,g)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){
+this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.7",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e<c&&"top";if("bottom"==this.affixed)return null!=c?!(e+this.unpin<=f.top)&&"bottom":!(e+g<=a-d)&&"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&e<=c?"top":null!=d&&i+j>=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/d3.min.js b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/d3.min.js
new file mode 100644
index 0000000..1664873
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/d3.min.js
@@ -0,0 +1,5 @@
+!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}function r(n){return null===n?NaN:+n}function i(n){return!isNaN(n)}function u(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)<0?r=u+1:i=u}return r},right:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)>0?i=u:r=u+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function c(){this._=Object.create(null)}function f(n){return(n+="")===bo||n[0]===_o?_o+n:n}function s(n){return(n+="")[0]===_o?n.slice(1):n}function h(n){return f(n)in this._}function p(n){return(n=f(n))in this._&&delete this._[n]}function g(){var n=[];for(var t in this._)n.push(s(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function y(){this._=Object.create(null)}function m(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=wo.length;r>e;++e){var i=wo[e]+t;if(i in n)return i}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,i=-1,u=r.length;++i<u;)(t=r[i].on)&&t.apply(this,arguments);return n}var e=[],r=new c;return t.on=function(t,i){var u,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,u=e.indexOf(o)).concat(e.slice(u+1)),r.remove(t)),i&&e.push(r.set(t,{on:i})),n)},t}function S(){ao.event.preventDefault()}function k(){for(var n,t=ao.event;n=t.sourceEvent;)t=n;return t}function N(n){for(var t=new _,e=0,r=arguments.length;++e<r;)t[arguments[e]]=w(t);return t.of=function(e,r){return function(i){try{var u=i.sourceEvent=ao.event;i.target=n,ao.event=i,t[i.type].apply(e,r)}finally{ao.event=u}}},t}function E(n){return ko(n,Co),n}function A(n){return"function"==typeof n?n:function(){return No(n,this)}}function C(n){return"function"==typeof n?n:function(){return Eo(n,this)}}function z(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function i(){this.setAttribute(n,t)}function u(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=ao.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?u:i}function L(n){return n.trim().replace(/\s+/g," ")}function q(n){return new RegExp("(?:^|\\s+)"+ao.requote(n)+"(?:\\s+|$)","g")}function T(n){return(n+"").trim().split(/^|\s+/)}function R(n,t){function e(){for(var e=-1;++e<i;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<i;)n[e](this,r)}n=T(n).map(D);var i=n.length;return"function"==typeof t?r:e}function D(n){var t=q(n);return function(e,r){if(i=e.classList)return r?i.add(n):i.remove(n);var i=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(i)||e.setAttribute("class",L(i+" "+n))):e.setAttribute("class",L(i.replace(t," ")))}}function P(n,t,e){function r(){this.style.removeProperty(n)}function i(){this.style.setProperty(n,t,e)}function u(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?u:i}function U(n,t){function e(){delete this[n]}function r(){this[n]=t}function i(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?i:r}function j(n){function t(){var t=this.ownerDocument,e=this.namespaceURI;return e===zo&&t.documentElement.namespaceURI===zo?t.createElement(n):t.createElementNS(e,n)}function e(){return this.ownerDocument.createElementNS(n.space,n.local)}return"function"==typeof n?n:(n=ao.ns.qualify(n)).local?e:t}function F(){var n=this.parentNode;n&&n.removeChild(this)}function H(n){return{__data__:n}}function O(n){return function(){return Ao(this,n)}}function I(n){return arguments.length||(n=e),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function Y(n,t){for(var e=0,r=n.length;r>e;e++)for(var i,u=n[e],o=0,a=u.length;a>o;o++)(i=u[o])&&t(i,o,e);return n}function Z(n){return ko(n,qo),n}function V(n){var t,e;return function(r,i,u){var o,a=n[u].update,l=a.length;for(u!=e&&(e=u,t=0),i>=t&&(t=i+1);!(o=a[t])&&++t<l;);return o}}function X(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function i(){var i=l(t,co(arguments));r.call(this),this.addEventListener(n,this[o]=i,i.$=e),i._=t}function u(){var t,e=new RegExp("^__on([^.]+)"+ao.requote(n)+"$");for(var r in this)if(t=r.match(e)){var i=this[r];this.removeEventListener(t[1],i,i.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),l=$;a>0&&(n=n.slice(0,a));var c=To.get(n);return c&&(n=c,l=B),a?t?i:r:t?b:u}function $(n,t){return function(e){var r=ao.event;ao.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ao.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Do,i="click"+r,u=ao.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ro&&(Ro="onselectstart"in e?!1:x(e.style,"userSelect")),Ro){var o=n(e).style,a=o[Ro];o[Ro]="none"}return function(n){if(u.on(r,null),Ro&&(o[Ro]=a),n){var t=function(){u.on(i,null)};u.on(i,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var i=r.createSVGPoint();if(0>Po){var u=t(n);if(u.scrollX||u.scrollY){r=ao.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Po=!(o.f||o.e),r.remove()}}return Po?(i.x=e.pageX,i.y=e.pageY):(i.x=e.clientX,i.y=e.clientY),i=i.matrixTransform(n.getScreenCTM().inverse()),[i.x,i.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ao.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nn(n){return n>1?0:-1>n?Fo:Math.acos(n)}function tn(n){return n>1?Io:-1>n?-Io:Math.asin(n)}function en(n){return((n=Math.exp(n))-1/n)/2}function rn(n){return((n=Math.exp(n))+1/n)/2}function un(n){return((n=Math.exp(2*n))-1)/(n+1)}function on(n){return(n=Math.sin(n/2))*n}function an(){}function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ln?new ln(n.h,n.s,n.l):_n(""+n,wn,ln):new ln(n,t,e)}function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?u+(o-u)*n/60:180>n?o:240>n?u+(o-u)*(240-n)/60:u}function i(n){return Math.round(255*r(n))}var u,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,u=2*e-o,new mn(i(n+120),i(n),i(n-120))}function fn(n,t,e){return this instanceof fn?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof fn?new fn(n.h,n.c,n.l):n instanceof hn?gn(n.l,n.a,n.b):gn((n=Sn((n=ao.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new fn(n,t,e)}function sn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math.cos(n*=Yo)*t,Math.sin(n)*t)}function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof hn?new hn(n.l,n.a,n.b):n instanceof fn?sn(n.h,n.c,n.l):Sn((n=mn(n)).r,n.g,n.b):new hn(n,t,e)}function pn(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=vn(i)*na,r=vn(r)*ta,u=vn(u)*ea,new mn(yn(3.2404542*i-1.5371385*r-.4985314*u),yn(-.969266*i+1.8760108*r+.041556*u),yn(.0556434*i-.2040259*r+1.0572252*u))}function gn(n,t,e){return n>0?new fn(Math.atan2(e,t)*Zo,Math.sqrt(t*t+e*e),n):new fn(NaN,NaN,n)}function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function yn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mn(n,t,e){return this instanceof mn?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mn?new mn(n.r,n.g,n.b):_n(""+n,mn,cn):new mn(n,t,e)}function Mn(n){return new mn(n>>16,n>>8&255,255&n)}function xn(n){return Mn(n)+""}function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _n(n,t,e){var r,i,u,o=0,a=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Nn(i[0]),Nn(i[1]),Nn(i[2]))}return(u=ua.get(n))?t(u.r,u.g,u.b):(null==n||"#"!==n.charAt(0)||isNaN(u=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&u)>>4,o=o>>4|o,a=240&u,a=a>>4|a,l=15&u,l=l<<4|l):7===n.length&&(o=(16711680&u)>>16,a=(65280&u)>>8,l=255&u)),t(o,a,l))}function wn(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-u,l=(o+u)/2;return a?(i=.5>l?a/(o+u):a/(2-o-u),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=NaN,i=l>0&&1>l?0:r),new ln(r,i,l)}function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761*t+.1804375*e)/na),i=dn((.2126729*n+.7151522*t+.072175*e)/ta),u=dn((.0193339*n+.119192*t+.9503041*e)/ea);return hn(116*i-16,500*(r-i),200*(i-u))}function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function En(n){return"function"==typeof n?n:function(){return n}}function An(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Cn(t,e,n,r)}}function Cn(n,t,e,r){function i(){var n,t=l.status;if(!t&&Ln(l)||t>=200&&300>t||304===t){try{n=e.call(u,l)}catch(r){return void o.error.call(u,r)}o.load.call(u,n)}else o.error.call(u,l)}var u={},o=ao.dispatch("beforesend","progress","load","error"),a={},l=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in l||!/^(http(s)?:)?\/\//.test(n)||(l=new XDomainRequest),"onload"in l?l.onload=l.onerror=i:l.onreadystatechange=function(){l.readyState>3&&i()},l.onprogress=function(n){var t=ao.event;ao.event=n;try{o.progress.call(u,l)}finally{ao.event=t}},u.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",u)},u.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",u):t},u.responseType=function(n){return arguments.length?(c=n,u):c},u.response=function(n){return e=n,u},["get","post"].forEach(function(n){u[n]=function(){return u.send.apply(u,[n].concat(co(arguments)))}}),u.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),l.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),l.setRequestHeader)for(var f in a)l.setRequestHeader(f,a[f]);return null!=t&&l.overrideMimeType&&l.overrideMimeType(t),null!=c&&(l.responseType=c),null!=i&&u.on("error",i).on("load",function(n){i(null,n)}),o.beforesend.call(u,l),l.send(null==r?null:r),u},u.abort=function(){return l.abort(),u},ao.rebind(u,o,"on"),null==r?u:u.get(zn(r))}function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var i=e+t,u={c:n,t:i,n:null};return aa?aa.n=u:oa=u,aa=u,la||(ca=clearTimeout(ca),la=1,fa(Tn)),u}function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(ca),ca=setTimeout(Tn,t)),la=0):(la=1,fa(Tn))}function Rn(){for(var n=Date.now(),t=oa;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null),t=t.n;return n}function Dn(){for(var n,t=oa,e=1/0;t;)t.c?(t.t<e&&(e=t.t),t=(n=t).n):t=n?n.n=t.n:oa=t.n;return aa=n,e}function Pn(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Un(n,t){var e=Math.pow(10,3*xo(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function jn(n){var t=n.decimal,e=n.thousands,r=n.grouping,i=n.currency,u=r&&e?function(n,t){for(var i=n.length,u=[],o=0,a=r[0],l=0;i>0&&a>0&&(l+a+1>t&&(a=Math.max(1,t-l)),u.push(n.substring(i-=a,i+a)),!((l+=a+1)>t));)a=r[o=(o+1)%r.length];return u.reverse().join(e)}:m;return function(n){var e=ha.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",l=e[4]||"",c=e[5],f=+e[6],s=e[7],h=e[8],p=e[9],g=1,v="",d="",y=!1,m=!0;switch(h&&(h=+h.substring(1)),(c||"0"===r&&"="===o)&&(c=r="0",o="="),p){case"n":s=!0,p="g";break;case"%":g=100,d="%",p="f";break;case"p":g=100,d="%",p="r";break;case"b":case"o":case"x":case"X":"#"===l&&(v="0"+p.toLowerCase());case"c":m=!1;case"d":y=!0,h=0;break;case"s":g=-1,p="r"}"$"===l&&(v=i[0],d=i[1]),"r"!=p||h||(p="g"),null!=h&&("g"==p?h=Math.max(1,Math.min(21,h)):"e"!=p&&"f"!=p||(h=Math.max(0,Math.min(20,h)))),p=pa.get(p)||Fn;var M=c&&s;return function(n){var e=d;if(y&&n%1)return"";var i=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>g){var l=ao.formatPrefix(n,h);n=l.scale(n),e=l.symbol+d}else n*=g;n=p(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=m?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!c&&s&&(x=u(x,1/0));var S=v.length+x.length+b.length+(M?0:i.length),k=f>S?new Array(S=f-S+1).join(r):"";return M&&(x=u(k+x,k.length?f-b.length:1/0)),i+=v,n=x+b,("<"===o?i+n+k:">"===o?k+i+n:"^"===o?k.substring(0,S>>=1)+i+n+k.substring(S):i+(M?n:k+n))+e}}}function Fn(n){return n+""}function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function On(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}function i(e){return t(e=n(new va(e-1)),1),e}function u(n,e){return t(n=new va(+n),e),n}function o(n,r,u){var o=i(n),a=[];if(u>1)for(;r>o;)e(o)%u||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{va=Hn;var r=new Hn;return r._=n,o(r,t,e)}finally{va=Date}}n.floor=n,n.round=r,n.ceil=i,n.offset=u,n.range=o;var l=n.utc=In(n);return l.floor=l,l.round=In(r),l.ceil=In(i),l.offset=In(u),l.range=a,n}function In(n){return function(t,e){try{va=Hn;var r=new Hn;return r._=t,n(r,e)._}finally{va=Date}}}function Yn(n){function t(n){function t(t){for(var e,i,u,o=[],a=-1,l=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.slice(l,a)),null!=(i=ya[e=n.charAt(++a)])&&(e=n.charAt(++a)),(u=A[e])&&(e=u(t,null==i?"e"===e?" ":"0":i)),o.push(e),l=a+1);return o.push(n.slice(l,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},i=e(r,n,t,0);if(i!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var u=null!=r.Z&&va!==Hn,o=new(u?Hn:va);return"j"in r?o.setFullYear(r.y,0,r.j):"W"in r||"U"in r?("w"in r||(r.w="W"in r?1:0),o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+(r.Z/100|0),r.M+r.Z%100,r.S,r.L),u?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var i,u,o,a=0,l=t.length,c=e.length;l>a;){if(r>=c)return-1;if(i=t.charCodeAt(a++),37===i){if(o=t.charAt(a++),u=C[o in ya?t.charAt(a++):o],!u||(r=u(n,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){N.lastIndex=0;var r=N.exec(t.slice(e));return r?(n.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,A.c.toString(),t,r)}function l(n,t,r){return e(n,A.x.toString(),t,r)}function c(n,t,r){return e(n,A.X.toString(),t,r)}function f(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var s=n.dateTime,h=n.date,p=n.time,g=n.periods,v=n.days,d=n.shortDays,y=n.months,m=n.shortMonths;t.utc=function(n){function e(n){try{va=Hn;var t=new va;return t._=n,r(t)}finally{va=Date}}var r=t(n);return e.parse=function(n){try{va=Hn;var t=r.parse(n);return t&&t._}finally{va=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ct;var M=ao.map(),x=Vn(v),b=Xn(v),_=Vn(d),w=Xn(d),S=Vn(y),k=Xn(y),N=Vn(m),E=Xn(m);g.forEach(function(n,t){M.set(n.toLowerCase(),t)});var A={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return m[n.getMonth()]},B:function(n){return y[n.getMonth()]},c:t(s),d:function(n,t){return Zn(n.getDate(),t,2)},e:function(n,t){return Zn(n.getDate(),t,2)},H:function(n,t){return Zn(n.getHours(),t,2)},I:function(n,t){return Zn(n.getHours()%12||12,t,2)},j:function(n,t){return Zn(1+ga.dayOfYear(n),t,3)},L:function(n,t){return Zn(n.getMilliseconds(),t,3)},m:function(n,t){return Zn(n.getMonth()+1,t,2)},M:function(n,t){return Zn(n.getMinutes(),t,2)},p:function(n){return g[+(n.getHours()>=12)]},S:function(n,t){return Zn(n.getSeconds(),t,2)},U:function(n,t){return Zn(ga.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Zn(ga.mondayOfYear(n),t,2)},x:t(h),X:t(p),y:function(n,t){return Zn(n.getFullYear()%100,t,2)},Y:function(n,t){return Zn(n.getFullYear()%1e4,t,4)},Z:at,"%":function(){return"%"}},C={a:r,A:i,b:u,B:o,c:a,d:tt,e:tt,H:rt,I:rt,j:et,L:ot,m:nt,M:it,p:f,S:ut,U:Bn,w:$n,W:Wn,x:l,X:c,y:Gn,Y:Jn,Z:Kn,"%":lt};return t}function Zn(n,t,e){var r=0>n?"-":"",i=(r?-n:n)+"",u=i.length;return r+(e>u?new Array(e-u+1).join(t)+i:i)}function Vn(n){return new RegExp("^(?:"+n.map(ao.requote).join("|")+")","i")}function Xn(n){for(var t=new c,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function $n(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Bn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e));return r?(n.U=+r[0],e+r[0].length):-1}function Wn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e));return r?(n.W=+r[0],e+r[0].length):-1}function Jn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Gn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.y=Qn(+r[0]),e+r[0].length):-1}function Kn(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+5):-1}function Qn(n){return n+(n>68?1900:2e3)}function nt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function tt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function et(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function rt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function it(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function ut(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ot(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function at(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=xo(t)/60|0,i=xo(t)%60;return e+Zn(r,"0",2)+Zn(i,"0",2)}function lt(n,t,e){Ma.lastIndex=0;var r=Ma.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ct(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ft(){}function st(n,t,e){var r=e.s=n+t,i=r-n,u=r-i;e.t=n-u+(t-i)}function ht(n,t){n&&wa.hasOwnProperty(n.type)&&wa[n.type](n,t)}function pt(n,t,e){var r,i=-1,u=n.length-e;for(t.lineStart();++i<u;)r=n[i],t.point(r[0],r[1],r[2]);t.lineEnd()}function gt(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)pt(n[e],t,1);t.polygonEnd()}function vt(){function n(n,t){n*=Yo,t=t*Yo/2+Fo/4;var e=n-r,o=e>=0?1:-1,a=o*e,l=Math.cos(t),c=Math.sin(t),f=u*c,s=i*l+f*Math.cos(a),h=f*o*Math.sin(a);ka.add(Math.atan2(h,s)),r=n,i=l,u=c}var t,e,r,i,u;Na.point=function(o,a){Na.point=n,r=(t=o)*Yo,i=Math.cos(a=(e=a)*Yo/2+Fo/4),u=Math.sin(a)},Na.lineEnd=function(){n(t,e)}}function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function yt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function mt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}function wt(n,t){return xo(n[0]-t[0])<Uo&&xo(n[1]-t[1])<Uo}function St(n,t){n*=Yo;var e=Math.cos(t*=Yo);kt(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function kt(n,t,e){++Ea,Ca+=(n-Ca)/Ea,za+=(t-za)/Ea,La+=(e-La)/Ea}function Nt(){function n(n,i){n*=Yo;var u=Math.cos(i*=Yo),o=u*Math.cos(n),a=u*Math.sin(n),l=Math.sin(i),c=Math.atan2(Math.sqrt((c=e*l-r*a)*c+(c=r*o-t*l)*c+(c=t*a-e*o)*c),t*o+e*a+r*l);Aa+=c,qa+=c*(t+(t=o)),Ta+=c*(e+(e=a)),Ra+=c*(r+(r=l)),kt(t,e,r)}var t,e,r;ja.point=function(i,u){i*=Yo;var o=Math.cos(u*=Yo);t=o*Math.cos(i),e=o*Math.sin(i),r=Math.sin(u),ja.point=n,kt(t,e,r)}}function Et(){ja.point=St}function At(){function n(n,t){n*=Yo;var e=Math.cos(t*=Yo),o=e*Math.cos(n),a=e*Math.sin(n),l=Math.sin(t),c=i*l-u*a,f=u*o-r*l,s=r*a-i*o,h=Math.sqrt(c*c+f*f+s*s),p=r*o+i*a+u*l,g=h&&-nn(p)/h,v=Math.atan2(h,p);Da+=g*c,Pa+=g*f,Ua+=g*s,Aa+=v,qa+=v*(r+(r=o)),Ta+=v*(i+(i=a)),Ra+=v*(u+(u=l)),kt(r,i,u)}var t,e,r,i,u;ja.point=function(o,a){t=o,e=a,ja.point=n,o*=Yo;var l=Math.cos(a*=Yo);r=l*Math.cos(o),i=l*Math.sin(o),u=Math.sin(a),kt(r,i,u)},ja.lineEnd=function(){n(t,e),ja.lineEnd=Et,ja.point=St}}function Ct(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function zt(){return!0}function Lt(n,t,e,r,i){var u=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(wt(e,r)){i.lineStart();for(var a=0;t>a;++a)i.point((e=n[a])[0],e[1]);return void i.lineEnd()}var l=new Tt(e,n,null,!0),c=new Tt(e,null,l,!1);l.o=c,u.push(l),o.push(c),l=new Tt(r,n,null,!1),c=new Tt(r,null,l,!0),l.o=c,u.push(l),o.push(c)}}),o.sort(t),qt(u),qt(o),u.length){for(var a=0,l=e,c=o.length;c>a;++a)o[a].e=l=!l;for(var f,s,h=u[0];;){for(var p=h,g=!0;p.v;)if((p=p.n)===h)return;f=p.z,i.lineStart();do{if(p.v=p.o.v=!0,p.e){if(g)for(var a=0,c=f.length;c>a;++a)i.point((s=f[a])[0],s[1]);else r(p.x,p.n.x,1,i);p=p.n}else{if(g){f=p.p.z;for(var a=f.length-1;a>=0;--a)i.point((s=f[a])[0],s[1])}else r(p.x,p.p.x,-1,i);p=p.p}p=p.o,f=p.z,g=!g}while(!p.v);i.lineEnd()}}}function qt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r<t;)i.n=e=n[r],e.p=i,i=e;i.n=e=n[0],e.p=i}}function Tt(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Rt(n,t,e,r){return function(i,u){function o(t,e){var r=i(t,e);n(t=r[0],e=r[1])&&u.point(t,e)}function a(n,t){var e=i(n,t);d.point(e[0],e[1])}function l(){m.point=a,d.lineStart()}function c(){m.point=o,d.lineEnd()}function f(n,t){v.push([n,t]);var e=i(n,t);x.point(e[0],e[1])}function s(){x.lineStart(),v=[]}function h(){f(v[0][0],v[0][1]),x.lineEnd();var n,t=x.clean(),e=M.buffer(),r=e.length;if(v.pop(),g.push(v),v=null,r)if(1&t){n=e[0];var i,r=n.length-1,o=-1;if(r>0){for(b||(u.polygonStart(),b=!0),u.lineStart();++o<r;)u.point((i=n[o])[0],i[1]);u.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),p.push(e.filter(Dt))}var p,g,v,d=t(u),y=i.invert(r[0],r[1]),m={point:o,lineStart:l,lineEnd:c,polygonStart:function(){m.point=f,m.lineStart=s,m.lineEnd=h,p=[],g=[]},polygonEnd:function(){m.point=o,m.lineStart=l,m.lineEnd=c,p=ao.merge(p);var n=Ot(y,g);p.length?(b||(u.polygonStart(),b=!0),Lt(p,Ut,n,e,u)):n&&(b||(u.polygonStart(),b=!0),u.lineStart(),e(null,null,1,u),u.lineEnd()),b&&(u.polygonEnd(),b=!1),p=g=null},sphere:function(){u.polygonStart(),u.lineStart(),e(null,null,1,u),u.lineEnd(),u.polygonEnd()}},M=Pt(),x=t(M),b=!1;return m}}function Dt(n){return n.length>1}function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ut(n,t){return((n=n.x)[0]<0?n[1]-Io-Uo:Io-n[1])-((t=t.x)[0]<0?t[1]-Io-Uo:Io-t[1])}function jt(n){var t,e=NaN,r=NaN,i=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(u,o){var a=u>0?Fo:-Fo,l=xo(u-e);xo(l-Fo)<Uo?(n.point(e,r=(r+o)/2>0?Io:-Io),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(u,r),t=0):i!==a&&l>=Fo&&(xo(e-i)<Uo&&(e-=i*Uo),xo(u-a)<Uo&&(u-=a*Uo),r=Ft(e,r,u,o),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=u,r=o),i=a},lineEnd:function(){n.lineEnd(),e=r=NaN},clean:function(){return 2-t}}}function Ft(n,t,e,r){var i,u,o=Math.sin(n-e);return xo(o)>Uo?Math.atan((Math.sin(t)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(t))*Math.sin(n))/(i*u*o)):(t+r)/2}function Ht(n,t,e,r){var i;if(null==n)i=e*Io,r.point(-Fo,i),r.point(0,i),r.point(Fo,i),r.point(Fo,0),r.point(Fo,-i),r.point(0,-i),r.point(-Fo,-i),r.point(-Fo,0),r.point(-Fo,i);else if(xo(n[0]-t[0])>Uo){var u=n[0]<t[0]?Fo:-Fo;i=e*u/2,r.point(-u,i),r.point(0,i),r.point(u,i)}else r.point(t[0],t[1])}function Ot(n,t){var e=n[0],r=n[1],i=[Math.sin(e),-Math.cos(e),0],u=0,o=0;ka.reset();for(var a=0,l=t.length;l>a;++a){var c=t[a],f=c.length;if(f)for(var s=c[0],h=s[0],p=s[1]/2+Fo/4,g=Math.sin(p),v=Math.cos(p),d=1;;){d===f&&(d=0),n=c[d];var y=n[0],m=n[1]/2+Fo/4,M=Math.sin(m),x=Math.cos(m),b=y-h,_=b>=0?1:-1,w=_*b,S=w>Fo,k=g*M;if(ka.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),u+=S?b+_*Ho:b,S^h>=e^y>=e){var N=mt(dt(s),dt(n));bt(N);var E=mt(i,N);bt(E);var A=(S^b>=0?-1:1)*tn(E[2]);(r>A||r===A&&(N[0]||N[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=y,g=M,v=x,s=n}}return(-Uo>u||Uo>u&&-Uo>ka)^1&o}function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>u}function e(n){var e,u,l,c,f;return{lineStart:function(){c=l=!1,f=1},point:function(s,h){var p,g=[s,h],v=t(s,h),d=o?v?0:i(s,h):v?i(s+(0>s?Fo:-Fo),h):0;if(!e&&(c=l=v)&&n.lineStart(),v!==l&&(p=r(e,g),(wt(e,p)||wt(g,p))&&(g[0]+=Uo,g[1]+=Uo,v=t(g[0],g[1]))),v!==l)f=0,v?(n.lineStart(),p=r(g,e),n.point(p[0],p[1])):(p=r(e,g),n.point(p[0],p[1]),n.lineEnd()),e=p;else if(a&&e&&o^v){var y;d&u||!(y=r(g,e,!0))||(f=0,o?(n.lineStart(),n.point(y[0][0],y[0][1]),n.point(y[1][0],y[1][1]),n.lineEnd()):(n.point(y[1][0],y[1][1]),n.lineEnd(),n.lineStart(),n.point(y[0][0],y[0][1])))}!v||e&&wt(e,g)||n.point(g[0],g[1]),e=g,l=v,u=d},lineEnd:function(){l&&n.lineEnd(),e=null},clean:function(){return f|(c&&l)<<1}}}function r(n,t,e){var r=dt(n),i=dt(t),o=[1,0,0],a=mt(r,i),l=yt(a,a),c=a[0],f=l-c*c;if(!f)return!e&&n;var s=u*l/f,h=-u*c/f,p=mt(o,a),g=xt(o,s),v=xt(a,h);Mt(g,v);var d=p,y=yt(g,d),m=yt(d,d),M=y*y-m*(yt(g,g)-1);if(!(0>M)){var x=Math.sqrt(M),b=xt(d,(-y-x)/m);if(Mt(b,g),b=_t(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],N=t[1];w>S&&(_=w,w=S,S=_);var E=S-w,A=xo(E-Fo)<Uo,C=A||Uo>E;if(!A&&k>N&&(_=k,k=N,N=_),C?A?k+N>0^b[1]<(xo(b[0]-w)<Uo?k:N):k<=b[1]&&b[1]<=N:E>Fo^(w<=b[0]&&b[0]<=S)){var z=xt(d,(-y+x)/m);return Mt(z,g),[b,_t(z)]}}}function i(t,e){var r=o?n:Fo-n,i=0;return-r>t?i|=1:t>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}var u=Math.cos(n),o=u>0,a=xo(u)>Uo,l=ve(n,6*Yo);return Rt(t,e,l,o?[0,-n]:[-Fo,n-Fo])}function Yt(n,t,e,r){return function(i){var u,o=i.a,a=i.b,l=o.x,c=o.y,f=a.x,s=a.y,h=0,p=1,g=f-l,v=s-c;if(u=n-l,g||!(u>0)){if(u/=g,0>g){if(h>u)return;p>u&&(p=u)}else if(g>0){if(u>p)return;u>h&&(h=u)}if(u=e-l,g||!(0>u)){if(u/=g,0>g){if(u>p)return;u>h&&(h=u)}else if(g>0){if(h>u)return;p>u&&(p=u)}if(u=t-c,v||!(u>0)){if(u/=v,0>v){if(h>u)return;p>u&&(p=u)}else if(v>0){if(u>p)return;u>h&&(h=u)}if(u=r-c,v||!(0>u)){if(u/=v,0>v){if(u>p)return;u>h&&(h=u)}else if(v>0){if(h>u)return;p>u&&(p=u)}return h>0&&(i.a={x:l+h*g,y:c+h*v}),1>p&&(i.b={x:l+p*g,y:c+p*v}),i}}}}}}function Zt(n,t,e,r){function i(r,i){return xo(r[0]-n)<Uo?i>0?0:3:xo(r[0]-e)<Uo?i>0?2:1:xo(r[1]-t)<Uo?i>0?1:0:i>0?3:2}function u(n,t){return o(n.x,t.x)}function o(n,t){var e=i(n,1),r=i(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function l(n){for(var t=0,e=d.length,r=n[1],i=0;e>i;++i)for(var u,o=1,a=d[i],l=a.length,c=a[0];l>o;++o)u=a[o],c[1]<=r?u[1]>r&&Q(c,u,n)>0&&++t:u[1]<=r&&Q(c,u,n)<0&&--t,c=u;return 0!==t}function c(u,a,l,c){var f=0,s=0;if(null==u||(f=i(u,l))!==(s=i(a,l))||o(u,a)<0^l>0){do c.point(0===f||3===f?n:e,f>1?r:t);while((f=(f+l+4)%4)!==s)}else c.point(a[0],a[1])}function f(i,u){return i>=n&&e>=i&&u>=t&&r>=u}function s(n,t){f(n,t)&&a.point(n,t)}function h(){C.point=g,d&&d.push(y=[]),S=!0,w=!1,b=_=NaN}function p(){v&&(g(m,M),x&&w&&E.rejoin(),v.push(E.buffer())),C.point=s,w&&a.lineEnd()}function g(n,t){n=Math.max(-Ha,Math.min(Ha,n)),t=Math.max(-Ha,Math.min(Ha,t));var e=f(n,t);if(d&&y.push([n,t]),S)m=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};A(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,y,m,M,x,b,_,w,S,k,N=a,E=Pt(),A=Yt(n,t,e,r),C={point:s,lineStart:h,lineEnd:p,polygonStart:function(){a=E,v=[],d=[],k=!0},polygonEnd:function(){a=N,v=ao.merge(v);var t=l([n,r]),e=k&&t,i=v.length;(e||i)&&(a.polygonStart(),e&&(a.lineStart(),c(null,null,1,a),a.lineEnd()),i&&Lt(v,u,t,c,a),a.polygonEnd()),v=d=y=null}};return C}}function Vt(n){var t=0,e=Fo/3,r=ae(n),i=r(t,e);return i.parallels=function(n){return arguments.length?r(t=n[0]*Fo/180,e=n[1]*Fo/180):[t/Fo*180,e/Fo*180]},i}function Xt(n,t){function e(n,t){var e=Math.sqrt(u-2*i*Math.sin(t))/i;return[e*Math.sin(n*=i),o-e*Math.cos(n)]}var r=Math.sin(n),i=(r+Math.sin(t))/2,u=1+r*(2*i-r),o=Math.sqrt(u)/i;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/i,tn((u-(n*n+e*e)*i*i)/(2*i))]},e}function $t(){function n(n,t){Ia+=i*n-r*t,r=n,i=t}var t,e,r,i;$a.point=function(u,o){$a.point=n,t=r=u,e=i=o},$a.lineEnd=function(){n(t,e)}}function Bt(n,t){Ya>n&&(Ya=n),n>Va&&(Va=n),Za>t&&(Za=t),t>Xa&&(Xa=t)}function Wt(){function n(n,t){o.push("M",n,",",t,u)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function i(){o.push("Z")}var u=Jt(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return u=Jt(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Gt(n,t){Ca+=n,za+=t,++La}function Kt(){function n(n,r){var i=n-t,u=r-e,o=Math.sqrt(i*i+u*u);qa+=o*(t+n)/2,Ta+=o*(e+r)/2,Ra+=o,Gt(t=n,e=r)}var t,e;Wa.point=function(r,i){Wa.point=n,Gt(t=r,e=i)}}function Qt(){Wa.point=Gt}function ne(){function n(n,t){var e=n-r,u=t-i,o=Math.sqrt(e*e+u*u);qa+=o*(r+n)/2,Ta+=o*(i+t)/2,Ra+=o,o=i*n-r*t,Da+=o*(r+n),Pa+=o*(i+t),Ua+=3*o,Gt(r=n,i=t)}var t,e,r,i;Wa.point=function(u,o){Wa.point=n,Gt(t=r=u,e=i=o)},Wa.lineEnd=function(){n(t,e)}}function te(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Ho)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function i(){a.point=t}function u(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:i,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=i,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function ee(n){function t(n){return(a?r:e)(n)}function e(t){return ue(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=NaN,S.point=u,t.lineStart()}function u(e,r){var u=dt([e,r]),o=n(e,r);i(M,x,m,b,_,w,M=o[0],x=o[1],m=e,b=u[0],_=u[1],w=u[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function l(){
+r(),S.point=c,S.lineEnd=f}function c(n,t){u(s=n,h=t),p=M,g=x,v=b,d=_,y=w,S.point=u}function f(){i(M,x,m,b,_,w,p,g,s,v,d,y,a,t),S.lineEnd=o,o()}var s,h,p,g,v,d,y,m,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=l},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function i(t,e,r,a,l,c,f,s,h,p,g,v,d,y){var m=f-t,M=s-e,x=m*m+M*M;if(x>4*u&&d--){var b=a+p,_=l+g,w=c+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),N=xo(xo(w)-1)<Uo||xo(r-h)<Uo?(r+h)/2:Math.atan2(_,b),E=n(N,k),A=E[0],C=E[1],z=A-t,L=C-e,q=M*z-m*L;(q*q/x>u||xo((m*z+M*L)/x-.5)>.3||o>a*p+l*g+c*v)&&(i(t,e,r,a,l,c,A,C,N,b/=S,_/=S,w,d,y),y.point(A,C),i(A,C,N,b,_,w,f,s,h,p,g,v,d,y))}}var u=.5,o=Math.cos(30*Yo),a=16;return t.precision=function(n){return arguments.length?(a=(u=n*n)>0&&16,t):Math.sqrt(u)},t}function re(n){var t=ee(function(t,e){return n([t*Zo,e*Zo])});return function(n){return le(t(n))}}function ie(n){this.stream=n}function ue(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function oe(n){return ae(function(){return n})()}function ae(n){function t(n){return n=a(n[0]*Yo,n[1]*Yo),[n[0]*h+l,c-n[1]*h]}function e(n){return n=a.invert((n[0]-l)/h,(c-n[1])/h),n&&[n[0]*Zo,n[1]*Zo]}function r(){a=Ct(o=se(y,M,x),u);var n=u(v,d);return l=p-n[0]*h,c=g+n[1]*h,i()}function i(){return f&&(f.valid=!1,f=null),t}var u,o,a,l,c,f,s=ee(function(n,t){return n=u(n,t),[n[0]*h+l,c-n[1]*h]}),h=150,p=480,g=250,v=0,d=0,y=0,M=0,x=0,b=Fa,_=m,w=null,S=null;return t.stream=function(n){return f&&(f.valid=!1),f=le(b(o,s(_(n)))),f.valid=!0,f},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Fa):It((w=+n)*Yo),i()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Zt(n[0][0],n[0][1],n[1][0],n[1][1]):m,i()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(p=+n[0],g=+n[1],r()):[p,g]},t.center=function(n){return arguments.length?(v=n[0]%360*Yo,d=n[1]%360*Yo,r()):[v*Zo,d*Zo]},t.rotate=function(n){return arguments.length?(y=n[0]%360*Yo,M=n[1]%360*Yo,x=n.length>2?n[2]%360*Yo:0,r()):[y*Zo,M*Zo,x*Zo]},ao.rebind(t,s,"precision"),function(){return u=n.apply(this,arguments),t.invert=u.invert&&e,r()}}function le(n){return ue(n,function(t,e){n.point(t*Yo,e*Yo)})}function ce(n,t){return[n,t]}function fe(n,t){return[n>Fo?n-Ho:-Fo>n?n+Ho:n,t]}function se(n,t,e){return n?t||e?Ct(pe(n),ge(t,e)):pe(n):t||e?ge(t,e):fe}function he(n){return function(t,e){return t+=n,[t>Fo?t-Ho:-Fo>t?t+Ho:t,e]}}function pe(n){var t=he(n);return t.invert=he(-n),t}function ge(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*r+a*i;return[Math.atan2(l*u-f*o,a*r-c*i),tn(f*u+l*o)]}var r=Math.cos(n),i=Math.sin(n),u=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*u-l*o;return[Math.atan2(l*u+c*o,a*r+f*i),tn(f*r-a*i)]},e}function ve(n,t){var e=Math.cos(n),r=Math.sin(n);return function(i,u,o,a){var l=o*t;null!=i?(i=de(e,i),u=de(e,u),(o>0?u>i:i>u)&&(i+=o*Ho)):(i=n+o*Ho,u=n-.5*l);for(var c,f=i;o>0?f>u:u>f;f-=l)a.point((c=_t([e,-r*Math.cos(f),-r*Math.sin(f)]))[0],c[1])}}function de(n,t){var e=dt(t);e[0]-=n,bt(e);var r=nn(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Uo)%(2*Math.PI)}function ye(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function me(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function Me(n){return n.source}function xe(n){return n.target}function be(n,t,e,r){var i=Math.cos(t),u=Math.sin(t),o=Math.cos(r),a=Math.sin(r),l=i*Math.cos(n),c=i*Math.sin(n),f=o*Math.cos(e),s=o*Math.sin(e),h=2*Math.asin(Math.sqrt(on(r-t)+i*o*on(e-n))),p=1/Math.sin(h),g=h?function(n){var t=Math.sin(n*=h)*p,e=Math.sin(h-n)*p,r=e*l+t*f,i=e*c+t*s,o=e*u+t*a;return[Math.atan2(i,r)*Zo,Math.atan2(o,Math.sqrt(r*r+i*i))*Zo]}:function(){return[n*Zo,t*Zo]};return g.distance=h,g}function _e(){function n(n,i){var u=Math.sin(i*=Yo),o=Math.cos(i),a=xo((n*=Yo)-t),l=Math.cos(a);Ja+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*u-e*o*l)*a),e*u+r*o*l),t=n,e=u,r=o}var t,e,r;Ga.point=function(i,u){t=i*Yo,e=Math.sin(u*=Yo),r=Math.cos(u),Ga.point=n},Ga.lineEnd=function(){Ga.point=Ga.lineEnd=b}}function we(n,t){function e(t,e){var r=Math.cos(t),i=Math.cos(e),u=n(r*i);return[u*i*Math.sin(t),u*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),i=t(r),u=Math.sin(i),o=Math.cos(i);return[Math.atan2(n*u,r*o),Math.asin(r&&e*u/r)]},e}function Se(n,t){function e(n,t){o>0?-Io+Uo>t&&(t=-Io+Uo):t>Io-Uo&&(t=Io-Uo);var e=o/Math.pow(i(t),u);return[e*Math.sin(u*n),o-e*Math.cos(u*n)]}var r=Math.cos(n),i=function(n){return Math.tan(Fo/4+n/2)},u=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(i(t)/i(n)),o=r*Math.pow(i(n),u)/u;return u?(e.invert=function(n,t){var e=o-t,r=K(u)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/u,2*Math.atan(Math.pow(o/r,1/u))-Io]},e):Ne}function ke(n,t){function e(n,t){var e=u-t;return[e*Math.sin(i*n),u-e*Math.cos(i*n)]}var r=Math.cos(n),i=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),u=r/i+n;return xo(i)<Uo?ce:(e.invert=function(n,t){var e=u-t;return[Math.atan2(n,e)/i,u-K(i)*Math.sqrt(n*n+e*e)]},e)}function Ne(n,t){return[n,Math.log(Math.tan(Fo/4+t/2))]}function Ee(n){var t,e=oe(n),r=e.scale,i=e.translate,u=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=i.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=u.apply(e,arguments);if(o===e){if(t=null==n){var a=Fo*r(),l=i();u([[l[0]-a,l[1]-a],[l[0]+a,l[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function Ae(n,t){return[Math.log(Math.tan(Fo/4+t/2)),-n]}function Ce(n){return n[0]}function ze(n){return n[1]}function Le(n){for(var t=n.length,e=[0,1],r=2,i=2;t>i;i++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[i])<=0;)--r;e[r++]=i}return e.slice(0,r)}function qe(n,t){return n[0]-t[0]||n[1]-t[1]}function Te(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Re(n,t,e,r){var i=n[0],u=e[0],o=t[0]-i,a=r[0]-u,l=n[1],c=e[1],f=t[1]-l,s=r[1]-c,h=(a*(l-c)-s*(i-u))/(s*o-a*f);return[i+h*o,l+h*f]}function De(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Pe(){rr(this),this.edge=this.site=this.circle=null}function Ue(n){var t=cl.pop()||new Pe;return t.site=n,t}function je(n){Be(n),ol.remove(n),cl.push(n),rr(n)}function Fe(n){var t=n.circle,e=t.x,r=t.cy,i={x:e,y:r},u=n.P,o=n.N,a=[n];je(n);for(var l=u;l.circle&&xo(e-l.circle.x)<Uo&&xo(r-l.circle.cy)<Uo;)u=l.P,a.unshift(l),je(l),l=u;a.unshift(l),Be(l);for(var c=o;c.circle&&xo(e-c.circle.x)<Uo&&xo(r-c.circle.cy)<Uo;)o=c.N,a.push(c),je(c),c=o;a.push(c),Be(c);var f,s=a.length;for(f=1;s>f;++f)c=a[f],l=a[f-1],nr(c.edge,l.site,c.site,i);l=a[0],c=a[s-1],c.edge=Ke(l.site,c.site,null,i),$e(l),$e(c)}function He(n){for(var t,e,r,i,u=n.x,o=n.y,a=ol._;a;)if(r=Oe(a,o)-u,r>Uo)a=a.L;else{if(i=u-Ie(a,o),!(i>Uo)){r>-Uo?(t=a.P,e=a):i>-Uo?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var l=Ue(n);if(ol.insert(t,l),t||e){if(t===e)return Be(t),e=Ue(t.site),ol.insert(l,e),l.edge=e.edge=Ke(t.site,l.site),$e(t),void $e(e);if(!e)return void(l.edge=Ke(t.site,l.site));Be(t),Be(e);var c=t.site,f=c.x,s=c.y,h=n.x-f,p=n.y-s,g=e.site,v=g.x-f,d=g.y-s,y=2*(h*d-p*v),m=h*h+p*p,M=v*v+d*d,x={x:(d*m-p*M)/y+f,y:(h*M-v*m)/y+s};nr(e.edge,c,g,x),l.edge=Ke(c,n,null,x),e.edge=Ke(n,g,null,x),$e(t),$e(e)}}function Oe(n,t){var e=n.site,r=e.x,i=e.y,u=i-t;if(!u)return r;var o=n.P;if(!o)return-(1/0);e=o.site;var a=e.x,l=e.y,c=l-t;if(!c)return a;var f=a-r,s=1/u-1/c,h=f/c;return s?(-h+Math.sqrt(h*h-2*s*(f*f/(-2*c)-l+c/2+i-u/2)))/s+r:(r+a)/2}function Ie(n,t){var e=n.N;if(e)return Oe(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ye(n){this.site=n,this.edges=[]}function Ze(n){for(var t,e,r,i,u,o,a,l,c,f,s=n[0][0],h=n[1][0],p=n[0][1],g=n[1][1],v=ul,d=v.length;d--;)if(u=v[d],u&&u.prepare())for(a=u.edges,l=a.length,o=0;l>o;)f=a[o].end(),r=f.x,i=f.y,c=a[++o%l].start(),t=c.x,e=c.y,(xo(r-t)>Uo||xo(i-e)>Uo)&&(a.splice(o,0,new tr(Qe(u.site,f,xo(r-s)<Uo&&g-i>Uo?{x:s,y:xo(t-s)<Uo?e:g}:xo(i-g)<Uo&&h-r>Uo?{x:xo(e-g)<Uo?t:h,y:g}:xo(r-h)<Uo&&i-p>Uo?{x:h,y:xo(t-h)<Uo?e:p}:xo(i-p)<Uo&&r-s>Uo?{x:xo(e-p)<Uo?t:s,y:p}:null),u.site,null)),++l)}function Ve(n,t){return t.angle-n.angle}function Xe(){rr(this),this.x=this.y=this.arc=this.site=this.cy=null}function $e(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,i=n.site,u=e.site;if(r!==u){var o=i.x,a=i.y,l=r.x-o,c=r.y-a,f=u.x-o,s=u.y-a,h=2*(l*s-c*f);if(!(h>=-jo)){var p=l*l+c*c,g=f*f+s*s,v=(s*p-c*g)/h,d=(l*g-f*p)/h,s=d+a,y=fl.pop()||new Xe;y.arc=n,y.site=i,y.x=v+o,y.y=s+Math.sqrt(v*v+d*d),y.cy=s,n.circle=y;for(var m=null,M=ll._;M;)if(y.y<M.y||y.y===M.y&&y.x<=M.x){if(!M.L){m=M.P;break}M=M.L}else{if(!M.R){m=M;break}M=M.R}ll.insert(m,y),m||(al=y)}}}}function Be(n){var t=n.circle;t&&(t.P||(al=t.N),ll.remove(t),fl.push(t),rr(t),n.circle=null)}function We(n){for(var t,e=il,r=Yt(n[0][0],n[0][1],n[1][0],n[1][1]),i=e.length;i--;)t=e[i],(!Je(t,n)||!r(t)||xo(t.a.x-t.b.x)<Uo&&xo(t.a.y-t.b.y)<Uo)&&(t.a=t.b=null,e.splice(i,1))}function Je(n,t){var e=n.b;if(e)return!0;var r,i,u=n.a,o=t[0][0],a=t[1][0],l=t[0][1],c=t[1][1],f=n.l,s=n.r,h=f.x,p=f.y,g=s.x,v=s.y,d=(h+g)/2,y=(p+v)/2;if(v===p){if(o>d||d>=a)return;if(h>g){if(u){if(u.y>=c)return}else u={x:d,y:l};e={x:d,y:c}}else{if(u){if(u.y<l)return}else u={x:d,y:c};e={x:d,y:l}}}else if(r=(h-g)/(v-p),i=y-r*d,-1>r||r>1)if(h>g){if(u){if(u.y>=c)return}else u={x:(l-i)/r,y:l};e={x:(c-i)/r,y:c}}else{if(u){if(u.y<l)return}else u={x:(c-i)/r,y:c};e={x:(l-i)/r,y:l}}else if(v>p){if(u){if(u.x>=a)return}else u={x:o,y:r*o+i};e={x:a,y:r*a+i}}else{if(u){if(u.x<o)return}else u={x:a,y:r*a+i};e={x:o,y:r*o+i}}return n.a=u,n.b=e,!0}function Ge(n,t){this.l=n,this.r=t,this.a=this.b=null}function Ke(n,t,e,r){var i=new Ge(n,t);return il.push(i),e&&nr(i,n,t,e),r&&nr(i,t,n,r),ul[n.i].edges.push(new tr(i,n,t)),ul[t.i].edges.push(new tr(i,t,n)),i}function Qe(n,t,e){var r=new Ge(n,null);return r.a=t,r.b=e,il.push(r),r}function nr(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function tr(n,t,e){var r=n.a,i=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(i.x-r.x,r.y-i.y):Math.atan2(r.x-i.x,i.y-r.y)}function er(){this._=null}function rr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function ir(n,t){var e=t,r=t.R,i=e.U;i?i.L===e?i.L=r:i.R=r:n._=r,r.U=i,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function ur(n,t){var e=t,r=t.L,i=e.U;i?i.L===e?i.L=r:i.R=r:n._=r,r.U=i,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function or(n){for(;n.L;)n=n.L;return n}function ar(n,t){var e,r,i,u=n.sort(lr).pop();for(il=[],ul=new Array(n.length),ol=new er,ll=new er;;)if(i=al,u&&(!i||u.y<i.y||u.y===i.y&&u.x<i.x))u.x===e&&u.y===r||(ul[u.i]=new Ye(u),He(u),e=u.x,r=u.y),u=n.pop();else{if(!i)break;Fe(i.arc)}t&&(We(t),Ze(t));var o={cells:ul,edges:il};return ol=ll=il=ul=null,o}function lr(n,t){return t.y-n.y||t.x-n.x}function cr(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function fr(n){return n.x}function sr(n){return n.y}function hr(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function pr(n,t,e,r,i,u){if(!n(t,e,r,i,u)){var o=.5*(e+i),a=.5*(r+u),l=t.nodes;l[0]&&pr(n,l[0],e,r,o,a),l[1]&&pr(n,l[1],o,r,i,a),l[2]&&pr(n,l[2],e,a,o,u),l[3]&&pr(n,l[3],o,a,i,u)}}function gr(n,t,e,r,i,u,o){var a,l=1/0;return function c(n,f,s,h,p){if(!(f>u||s>o||r>h||i>p)){if(g=n.point){var g,v=t-n.x,d=e-n.y,y=v*v+d*d;if(l>y){var m=Math.sqrt(l=y);r=t-m,i=e-m,u=t+m,o=e+m,a=g}}for(var M=n.nodes,x=.5*(f+h),b=.5*(s+p),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:c(n,f,s,x,b);break;case 1:c(n,x,s,h,b);break;case 2:c(n,f,b,x,p);break;case 3:c(n,x,b,h,p)}}}(n,r,i,u,o),a}function vr(n,t){n=ao.rgb(n),t=ao.rgb(t);var e=n.r,r=n.g,i=n.b,u=t.r-e,o=t.g-r,a=t.b-i;return function(n){return"#"+bn(Math.round(e+u*n))+bn(Math.round(r+o*n))+bn(Math.round(i+a*n))}}function dr(n,t){var e,r={},i={};for(e in n)e in t?r[e]=Mr(n[e],t[e]):i[e]=n[e];for(e in t)e in n||(i[e]=t[e]);return function(n){for(e in r)i[e]=r[e](n);return i}}function yr(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function mr(n,t){var e,r,i,u=hl.lastIndex=pl.lastIndex=0,o=-1,a=[],l=[];for(n+="",t+="";(e=hl.exec(n))&&(r=pl.exec(t));)(i=r.index)>u&&(i=t.slice(u,i),a[o]?a[o]+=i:a[++o]=i),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,l.push({i:o,x:yr(e,r)})),u=pl.lastIndex;return u<t.length&&(i=t.slice(u),a[o]?a[o]+=i:a[++o]=i),a.length<2?l[0]?(t=l[0].x,function(n){return t(n)+""}):function(){return t}:(t=l.length,function(n){for(var e,r=0;t>r;++r)a[(e=l[r]).i]=e.x(n);return a.join("")})}function Mr(n,t){for(var e,r=ao.interpolators.length;--r>=0&&!(e=ao.interpolators[r](n,t)););return e}function xr(n,t){var e,r=[],i=[],u=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(Mr(n[e],t[e]));for(;u>e;++e)i[e]=n[e];for(;o>e;++e)i[e]=t[e];return function(n){for(e=0;a>e;++e)i[e]=r[e](n);return i}}function br(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function _r(n){return function(t){return 1-n(1-t)}}function wr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function Sr(n){return n*n}function kr(n){return n*n*n}function Nr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Er(n){return function(t){return Math.pow(t,n)}}function Ar(n){return 1-Math.cos(n*Io)}function Cr(n){return Math.pow(2,10*(n-1))}function zr(n){return 1-Math.sqrt(1-n*n)}function Lr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Ho*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Ho/t)}}function qr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Tr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=ao.hcl(n),t=ao.hcl(t);var e=n.h,r=n.c,i=n.l,u=t.h-e,o=t.c-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return sn(e+u*n,r+o*n,i+a*n)+""}}function Dr(n,t){n=ao.hsl(n),t=ao.hsl(t);var e=n.h,r=n.s,i=n.l,u=t.h-e,o=t.s-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return cn(e+u*n,r+o*n,i+a*n)+""}}function Pr(n,t){n=ao.lab(n),t=ao.lab(t);var e=n.l,r=n.a,i=n.b,u=t.l-e,o=t.a-r,a=t.b-i;return function(n){return pn(e+u*n,r+o*n,i+a*n)+""}}function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function jr(n){var t=[n.a,n.b],e=[n.c,n.d],r=Hr(t),i=Fr(t,e),u=Hr(Or(e,t,-i))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,i*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Zo,this.translate=[n.e,n.f],this.scale=[r,u],this.skew=u?Math.atan2(i,u)*Zo:0}function Fr(n,t){return n[0]*t[0]+n[1]*t[1]}function Hr(n){var t=Math.sqrt(Fr(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Or(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Ir(n){return n.length?n.pop()+",":""}function Yr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push("translate(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else(t[0]||t[1])&&e.push("translate("+t+")")}function Zr(n,t,e,r){n!==t?(n-t>180?t+=360:t-n>180&&(n+=360),r.push({i:e.push(Ir(e)+"rotate(",null,")")-2,x:yr(n,t)})):t&&e.push(Ir(e)+"rotate("+t+")")}function Vr(n,t,e,r){n!==t?r.push({i:e.push(Ir(e)+"skewX(",null,")")-2,x:yr(n,t)}):t&&e.push(Ir(e)+"skewX("+t+")")}function Xr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push(Ir(e)+"scale(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else 1===t[0]&&1===t[1]||e.push(Ir(e)+"scale("+t+")")}function $r(n,t){var e=[],r=[];return n=ao.transform(n),t=ao.transform(t),Yr(n.translate,t.translate,e,r),Zr(n.rotate,t.rotate,e,r),Vr(n.skew,t.skew,e,r),Xr(n.scale,t.scale,e,r),n=t=null,function(n){for(var t,i=-1,u=r.length;++i<u;)e[(t=r[i]).i]=t.x(n);return e.join("")}}function Br(n,t){return t=(t-=n=+n)||1/t,function(e){return(e-n)/t}}function Wr(n,t){return t=(t-=n=+n)||1/t,function(e){return Math.max(0,Math.min(1,(e-n)/t))}}function Jr(n){for(var t=n.source,e=n.target,r=Kr(t,e),i=[t];t!==r;)t=t.parent,i.push(t);for(var u=i.length;e!==r;)i.splice(u,0,e),e=e.parent;return i}function Gr(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Kr(n,t){if(n===t)return n;for(var e=Gr(n),r=Gr(t),i=e.pop(),u=r.pop(),o=null;i===u;)o=i,i=e.pop(),u=r.pop();return o}function Qr(n){n.fixed|=2}function ni(n){n.fixed&=-7}function ti(n){n.fixed|=4,n.px=n.x,n.py=n.y}function ei(n){n.fixed&=-5}function ri(n,t,e){var r=0,i=0;if(n.charge=0,!n.leaf)for(var u,o=n.nodes,a=o.length,l=-1;++l<a;)u=o[l],null!=u&&(ri(u,t,e),n.charge+=u.charge,r+=u.charge*u.cx,i+=u.charge*u.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var c=t*e[n.point.index];n.charge+=n.pointCharge=c,r+=c*n.point.x,i+=c*n.point.y}n.cx=r/n.charge,n.cy=i/n.charge}function ii(n,t){return ao.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=fi,n}function ui(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(i=n.children)&&(r=i.length))for(var r,i;--r>=0;)e.push(i[r])}function oi(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(u=n.children)&&(i=u.length))for(var i,u,o=-1;++o<i;)e.push(u[o]);for(;null!=(n=r.pop());)t(n)}function ai(n){return n.children}function li(n){return n.value}function ci(n,t){return t.value-n.value}function fi(n){return ao.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function si(n){return n.x}function hi(n){return n.y}function pi(n,t,e){n.y0=t,n.y=e}function gi(n){return ao.range(n.length)}function vi(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function di(n){for(var t,e=1,r=0,i=n[0][1],u=n.length;u>e;++e)(t=n[e][1])>i&&(r=e,i=t);return r}function yi(n){return n.reduce(mi,0)}function mi(n,t){return n+t[1]}function Mi(n,t){return xi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function xi(n,t){for(var e=-1,r=+n[0],i=(n[1]-r)/t,u=[];++e<=t;)u[e]=i*e+r;return u}function bi(n){return[ao.min(n),ao.max(n)]}function _i(n,t){return n.value-t.value}function wi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Si(n,t){n._pack_next=t,t._pack_prev=n}function ki(n,t){var e=t.x-n.x,r=t.y-n.y,i=n.r+t.r;return.999*i*i>e*e+r*r}function Ni(n){function t(n){f=Math.min(n.x-n.r,f),s=Math.max(n.x+n.r,s),h=Math.min(n.y-n.r,h),p=Math.max(n.y+n.r,p)}if((e=n.children)&&(c=e.length)){var e,r,i,u,o,a,l,c,f=1/0,s=-(1/0),h=1/0,p=-(1/0);if(e.forEach(Ei),r=e[0],r.x=-r.r,r.y=0,t(r),c>1&&(i=e[1],i.x=i.r,i.y=0,t(i),c>2))for(u=e[2],zi(r,i,u),t(u),wi(r,u),r._pack_prev=u,wi(u,i),i=r._pack_next,o=3;c>o;o++){zi(r,i,u=e[o]);var g=0,v=1,d=1;for(a=i._pack_next;a!==i;a=a._pack_next,v++)if(ki(a,u)){g=1;break}if(1==g)for(l=r._pack_prev;l!==a._pack_prev&&!ki(l,u);l=l._pack_prev,d++);g?(d>v||v==d&&i.r<r.r?Si(r,i=a):Si(r=l,i),o--):(wi(r,u),i=u,t(u))}var y=(f+s)/2,m=(h+p)/2,M=0;for(o=0;c>o;o++)u=e[o],u.x-=y,u.y-=m,M=Math.max(M,u.r+Math.sqrt(u.x*u.x+u.y*u.y));n.r=M,e.forEach(Ai)}}function Ei(n){n._pack_next=n._pack_prev=n}function Ai(n){delete n._pack_next,delete n._pack_prev}function Ci(n,t,e,r){var i=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,i)for(var u=-1,o=i.length;++u<o;)Ci(i[u],t,e,r)}function zi(n,t,e){var r=n.r+e.r,i=t.x-n.x,u=t.y-n.y;if(r&&(i||u)){var o=t.r+e.r,a=i*i+u*u;o*=o,r*=r;var l=.5+(r-o)/(2*a),c=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+l*i+c*u,e.y=n.y+l*u-c*i}else e.x=n.x+r,e.y=n.y}function Li(n,t){return n.parent==t.parent?1:2}function qi(n){var t=n.children;return t.length?t[0]:n.t}function Ti(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function Ri(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function Di(n){for(var t,e=0,r=0,i=n.children,u=i.length;--u>=0;)t=i[u],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Pi(n,t,e){return n.a.parent===t.parent?n.a:e}function Ui(n){return 1+ao.max(n,function(n){return n.y})}function ji(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Fi(n){var t=n.children;return t&&t.length?Fi(t[0]):n}function Hi(n){var t,e=n.children;return e&&(t=e.length)?Hi(e[t-1]):n}function Oi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Ii(n,t){var e=n.x+t[3],r=n.y+t[0],i=n.dx-t[1]-t[3],u=n.dy-t[0]-t[2];return 0>i&&(e+=i/2,i=0),0>u&&(r+=u/2,u=0),{x:e,y:r,dx:i,dy:u}}function Yi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Zi(n){return n.rangeExtent?n.rangeExtent():Yi(n.range())}function Vi(n,t,e,r){var i=e(n[0],n[1]),u=r(t[0],t[1]);return function(n){return u(i(n))}}function Xi(n,t){var e,r=0,i=n.length-1,u=n[r],o=n[i];return u>o&&(e=r,r=i,i=e,e=u,u=o,o=e),n[r]=t.floor(u),n[i]=t.ceil(o),n}function $i(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:Sl}function Bi(n,t,e,r){var i=[],u=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)i.push(e(n[o-1],n[o])),u.push(r(t[o-1],t[o]));return function(t){var e=ao.bisect(n,t,1,a)-1;return u[e](i[e](t))}}function Wi(n,t,e,r){function i(){var i=Math.min(n.length,t.length)>2?Bi:Vi,l=r?Wr:Br;return o=i(n,t,l,e),a=i(t,n,l,Mr),u}function u(n){return o(n)}var o,a;return u.invert=function(n){return a(n)},u.domain=function(t){return arguments.length?(n=t.map(Number),i()):n},u.range=function(n){return arguments.length?(t=n,i()):t},u.rangeRound=function(n){return u.range(n).interpolate(Ur)},u.clamp=function(n){return arguments.length?(r=n,i()):r},u.interpolate=function(n){return arguments.length?(e=n,i()):e},u.ticks=function(t){return Qi(n,t)},u.tickFormat=function(t,e){return nu(n,t,e)},u.nice=function(t){return Gi(n,t),i()},u.copy=function(){return Wi(n,t,e,r)},i()}function Ji(n,t){return ao.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Gi(n,t){return Xi(n,$i(Ki(n,t)[2])),Xi(n,$i(Ki(n,t)[2])),n}function Ki(n,t){null==t&&(t=10);var e=Yi(n),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),u=t/r*i;return.15>=u?i*=10:.35>=u?i*=5:.75>=u&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function Qi(n,t){return ao.range.apply(ao,Ki(n,t))}function nu(n,t,e){var r=Ki(n,t);if(e){var i=ha.exec(e);if(i.shift(),"s"===i[8]){var u=ao.formatPrefix(Math.max(xo(r[0]),xo(r[1])));return i[7]||(i[7]="."+tu(u.scale(r[2]))),i[8]="f",e=ao.format(i.join("")),function(n){return e(u.scale(n))+u.symbol}}i[7]||(i[7]="."+eu(i[8],r)),e=i.join("")}else e=",."+tu(r[2])+"f";return ao.format(e)}function tu(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function eu(n,t){var e=tu(t[2]);return n in kl?Math.abs(e-tu(Math.max(xo(t[0]),xo(t[1]))))+ +("e"!==n):e-2*("%"===n)}function ru(n,t,e,r){function i(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function u(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(i(t))}return o.invert=function(t){return u(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(i)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(i)),o):t},o.nice=function(){var t=Xi(r.map(i),e?Math:El);return n.domain(t),r=t.map(u),o},o.ticks=function(){var n=Yi(r),o=[],a=n[0],l=n[1],c=Math.floor(i(a)),f=Math.ceil(i(l)),s=t%1?2:t;if(isFinite(f-c)){if(e){for(;f>c;c++)for(var h=1;s>h;h++)o.push(u(c)*h);o.push(u(c))}else for(o.push(u(c));c++<f;)for(var h=s-1;h>0;h--)o.push(u(c)*h);for(c=0;o[c]<a;c++);for(f=o.length;o[f-1]>l;f--);o=o.slice(c,f)}return o},o.tickFormat=function(n,e){if(!arguments.length)return Nl;arguments.length<2?e=Nl:"function"!=typeof e&&(e=ao.format(e));var r=Math.max(1,t*n/o.ticks().length);return function(n){var o=n/u(Math.round(i(n)));return t-.5>o*t&&(o*=t),r>=o?e(n):""}},o.copy=function(){return ru(n.copy(),t,e,r)},Ji(o,n)}function iu(n,t,e){function r(t){return n(i(t))}var i=uu(t),u=uu(1/t);return r.invert=function(t){return u(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(i)),r):e},r.ticks=function(n){return Qi(e,n)},r.tickFormat=function(n,t){return nu(e,n,t)},r.nice=function(n){return r.domain(Gi(e,n))},r.exponent=function(o){return arguments.length?(i=uu(t=o),u=uu(1/t),n.domain(e.map(i)),r):t},r.copy=function(){return iu(n.copy(),t,e)},Ji(r,n)}function uu(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ou(n,t){function e(e){return u[((i.get(e)||("range"===t.t?i.set(e,n.push(e)):NaN))-1)%u.length]}function r(t,e){return ao.range(n.length).map(function(n){return t+e*n})}var i,u,o;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new c;for(var u,o=-1,a=r.length;++o<a;)i.has(u=r[o])||i.set(u,n.push(u));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(u=n,o=0,t={t:"range",a:arguments},e):u},e.rangePoints=function(i,a){arguments.length<2&&(a=0);var l=i[0],c=i[1],f=n.length<2?(l=(l+c)/2,0):(c-l)/(n.length-1+a);return u=r(l+f*a/2,f),o=0,t={t:"rangePoints",a:arguments},e},e.rangeRoundPoints=function(i,a){arguments.length<2&&(a=0);var l=i[0],c=i[1],f=n.length<2?(l=c=Math.round((l+c)/2),0):(c-l)/(n.length-1+a)|0;return u=r(l+Math.round(f*a/2+(c-l-(n.length-1+a)*f)/2),f),o=0,t={t:"rangeRoundPoints",a:arguments},e},e.rangeBands=function(i,a,l){arguments.length<2&&(a=0),arguments.length<3&&(l=a);var c=i[1]<i[0],f=i[c-0],s=i[1-c],h=(s-f)/(n.length-a+2*l);return u=r(f+h*l,h),c&&u.reverse(),o=h*(1-a),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(i,a,l){arguments.length<2&&(a=0),arguments.length<3&&(l=a);var c=i[1]<i[0],f=i[c-0],s=i[1-c],h=Math.floor((s-f)/(n.length-a+2*l));return u=r(f+Math.round((s-f-(n.length-a)*h)/2),h),c&&u.reverse(),o=Math.round(h*(1-a)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return o},e.rangeExtent=function(){return Yi(t.a[0])},e.copy=function(){return ou(n,t)},e.domain(n)}function au(n,t){function u(){var e=0,r=t.length;for(a=[];++e<r;)a[e-1]=ao.quantile(n,e/r);return o}function o(n){return isNaN(n=+n)?void 0:t[ao.bisect(a,n)]}var a;return o.domain=function(t){return arguments.length?(n=t.map(r).filter(i).sort(e),u()):n},o.range=function(n){return arguments.length?(t=n,u()):t},o.quantiles=function(){return a},o.invertExtent=function(e){return e=t.indexOf(e),0>e?[NaN,NaN]:[e>0?a[e-1]:n[0],e<a.length?a[e]:n[n.length-1]]},o.copy=function(){return au(n,t)},u()}function lu(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(u*(t-n))))]}function i(){return u=e.length/(t-n),o=e.length-1,r}var u,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],i()):[n,t]},r.range=function(n){return arguments.length?(e=n,i()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?NaN:t/u+n,[t,t+1/u]},r.copy=function(){return lu(n,t,e)},i()}function cu(n,t){function e(e){return e>=e?t[ao.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return cu(n,t)},e}function fu(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Qi(n,t)},t.tickFormat=function(t,e){return nu(n,t,e)},t.copy=function(){return fu(n)},t}function su(){return 0}function hu(n){return n.innerRadius}function pu(n){return n.outerRadius}function gu(n){return n.startAngle}function vu(n){return n.endAngle}function du(n){return n&&n.padAngle}function yu(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function mu(n,t,e,r,i){var u=n[0]-t[0],o=n[1]-t[1],a=(i?r:-r)/Math.sqrt(u*u+o*o),l=a*o,c=-a*u,f=n[0]+l,s=n[1]+c,h=t[0]+l,p=t[1]+c,g=(f+h)/2,v=(s+p)/2,d=h-f,y=p-s,m=d*d+y*y,M=e-r,x=f*p-h*s,b=(0>y?-1:1)*Math.sqrt(Math.max(0,M*M*m-x*x)),_=(x*y-d*b)/m,w=(-x*d-y*b)/m,S=(x*y+d*b)/m,k=(-x*d+y*b)/m,N=_-g,E=w-v,A=S-g,C=k-v;return N*N+E*E>A*A+C*C&&(_=S,w=k),[[_-l,w-c],[_*e/M,w*e/M]]}function Mu(n){function t(t){function o(){c.push("M",u(n(f),a))}for(var l,c=[],f=[],s=-1,h=t.length,p=En(e),g=En(r);++s<h;)i.call(this,l=t[s],s)?f.push([+p.call(this,l,s),+g.call(this,l,s)]):f.length&&(o(),f=[]);return f.length&&o(),c.length?c.join(""):null}var e=Ce,r=ze,i=zt,u=xu,o=u.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(i=n,t):i},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?u=n:(u=Tl.get(n)||xu).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function xu(n){return n.length>1?n.join("L"):n+"Z"}function bu(n){return n.join("L")+"Z"}function _u(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&i.push("H",r[0]),i.join("")}function wu(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("V",(r=n[t])[1],"H",r[0]);return i.join("")}function Su(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("H",(r=n[t])[0],"V",r[1]);return i.join("")}function ku(n,t){return n.length<4?xu(n):n[1]+Au(n.slice(1,-1),Cu(n,t))}function Nu(n,t){return n.length<3?bu(n):n[0]+Au((n.push(n[0]),n),Cu([n[n.length-2]].concat(n,[n[1]]),t))}function Eu(n,t){return n.length<3?xu(n):n[0]+Au(n,Cu(n,t))}function Au(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return xu(n);var e=n.length!=t.length,r="",i=n[0],u=n[1],o=t[0],a=o,l=1;if(e&&(r+="Q"+(u[0]-2*o[0]/3)+","+(u[1]-2*o[1]/3)+","+u[0]+","+u[1],i=n[1],l=2),t.length>1){a=t[1],u=n[l],l++,r+="C"+(i[0]+o[0])+","+(i[1]+o[1])+","+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1];for(var c=2;c<t.length;c++,l++)u=n[l],a=t[c],r+="S"+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1]}if(e){var f=n[l];r+="Q"+(u[0]+2*a[0]/3)+","+(u[1]+2*a[1]/3)+","+f[0]+","+f[1]}return r}function Cu(n,t){for(var e,r=[],i=(1-t)/2,u=n[0],o=n[1],a=1,l=n.length;++a<l;)e=u,u=o,o=n[a],r.push([i*(o[0]-e[0]),i*(o[1]-e[1])]);return r}function zu(n){if(n.length<3)return xu(n);var t=1,e=n.length,r=n[0],i=r[0],u=r[1],o=[i,i,i,(r=n[1])[0]],a=[u,u,u,r[1]],l=[i,",",u,"L",Ru(Pl,o),",",Ru(Pl,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Du(l,o,a);return n.pop(),l.push("L",r),l.join("")}function Lu(n){if(n.length<4)return xu(n);for(var t,e=[],r=-1,i=n.length,u=[0],o=[0];++r<3;)t=n[r],u.push(t[0]),o.push(t[1]);for(e.push(Ru(Pl,u)+","+Ru(Pl,o)),--r;++r<i;)t=n[r],u.shift(),u.push(t[0]),o.shift(),o.push(t[1]),Du(e,u,o);return e.join("")}function qu(n){for(var t,e,r=-1,i=n.length,u=i+4,o=[],a=[];++r<4;)e=n[r%i],o.push(e[0]),a.push(e[1]);for(t=[Ru(Pl,o),",",Ru(Pl,a)],--r;++r<u;)e=n[r%i],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Du(t,o,a);return t.join("")}function Tu(n,t){var e=n.length-1;if(e)for(var r,i,u=n[0][0],o=n[0][1],a=n[e][0]-u,l=n[e][1]-o,c=-1;++c<=e;)r=n[c],i=c/e,r[0]=t*r[0]+(1-t)*(u+i*a),r[1]=t*r[1]+(1-t)*(o+i*l);return zu(n)}function Ru(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Du(n,t,e){n.push("C",Ru(Rl,t),",",Ru(Rl,e),",",Ru(Dl,t),",",Ru(Dl,e),",",Ru(Pl,t),",",Ru(Pl,e))}function Pu(n,t){return(t[1]-n[1])/(t[0]-n[0])}function Uu(n){for(var t=0,e=n.length-1,r=[],i=n[0],u=n[1],o=r[0]=Pu(i,u);++t<e;)r[t]=(o+(o=Pu(i=u,u=n[t+1])))/2;return r[t]=o,r}function ju(n){for(var t,e,r,i,u=[],o=Uu(n),a=-1,l=n.length-1;++a<l;)t=Pu(n[a],n[a+1]),xo(t)<Uo?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,i=e*e+r*r,i>9&&(i=3*t/Math.sqrt(i),o[a]=i*e,o[a+1]=i*r));for(a=-1;++a<=l;)i=(n[Math.min(l,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),u.push([i||0,o[a]*i||0]);return u}function Fu(n){return n.length<3?xu(n):n[0]+Au(n,ju(n))}function Hu(n){for(var t,e,r,i=-1,u=n.length;++i<u;)t=n[i],e=t[0],r=t[1]-Io,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Ou(n){function t(t){function l(){v.push("M",a(n(y),s),f,c(n(d.reverse()),s),"Z")}for(var h,p,g,v=[],d=[],y=[],m=-1,M=t.length,x=En(e),b=En(i),_=e===r?function(){
+return p}:En(r),w=i===u?function(){return g}:En(u);++m<M;)o.call(this,h=t[m],m)?(d.push([p=+x.call(this,h,m),g=+b.call(this,h,m)]),y.push([+_.call(this,h,m),+w.call(this,h,m)])):d.length&&(l(),d=[],y=[]);return d.length&&l(),v.length?v.join(""):null}var e=Ce,r=Ce,i=0,u=ze,o=zt,a=xu,l=a.key,c=a,f="L",s=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(i=u=n,t):u},t.y0=function(n){return arguments.length?(i=n,t):i},t.y1=function(n){return arguments.length?(u=n,t):u},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(l="function"==typeof n?a=n:(a=Tl.get(n)||xu).key,c=a.reverse||a,f=a.closed?"M":"L",t):l},t.tension=function(n){return arguments.length?(s=n,t):s},t}function Iu(n){return n.radius}function Yu(n){return[n.x,n.y]}function Zu(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]-Io;return[e*Math.cos(r),e*Math.sin(r)]}}function Vu(){return 64}function Xu(){return"circle"}function $u(n){var t=Math.sqrt(n/Fo);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Bu(n){return function(){var t,e,r;(t=this[n])&&(r=t[e=t.active])&&(r.timer.c=null,r.timer.t=NaN,--t.count?delete t[e]:delete this[n],t.active+=.5,r.event&&r.event.interrupt.call(this,this.__data__,r.index))}}function Wu(n,t,e){return ko(n,Yl),n.namespace=t,n.id=e,n}function Ju(n,t,e,r){var i=n.id,u=n.namespace;return Y(n,"function"==typeof e?function(n,o,a){n[u][i].tween.set(t,r(e.call(n,n.__data__,o,a)))}:(e=r(e),function(n){n[u][i].tween.set(t,e)}))}function Gu(n){return null==n&&(n=""),function(){this.textContent=n}}function Ku(n){return null==n?"__transition__":"__transition_"+n+"__"}function Qu(n,t,e,r,i){function u(n){var t=v.delay;return f.t=t+l,n>=t?o(n-t):void(f.c=o)}function o(e){var i=g.active,u=g[i];u&&(u.timer.c=null,u.timer.t=NaN,--g.count,delete g[i],u.event&&u.event.interrupt.call(n,n.__data__,u.index));for(var o in g)if(r>+o){var c=g[o];c.timer.c=null,c.timer.t=NaN,--g.count,delete g[o]}f.c=a,qn(function(){return f.c&&a(e||1)&&(f.c=null,f.t=NaN),1},0,l),g.active=r,v.event&&v.event.start.call(n,n.__data__,t),p=[],v.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&p.push(r)}),h=v.ease,s=v.duration}function a(i){for(var u=i/s,o=h(u),a=p.length;a>0;)p[--a].call(n,o);return u>=1?(v.event&&v.event.end.call(n,n.__data__,t),--g.count?delete g[r]:delete n[e],1):void 0}var l,f,s,h,p,g=n[e]||(n[e]={active:0,count:0}),v=g[r];v||(l=i.time,f=qn(u,0,l),v=g[r]={tween:new c,time:l,timer:f,delay:i.delay,duration:i.duration,ease:i.ease,index:t},i=null,++g.count)}function no(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function to(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function eo(n){return n.toISOString()}function ro(n,t,e){function r(t){return n(t)}function i(n,e){var r=n[1]-n[0],i=r/e,u=ao.bisect(Kl,i);return u==Kl.length?[t.year,Ki(n.map(function(n){return n/31536e6}),e)[2]]:u?t[i/Kl[u-1]<Kl[u]/i?u-1:u]:[tc,Ki(n,e)[2]]}return r.invert=function(t){return io(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(io)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,io(+e+1),t).length}var u=r.domain(),o=Yi(u),a=null==n?i(o,10):"number"==typeof n&&i(o,n);return a&&(n=a[0],t=a[1]),r.domain(Xi(u,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Yi(r.domain()),u=null==n?i(e,10):"number"==typeof n?i(e,n):!n.range&&[{range:n},t];return u&&(n=u[0],t=u[1]),n.range(e[0],io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return ro(n.copy(),t,e)},Ji(r,n)}function io(n){return new Date(n)}function uo(n){return JSON.parse(n.responseText)}function oo(n){var t=fo.createRange();return t.selectNode(fo.body),t.createContextualFragment(n.responseText)}var ao={version:"3.5.17"},lo=[].slice,co=function(n){return lo.call(n)},fo=this.document;if(fo)try{co(fo.documentElement.childNodes)[0].nodeType}catch(so){co=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),fo)try{fo.createElement("DIV").style.setProperty("opacity",0,"")}catch(ho){var po=this.Element.prototype,go=po.setAttribute,vo=po.setAttributeNS,yo=this.CSSStyleDeclaration.prototype,mo=yo.setProperty;po.setAttribute=function(n,t){go.call(this,n,t+"")},po.setAttributeNS=function(n,t,e){vo.call(this,n,t,e+"")},yo.setProperty=function(n,t,e){mo.call(this,n,t+"",e)}}ao.ascending=e,ao.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:NaN},ao.min=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i<u;)if(null!=(r=n[i])&&r>=r){e=r;break}for(;++i<u;)null!=(r=n[i])&&e>r&&(e=r)}else{for(;++i<u;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=r;break}for(;++i<u;)null!=(r=t.call(n,n[i],i))&&e>r&&(e=r)}return e},ao.max=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i<u;)if(null!=(r=n[i])&&r>=r){e=r;break}for(;++i<u;)null!=(r=n[i])&&r>e&&(e=r)}else{for(;++i<u;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=r;break}for(;++i<u;)null!=(r=t.call(n,n[i],i))&&r>e&&(e=r)}return e},ao.extent=function(n,t){var e,r,i,u=-1,o=n.length;if(1===arguments.length){for(;++u<o;)if(null!=(r=n[u])&&r>=r){e=i=r;break}for(;++u<o;)null!=(r=n[u])&&(e>r&&(e=r),r>i&&(i=r))}else{for(;++u<o;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=i=r;break}for(;++u<o;)null!=(r=t.call(n,n[u],u))&&(e>r&&(e=r),r>i&&(i=r))}return[e,i]},ao.sum=function(n,t){var e,r=0,u=n.length,o=-1;if(1===arguments.length)for(;++o<u;)i(e=+n[o])&&(r+=e);else for(;++o<u;)i(e=+t.call(n,n[o],o))&&(r+=e);return r},ao.mean=function(n,t){var e,u=0,o=n.length,a=-1,l=o;if(1===arguments.length)for(;++a<o;)i(e=r(n[a]))?u+=e:--l;else for(;++a<o;)i(e=r(t.call(n,n[a],a)))?u+=e:--l;return l?u/l:void 0},ao.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),i=+n[r-1],u=e-r;return u?i+u*(n[r]-i):i},ao.median=function(n,t){var u,o=[],a=n.length,l=-1;if(1===arguments.length)for(;++l<a;)i(u=r(n[l]))&&o.push(u);else for(;++l<a;)i(u=r(t.call(n,n[l],l)))&&o.push(u);return o.length?ao.quantile(o.sort(e),.5):void 0},ao.variance=function(n,t){var e,u,o=n.length,a=0,l=0,c=-1,f=0;if(1===arguments.length)for(;++c<o;)i(e=r(n[c]))&&(u=e-a,a+=u/++f,l+=u*(e-a));else for(;++c<o;)i(e=r(t.call(n,n[c],c)))&&(u=e-a,a+=u/++f,l+=u*(e-a));return f>1?l/(f-1):void 0},ao.deviation=function(){var n=ao.variance.apply(this,arguments);return n?Math.sqrt(n):n};var Mo=u(e);ao.bisectLeft=Mo.left,ao.bisect=ao.bisectRight=Mo.right,ao.bisector=function(n){return u(1===n.length?function(t,r){return e(n(t),r)}:n)},ao.shuffle=function(n,t,e){(u=arguments.length)<3&&(e=n.length,2>u&&(t=0));for(var r,i,u=e-t;u;)i=Math.random()*u--|0,r=n[u+t],n[u+t]=n[i+t],n[i+t]=r;return n},ao.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ao.pairs=function(n){for(var t,e=0,r=n.length-1,i=n[0],u=new Array(0>r?0:r);r>e;)u[e]=[t=i,i=n[++e]];return u},ao.transpose=function(n){if(!(i=n.length))return[];for(var t=-1,e=ao.min(n,o),r=new Array(e);++t<e;)for(var i,u=-1,a=r[t]=new Array(i);++u<i;)a[u]=n[u][t];return r},ao.zip=function(){return ao.transpose(arguments)},ao.keys=function(n){var t=[];for(var e in n)t.push(e);return t},ao.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},ao.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},ao.merge=function(n){for(var t,e,r,i=n.length,u=-1,o=0;++u<i;)o+=n[u].length;for(e=new Array(o);--i>=0;)for(r=n[i],t=r.length;--t>=0;)e[--o]=r[t];return e};var xo=Math.abs;ao.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,i=[],u=a(xo(e)),o=-1;if(n*=u,t*=u,e*=u,0>e)for(;(r=n+e*++o)>t;)i.push(r/u);else for(;(r=n+e*++o)<t;)i.push(r/u);return i},ao.map=function(n,t){var e=new c;if(n instanceof c)n.forEach(function(n,t){e.set(n,t)});else if(Array.isArray(n)){var r,i=-1,u=n.length;if(1===arguments.length)for(;++i<u;)e.set(i,n[i]);else for(;++i<u;)e.set(t.call(n,r=n[i],i),r)}else for(var o in n)e.set(o,n[o]);return e};var bo="__proto__",_o="\x00";l(c,{has:h,get:function(n){return this._[f(n)]},set:function(n,t){return this._[f(n)]=t},remove:p,keys:g,values:function(){var n=[];for(var t in this._)n.push(this._[t]);return n},entries:function(){var n=[];for(var t in this._)n.push({key:s(t),value:this._[t]});return n},size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t),this._[t])}}),ao.nest=function(){function n(t,o,a){if(a>=u.length)return r?r.call(i,o):e?o.sort(e):o;for(var l,f,s,h,p=-1,g=o.length,v=u[a++],d=new c;++p<g;)(h=d.get(l=v(f=o[p])))?h.push(f):d.set(l,[f]);return t?(f=t(),s=function(e,r){f.set(e,n(t,r,a))}):(f={},s=function(e,r){f[e]=n(t,r,a)}),d.forEach(s),f}function t(n,e){if(e>=u.length)return n;var r=[],i=o[e++];return n.forEach(function(n,i){r.push({key:n,values:t(i,e)})}),i?r.sort(function(n,t){return i(n.key,t.key)}):r}var e,r,i={},u=[],o=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(ao.map,e,0),0)},i.key=function(n){return u.push(n),i},i.sortKeys=function(n){return o[u.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},ao.set=function(n){var t=new y;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},l(y,{has:h,add:function(n){return this._[f(n+="")]=!0,n},remove:p,values:g,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t))}}),ao.behavior={},ao.rebind=function(n,t){for(var e,r=1,i=arguments.length;++r<i;)n[e=arguments[r]]=M(n,t,t[e]);return n};var wo=["webkit","ms","moz","Moz","o","O"];ao.dispatch=function(){for(var n=new _,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=w(n);return n},_.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ao.event=null,ao.requote=function(n){return n.replace(So,"\\$&")};var So=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ko={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},No=function(n,t){return t.querySelector(n)},Eo=function(n,t){return t.querySelectorAll(n)},Ao=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(Ao=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(No=function(n,t){return Sizzle(n,t)[0]||null},Eo=Sizzle,Ao=Sizzle.matchesSelector),ao.selection=function(){return ao.select(fo.documentElement)};var Co=ao.selection.prototype=[];Co.select=function(n){var t,e,r,i,u=[];n=A(n);for(var o=-1,a=this.length;++o<a;){u.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var l=-1,c=r.length;++l<c;)(i=r[l])?(t.push(e=n.call(i,i.__data__,l,o)),e&&"__data__"in i&&(e.__data__=i.__data__)):t.push(null)}return E(u)},Co.selectAll=function(n){var t,e,r=[];n=C(n);for(var i=-1,u=this.length;++i<u;)for(var o=this[i],a=-1,l=o.length;++a<l;)(e=o[a])&&(r.push(t=co(n.call(e,e.__data__,a,i))),t.parentNode=e);return E(r)};var zo="http://www.w3.org/1999/xhtml",Lo={svg:"http://www.w3.org/2000/svg",xhtml:zo,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};ao.ns={prefix:Lo,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&"xmlns"!==(e=n.slice(0,t))&&(n=n.slice(t+1)),Lo.hasOwnProperty(e)?{space:Lo[e],local:n}:n}},Co.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ao.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},Co.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,i=-1;if(t=e.classList){for(;++i<r;)if(!t.contains(n[i]))return!1}else for(t=e.getAttribute("class");++i<r;)if(!q(n[i]).test(t))return!1;return!0}for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},Co.style=function(n,e,r){var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>i){var u=this.node();return t(u).getComputedStyle(u,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},Co.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},Co.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Co.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Co.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Co.insert=function(n,t){return n=j(n),t=A(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},Co.remove=function(){return this.each(F)},Co.data=function(n,t){function e(n,e){var r,i,u,o=n.length,s=e.length,h=Math.min(o,s),p=new Array(s),g=new Array(s),v=new Array(o);if(t){var d,y=new c,m=new Array(o);for(r=-1;++r<o;)(i=n[r])&&(y.has(d=t.call(i,i.__data__,r))?v[r]=i:y.set(d,i),m[r]=d);for(r=-1;++r<s;)(i=y.get(d=t.call(e,u=e[r],r)))?i!==!0&&(p[r]=i,i.__data__=u):g[r]=H(u),y.set(d,!0);for(r=-1;++r<o;)r in m&&y.get(m[r])!==!0&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],u=e[r],i?(i.__data__=u,p[r]=i):g[r]=H(u);for(;s>r;++r)g[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}g.update=p,g.parentNode=p.parentNode=v.parentNode=n.parentNode,a.push(g),l.push(p),f.push(v)}var r,i,u=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++u<o;)(i=r[u])&&(n[u]=i.__data__);return n}var a=Z([]),l=E([]),f=E([]);if("function"==typeof n)for(;++u<o;)e(r=this[u],n.call(r,r.parentNode.__data__,u));else for(;++u<o;)e(r=this[u],n);return l.enter=function(){return a},l.exit=function(){return f},l},Co.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},Co.filter=function(n){var t,e,r,i=[];"function"!=typeof n&&(n=O(n));for(var u=0,o=this.length;o>u;u++){i.push(t=[]),t.parentNode=(e=this[u]).parentNode;for(var a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return E(i)},Co.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],i=r.length-1,u=r[i];--i>=0;)(e=r[i])&&(u&&u!==e.nextSibling&&u.parentNode.insertBefore(e,u),u=e);return this},Co.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},Co.each=function(n){return Y(this,function(t,e,r){n.call(t,t.__data__,e,r)})},Co.call=function(n){var t=co(arguments);return n.apply(t[0]=this,t),this},Co.empty=function(){return!this.node()},Co.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,i=e.length;i>r;r++){var u=e[r];if(u)return u}return null},Co.size=function(){var n=0;return Y(this,function(){++n}),n};var qo=[];ao.selection.enter=Z,ao.selection.enter.prototype=qo,qo.append=Co.append,qo.empty=Co.empty,qo.node=Co.node,qo.call=Co.call,qo.size=Co.size,qo.select=function(n){for(var t,e,r,i,u,o=[],a=-1,l=this.length;++a<l;){r=(i=this[a]).update,o.push(t=[]),t.parentNode=i.parentNode;for(var c=-1,f=i.length;++c<f;)(u=i[c])?(t.push(r[c]=e=n.call(i.parentNode,u.__data__,c,a)),e.__data__=u.__data__):t.push(null)}return E(o)},qo.insert=function(n,t){return arguments.length<2&&(t=V(this)),Co.insert.call(this,n,t)},ao.select=function(t){var e;return"string"==typeof t?(e=[No(t,fo)],e.parentNode=fo.documentElement):(e=[t],e.parentNode=n(t)),E([e])},ao.selectAll=function(n){var t;return"string"==typeof n?(t=co(Eo(n,fo)),t.parentNode=fo.documentElement):(t=co(n),t.parentNode=null),E([t])},Co.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var To=ao.map({mouseenter:"mouseover",mouseleave:"mouseout"});fo&&To.forEach(function(n){"on"+n in fo&&To.remove(n)});var Ro,Do=0;ao.mouse=function(n){return J(n,k())};var Po=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ao.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,i=0,u=t.length;u>i;++i)if((r=t[i]).identifier===e)return J(n,r)},ao.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",o)}function e(n,t,e,u,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],g|=n|e,M=r,p({type:"drag",x:r[0]+c[0],y:r[1]+c[1],dx:n,dy:e}))}function l(){t(h,v)&&(y.on(u+d,null).on(o+d,null),m(g),p({type:"dragend"}))}var c,f=this,s=ao.event.target.correspondingElement||ao.event.target,h=f.parentNode,p=r.of(f,arguments),g=0,v=n(),d=".drag"+(null==v?"":"-"+v),y=ao.select(e(s)).on(u+d,a).on(o+d,l),m=W(s),M=t(h,v);i?(c=i.apply(f,arguments),c=[c.x-M[0],c.y-M[1]]):c=[0,0],p({type:"dragstart"})}}var r=N(n,"drag","dragstart","dragend"),i=null,u=e(b,ao.mouse,t,"mousemove","mouseup"),o=e(G,ao.touch,m,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},ao.rebind(n,r,"on")},ao.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?co(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Uo=1e-6,jo=Uo*Uo,Fo=Math.PI,Ho=2*Fo,Oo=Ho-Uo,Io=Fo/2,Yo=Fo/180,Zo=180/Fo,Vo=Math.SQRT2,Xo=2,$o=4;ao.interpolateZoom=function(n,t){var e,r,i=n[0],u=n[1],o=n[2],a=t[0],l=t[1],c=t[2],f=a-i,s=l-u,h=f*f+s*s;if(jo>h)r=Math.log(c/o)/Vo,e=function(n){return[i+n*f,u+n*s,o*Math.exp(Vo*n*r)]};else{var p=Math.sqrt(h),g=(c*c-o*o+$o*h)/(2*o*Xo*p),v=(c*c-o*o-$o*h)/(2*c*Xo*p),d=Math.log(Math.sqrt(g*g+1)-g),y=Math.log(Math.sqrt(v*v+1)-v);r=(y-d)/Vo,e=function(n){var t=n*r,e=rn(d),a=o/(Xo*p)*(e*un(Vo*t+d)-en(d));return[i+a*f,u+a*s,o*e/rn(Vo*t+d)]}}return e.duration=1e3*r,e},ao.behavior.zoom=function(){function n(n){n.on(L,s).on(Wo+".zoom",p).on("dblclick.zoom",g).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function i(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},i(Math.pow(2,o)),u(d=e,r),t=ao.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function l(n){z++||n({type:"zoomstart"})}function c(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function f(n){--z||(n({type:"zoomend"}),d=null)}function s(){function n(){a=1,u(ao.mouse(i),h),c(o)}function r(){s.on(q,null).on(T,null),p(a),f(o)}var i=this,o=D.of(i,arguments),a=0,s=ao.select(t(i)).on(q,n).on(T,r),h=e(ao.mouse(i)),p=W(i);Il.call(i),l(o)}function h(){function n(){var n=ao.touches(g);return p=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ao.event.target;ao.select(t).on(x,r).on(b,a),_.push(t);for(var e=ao.event.changedTouches,i=0,u=e.length;u>i;++i)d[e[i].identifier]=null;var l=n(),c=Date.now();if(1===l.length){if(500>c-M){var f=l[0];o(g,f,d[f.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=c}else if(l.length>1){var f=l[0],s=l[1],h=f[0]-s[0],p=f[1]-s[1];y=h*h+p*p}}function r(){var n,t,e,r,o=ao.touches(g);Il.call(g);for(var a=0,l=o.length;l>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var f=(f=e[0]-n[0])*f+(f=e[1]-n[1])*f,s=y&&Math.sqrt(f/y);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],i(s*p)}M=null,u(n,t),c(v)}function a(){if(ao.event.touches.length){for(var t=ao.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var i in d)return void n()}ao.selectAll(_).on(m,null),w.on(L,s).on(R,h),N(),f(v)}var p,g=this,v=D.of(g,arguments),d={},y=0,m=".zoom-"+ao.event.changedTouches[0].identifier,x="touchmove"+m,b="touchend"+m,_=[],w=ao.select(g),N=W(g);t(),l(v),w.on(L,null).on(R,t)}function p(){var n=D.of(this,arguments);m?clearTimeout(m):(Il.call(this),v=e(d=y||ao.mouse(this)),l(n)),m=setTimeout(function(){m=null,f(n)},50),S(),i(Math.pow(2,.002*Bo())*k.k),u(d,v),c(n)}function g(){var n=ao.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ao.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,y,m,M,x,b,_,w,k={x:0,y:0,k:1},E=[960,500],A=Jo,C=250,z=0,L="mousedown.zoom",q="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=N(n,"zoomstart","zoom","zoomend");return Wo||(Wo="onwheel"in fo?(Bo=function(){return-ao.event.deltaY*(ao.event.deltaMode?120:1)},"wheel"):"onmousewheel"in fo?(Bo=function(){return ao.event.wheelDelta},"mousewheel"):(Bo=function(){return-ao.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Hl?ao.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},l(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],i=d?d[0]:e/2,u=d?d[1]:r/2,o=ao.interpolateZoom([(i-k.x)/k.k,(u-k.y)/k.k,e/k.k],[(i-t.x)/t.k,(u-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:i-r[0]*a,y:u-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){f(n)}).each("end.zoom",function(){f(n)}):(this.__chart__=k,l(n),c(n),f(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:null},i(+t),a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Jo:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(y=t&&[+t[0],+t[1]],n):y},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ao.rebind(n,D,"on")};var Bo,Wo,Jo=[0,1/0];ao.color=an,an.prototype.toString=function(){return this.rgb()+""},ao.hsl=ln;var Go=ln.prototype=new an;Go.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,this.l/n)},Go.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,n*this.l)},Go.rgb=function(){return cn(this.h,this.s,this.l)},ao.hcl=fn;var Ko=fn.prototype=new an;Ko.brighter=function(n){return new fn(this.h,this.c,Math.min(100,this.l+Qo*(arguments.length?n:1)))},Ko.darker=function(n){return new fn(this.h,this.c,Math.max(0,this.l-Qo*(arguments.length?n:1)))},Ko.rgb=function(){return sn(this.h,this.c,this.l).rgb()},ao.lab=hn;var Qo=18,na=.95047,ta=1,ea=1.08883,ra=hn.prototype=new an;ra.brighter=function(n){return new hn(Math.min(100,this.l+Qo*(arguments.length?n:1)),this.a,this.b)},ra.darker=function(n){return new hn(Math.max(0,this.l-Qo*(arguments.length?n:1)),this.a,this.b)},ra.rgb=function(){return pn(this.l,this.a,this.b)},ao.rgb=mn;var ia=mn.prototype=new an;ia.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,i=30;return t||e||r?(t&&i>t&&(t=i),e&&i>e&&(e=i),r&&i>r&&(r=i),new mn(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mn(i,i,i)},ia.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mn(n*this.r,n*this.g,n*this.b)},ia.hsl=function(){return wn(this.r,this.g,this.b)},ia.toString=function(){return"#"+bn(this.r)+bn(this.g)+bn(this.b)};var ua=ao.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ua.forEach(function(n,t){ua.set(n,Mn(t))}),ao.functor=En,ao.xhr=An(m),ao.dsv=function(n,t){function e(n,e,u){arguments.length<3&&(u=e,e=null);var o=Cn(n,t,null==e?r:i(e),u);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:i(n)):e},o}function r(n){return e.parse(n.responseText)}function i(n){return function(t){return e.parse(t.responseText,n)}}function u(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var i=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(i(n),e)}:i})},e.parseRows=function(n,t){function e(){if(f>=c)return o;if(i)return i=!1,u;var t=f;if(34===n.charCodeAt(t)){for(var e=t;e++<c;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}f=e+2;var r=n.charCodeAt(e+1);return 13===r?(i=!0,10===n.charCodeAt(e+2)&&++f):10===r&&(i=!0),n.slice(t+1,e).replace(/""/g,'"')}for(;c>f;){var r=n.charCodeAt(f++),a=1;if(10===r)i=!0;else if(13===r)i=!0,10===n.charCodeAt(f)&&(++f,++a);else if(r!==l)continue;return n.slice(t,f-a)}return n.slice(t)}for(var r,i,u={},o={},a=[],c=n.length,f=0,s=0;(r=e())!==o;){for(var h=[];r!==u&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,s++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new y,i=[];return t.forEach(function(n){for(var t in n)r.has(t)||i.push(r.add(t))}),[i.map(o).join(n)].concat(t.map(function(t){return i.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(u).join("\n")},e},ao.csv=ao.dsv(",","text/csv"),ao.tsv=ao.dsv(" ","text/tab-separated-values");var oa,aa,la,ca,fa=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ao.timer=function(){qn.apply(this,arguments)},ao.timer.flush=function(){Rn(),Dn()},ao.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var sa=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Un);ao.formatPrefix=function(n,t){var e=0;return(n=+n)&&(0>n&&(n*=-1),t&&(n=ao.round(n,Pn(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),sa[8+e/3]};var ha=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,pa=ao.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ao.round(n,Pn(n,t))).toFixed(Math.max(0,Math.min(20,Pn(n*(1+1e-15),t))))}}),ga=ao.time={},va=Date;Hn.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){da.setUTCDate.apply(this._,arguments)},setDay:function(){da.setUTCDay.apply(this._,arguments)},setFullYear:function(){da.setUTCFullYear.apply(this._,arguments)},setHours:function(){da.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){da.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){da.setUTCMinutes.apply(this._,arguments)},setMonth:function(){da.setUTCMonth.apply(this._,arguments)},setSeconds:function(){da.setUTCSeconds.apply(this._,arguments)},setTime:function(){da.setTime.apply(this._,arguments)}};var da=Date.prototype;ga.year=On(function(n){return n=ga.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ga.years=ga.year.range,ga.years.utc=ga.year.utc.range,ga.day=On(function(n){var t=new va(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ga.days=ga.day.range,ga.days.utc=ga.day.utc.range,ga.dayOfYear=function(n){var t=ga.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ga[n]=On(function(n){return(n=ga.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ga[n+"s"]=e.range,ga[n+"s"].utc=e.utc.range,ga[n+"OfYear"]=function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)}}),ga.week=ga.sunday,ga.weeks=ga.sunday.range,ga.weeks.utc=ga.sunday.utc.range,ga.weekOfYear=ga.sundayOfYear;var ya={"-":"",_:" ",0:"0"},ma=/^\s*\d+/,Ma=/^%/;ao.locale=function(n){return{numberFormat:jn(n),timeFormat:Yn(n)}};var xa=ao.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],
+shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ao.format=xa.numberFormat,ao.geo={},ft.prototype={s:0,t:0,add:function(n){st(n,this.t,ba),st(ba.s,this.s,this),this.s?this.t+=ba.t:this.s=ba.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var ba=new ft;ao.geo.stream=function(n,t){n&&_a.hasOwnProperty(n.type)?_a[n.type](n,t):ht(n,t)};var _a={Feature:function(n,t){ht(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,i=e.length;++r<i;)ht(e[r].geometry,t)}},wa={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){pt(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)pt(e[r],t,0)},Polygon:function(n,t){gt(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)gt(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,i=e.length;++r<i;)ht(e[r],t)}};ao.geo.area=function(n){return Sa=0,ao.geo.stream(n,Na),Sa};var Sa,ka=new ft,Na={sphere:function(){Sa+=4*Fo},point:b,lineStart:b,lineEnd:b,polygonStart:function(){ka.reset(),Na.lineStart=vt},polygonEnd:function(){var n=2*ka;Sa+=0>n?4*Fo+n:n,Na.lineStart=Na.lineEnd=Na.point=b}};ao.geo.bounds=function(){function n(n,t){M.push(x=[f=n,h=n]),s>t&&(s=t),t>p&&(p=t)}function t(t,e){var r=dt([t*Yo,e*Yo]);if(y){var i=mt(y,r),u=[i[1],-i[0],0],o=mt(u,i);bt(o),o=_t(o);var l=t-g,c=l>0?1:-1,v=o[0]*Zo*c,d=xo(l)>180;if(d^(v>c*g&&c*t>v)){var m=o[1]*Zo;m>p&&(p=m)}else if(v=(v+360)%360-180,d^(v>c*g&&c*t>v)){var m=-o[1]*Zo;s>m&&(s=m)}else s>e&&(s=e),e>p&&(p=e);d?g>t?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t):h>=f?(f>t&&(f=t),t>h&&(h=t)):t>g?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t)}else n(t,e);y=r,g=t}function e(){b.point=t}function r(){x[0]=f,x[1]=h,b.point=n,y=null}function i(n,e){if(y){var r=n-g;m+=xo(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Na.point(n,e),t(n,e)}function u(){Na.lineStart()}function o(){i(v,d),Na.lineEnd(),xo(m)>Uo&&(f=-(h=180)),x[0]=f,x[1]=h,y=null}function a(n,t){return(t-=n)<0?t+360:t}function l(n,t){return n[0]-t[0]}function c(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var f,s,h,p,g,v,d,y,m,M,x,b={point:n,lineStart:e,lineEnd:r,polygonStart:function(){b.point=i,b.lineStart=u,b.lineEnd=o,m=0,Na.polygonStart()},polygonEnd:function(){Na.polygonEnd(),b.point=n,b.lineStart=e,b.lineEnd=r,0>ka?(f=-(h=180),s=-(p=90)):m>Uo?p=90:-Uo>m&&(s=-90),x[0]=f,x[1]=h}};return function(n){p=h=-(f=s=1/0),M=[],ao.geo.stream(n,b);var t=M.length;if(t){M.sort(l);for(var e,r=1,i=M[0],u=[i];t>r;++r)e=M[r],c(e[0],i)||c(e[1],i)?(a(i[0],e[1])>a(i[0],i[1])&&(i[1]=e[1]),a(e[0],i[1])>a(i[0],i[1])&&(i[0]=e[0])):u.push(i=e);for(var o,e,g=-(1/0),t=u.length-1,r=0,i=u[t];t>=r;i=e,++r)e=u[r],(o=a(i[1],e[0]))>g&&(g=o,f=e[0],h=i[1])}return M=x=null,f===1/0||s===1/0?[[NaN,NaN],[NaN,NaN]]:[[f,s],[h,p]]}}(),ao.geo.centroid=function(n){Ea=Aa=Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,ja);var t=Da,e=Pa,r=Ua,i=t*t+e*e+r*r;return jo>i&&(t=qa,e=Ta,r=Ra,Uo>Aa&&(t=Ca,e=za,r=La),i=t*t+e*e+r*r,jo>i)?[NaN,NaN]:[Math.atan2(e,t)*Zo,tn(r/Math.sqrt(i))*Zo]};var Ea,Aa,Ca,za,La,qa,Ta,Ra,Da,Pa,Ua,ja={sphere:b,point:St,lineStart:Nt,lineEnd:Et,polygonStart:function(){ja.lineStart=At},polygonEnd:function(){ja.lineStart=Nt}},Fa=Rt(zt,jt,Ht,[-Fo,-Fo/2]),Ha=1e9;ao.geo.clipExtent=function(){var n,t,e,r,i,u,o={stream:function(n){return i&&(i.valid=!1),i=u(n),i.valid=!0,i},extent:function(a){return arguments.length?(u=Zt(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),i&&(i.valid=!1,i=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ao.geo.conicEqualArea=function(){return Vt(Xt)}).raw=Xt,ao.geo.albers=function(){return ao.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ao.geo.albersUsa=function(){function n(n){var u=n[0],o=n[1];return t=null,e(u,o),t||(r(u,o),t)||i(u,o),t}var t,e,r,i,u=ao.geo.albers(),o=ao.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ao.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=u.scale(),e=u.translate(),r=(n[0]-e[0])/t,i=(n[1]-e[1])/t;return(i>=.12&&.234>i&&r>=-.425&&-.214>r?o:i>=.166&&.234>i&&r>=-.214&&-.115>r?a:u).invert(n)},n.stream=function(n){var t=u.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,i){t.point(n,i),e.point(n,i),r.point(n,i)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(u.precision(t),o.precision(t),a.precision(t),n):u.precision()},n.scale=function(t){return arguments.length?(u.scale(t),o.scale(.35*t),a.scale(t),n.translate(u.translate())):u.scale()},n.translate=function(t){if(!arguments.length)return u.translate();var c=u.scale(),f=+t[0],s=+t[1];return e=u.translate(t).clipExtent([[f-.455*c,s-.238*c],[f+.455*c,s+.238*c]]).stream(l).point,r=o.translate([f-.307*c,s+.201*c]).clipExtent([[f-.425*c+Uo,s+.12*c+Uo],[f-.214*c-Uo,s+.234*c-Uo]]).stream(l).point,i=a.translate([f-.205*c,s+.212*c]).clipExtent([[f-.214*c+Uo,s+.166*c+Uo],[f-.115*c-Uo,s+.234*c-Uo]]).stream(l).point,n},n.scale(1070)};var Oa,Ia,Ya,Za,Va,Xa,$a={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Ia=0,$a.lineStart=$t},polygonEnd:function(){$a.lineStart=$a.lineEnd=$a.point=b,Oa+=xo(Ia/2)}},Ba={point:Bt,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Wa={point:Gt,lineStart:Kt,lineEnd:Qt,polygonStart:function(){Wa.lineStart=ne},polygonEnd:function(){Wa.point=Gt,Wa.lineStart=Kt,Wa.lineEnd=Qt}};ao.geo.path=function(){function n(n){return n&&("function"==typeof a&&u.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=i(u)),ao.geo.stream(n,o)),u.result()}function t(){return o=null,n}var e,r,i,u,o,a=4.5;return n.area=function(n){return Oa=0,ao.geo.stream(n,i($a)),Oa},n.centroid=function(n){return Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,i(Wa)),Ua?[Da/Ua,Pa/Ua]:Ra?[qa/Ra,Ta/Ra]:La?[Ca/La,za/La]:[NaN,NaN]},n.bounds=function(n){return Va=Xa=-(Ya=Za=1/0),ao.geo.stream(n,i(Ba)),[[Ya,Za],[Va,Xa]]},n.projection=function(n){return arguments.length?(i=(e=n)?n.stream||re(n):m,t()):e},n.context=function(n){return arguments.length?(u=null==(r=n)?new Wt:new te(n),"function"!=typeof a&&u.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(u.pointRadius(+t),+t),n):a},n.projection(ao.geo.albersUsa()).context(null)},ao.geo.transform=function(n){return{stream:function(t){var e=new ie(t);for(var r in n)e[r]=n[r];return e}}},ie.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ao.geo.projection=oe,ao.geo.projectionMutator=ae,(ao.geo.equirectangular=function(){return oe(ce)}).raw=ce.invert=ce,ao.geo.rotation=function(n){function t(t){return t=n(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t}return n=se(n[0]%360*Yo,n[1]*Yo,n.length>2?n[2]*Yo:0),t.invert=function(t){return t=n.invert(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t},t},fe.invert=ce,ao.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=se(-n[0]*Yo,-n[1]*Yo,0).invert,i=[];return e(null,null,1,{point:function(n,e){i.push(n=t(n,e)),n[0]*=Zo,n[1]*=Zo}}),{type:"Polygon",coordinates:[i]}}var t,e,r=[0,0],i=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=ve((t=+r)*Yo,i*Yo),n):t},n.precision=function(r){return arguments.length?(e=ve(t*Yo,(i=+r)*Yo),n):i},n.angle(90)},ao.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Yo,i=n[1]*Yo,u=t[1]*Yo,o=Math.sin(r),a=Math.cos(r),l=Math.sin(i),c=Math.cos(i),f=Math.sin(u),s=Math.cos(u);return Math.atan2(Math.sqrt((e=s*o)*e+(e=c*f-l*s*a)*e),l*f+c*s*a)},ao.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ao.range(Math.ceil(u/d)*d,i,d).map(h).concat(ao.range(Math.ceil(c/y)*y,l,y).map(p)).concat(ao.range(Math.ceil(r/g)*g,e,g).filter(function(n){return xo(n%d)>Uo}).map(f)).concat(ao.range(Math.ceil(a/v)*v,o,v).filter(function(n){return xo(n%y)>Uo}).map(s))}var e,r,i,u,o,a,l,c,f,s,h,p,g=10,v=g,d=90,y=360,m=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(u).concat(p(l).slice(1),h(i).reverse().slice(1),p(c).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(u=+t[0][0],i=+t[1][0],c=+t[0][1],l=+t[1][1],u>i&&(t=u,u=i,i=t),c>l&&(t=c,c=l,l=t),n.precision(m)):[[u,c],[i,l]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(m)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],y=+t[1],n):[d,y]},n.minorStep=function(t){return arguments.length?(g=+t[0],v=+t[1],n):[g,v]},n.precision=function(t){return arguments.length?(m=+t,f=ye(a,o,90),s=me(r,e,m),h=ye(c,l,90),p=me(u,i,m),n):m},n.majorExtent([[-180,-90+Uo],[180,90-Uo]]).minorExtent([[-180,-80-Uo],[180,80+Uo]])},ao.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||i.apply(this,arguments)]}}var t,e,r=Me,i=xe;return n.distance=function(){return ao.geo.distance(t||r.apply(this,arguments),e||i.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(i=t,e="function"==typeof t?null:t,n):i},n.precision=function(){return arguments.length?n:0},n},ao.geo.interpolate=function(n,t){return be(n[0]*Yo,n[1]*Yo,t[0]*Yo,t[1]*Yo)},ao.geo.length=function(n){return Ja=0,ao.geo.stream(n,Ga),Ja};var Ja,Ga={sphere:b,point:b,lineStart:_e,lineEnd:b,polygonStart:b,polygonEnd:b},Ka=we(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ao.geo.azimuthalEqualArea=function(){return oe(Ka)}).raw=Ka;var Qa=we(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},m);(ao.geo.azimuthalEquidistant=function(){return oe(Qa)}).raw=Qa,(ao.geo.conicConformal=function(){return Vt(Se)}).raw=Se,(ao.geo.conicEquidistant=function(){return Vt(ke)}).raw=ke;var nl=we(function(n){return 1/n},Math.atan);(ao.geo.gnomonic=function(){return oe(nl)}).raw=nl,Ne.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Io]},(ao.geo.mercator=function(){return Ee(Ne)}).raw=Ne;var tl=we(function(){return 1},Math.asin);(ao.geo.orthographic=function(){return oe(tl)}).raw=tl;var el=we(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ao.geo.stereographic=function(){return oe(el)}).raw=el,Ae.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Io]},(ao.geo.transverseMercator=function(){var n=Ee(Ae),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Ae,ao.geom={},ao.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,i=En(e),u=En(r),o=n.length,a=[],l=[];for(t=0;o>t;t++)a.push([+i.call(this,n[t],t),+u.call(this,n[t],t),t]);for(a.sort(qe),t=0;o>t;t++)l.push([a[t][0],-a[t][1]]);var c=Le(a),f=Le(l),s=f[0]===c[0],h=f[f.length-1]===c[c.length-1],p=[];for(t=c.length-1;t>=0;--t)p.push(n[a[c[t]][2]]);for(t=+s;t<f.length-h;++t)p.push(n[a[f[t]][2]]);return p}var e=Ce,r=ze;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},ao.geom.polygon=function(n){return ko(n,rl),n};var rl=ao.geom.polygon.prototype=[];rl.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],i=0;++t<e;)n=r,r=this[t],i+=n[1]*r[0]-n[0]*r[1];return.5*i},rl.centroid=function(n){var t,e,r=-1,i=this.length,u=0,o=0,a=this[i-1];for(arguments.length||(n=-1/(6*this.area()));++r<i;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],u+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[u*n,o*n]},rl.clip=function(n){for(var t,e,r,i,u,o,a=De(n),l=-1,c=this.length-De(this),f=this[c-1];++l<c;){for(t=n.slice(),n.length=0,i=this[l],u=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Te(o,f,i)?(Te(u,f,i)||n.push(Re(u,o,f,i)),n.push(o)):Te(u,f,i)&&n.push(Re(u,o,f,i)),u=o;a&&n.push(n[0]),f=i}return n};var il,ul,ol,al,ll,cl=[],fl=[];Ye.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Ve),t.length},tr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},er.prototype={insert:function(n,t){var e,r,i;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=or(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(i=r.R,i&&i.C?(e.C=i.C=!1,r.C=!0,n=r):(n===e.R&&(ir(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ur(this,r))):(i=r.L,i&&i.C?(e.C=i.C=!1,r.C=!0,n=r):(n===e.L&&(ur(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ir(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,i=n.U,u=n.L,o=n.R;if(e=u?o?or(o):u:o,i?i.L===n?i.L=e:i.R=e:this._=e,u&&o?(r=e.C,e.C=n.C,e.L=u,u.U=e,e!==o?(i=e.U,e.U=n.U,n=e.R,i.L=n,e.R=o,o.U=e):(e.U=i,i=e,n=e.R)):(r=n.C,n=e),n&&(n.U=i),!r){if(n&&n.C)return void(n.C=!1);do{if(n===this._)break;if(n===i.L){if(t=i.R,t.C&&(t.C=!1,i.C=!0,ir(this,i),t=i.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,ur(this,t),t=i.R),t.C=i.C,i.C=t.R.C=!1,ir(this,i),n=this._;break}}else if(t=i.L,t.C&&(t.C=!1,i.C=!0,ur(this,i),t=i.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,ir(this,t),t=i.L),t.C=i.C,i.C=t.L.C=!1,ur(this,i),n=this._;break}t.C=!0,n=i,i=i.U}while(!n.C);n&&(n.C=!1)}}},ao.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],i=a[0][1],u=a[1][0],o=a[1][1];return ar(e(n),a).cells.forEach(function(e,a){var l=e.edges,c=e.site,f=t[a]=l.length?l.map(function(n){var t=n.start();return[t.x,t.y]}):c.x>=r&&c.x<=u&&c.y>=i&&c.y<=o?[[r,o],[u,o],[u,i],[r,i]]:[];f.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(u(n,t)/Uo)*Uo,y:Math.round(o(n,t)/Uo)*Uo,i:t}})}var r=Ce,i=ze,u=r,o=i,a=sl;return n?t(n):(t.links=function(n){return ar(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return ar(e(n)).cells.forEach(function(e,r){for(var i,u,o=e.site,a=e.edges.sort(Ve),l=-1,c=a.length,f=a[c-1].edge,s=f.l===o?f.r:f.l;++l<c;)i=f,u=s,f=a[l].edge,s=f.l===o?f.r:f.l,r<u.i&&r<s.i&&cr(o,u,s)<0&&t.push([n[r],n[u.i],n[s.i]])}),t},t.x=function(n){return arguments.length?(u=En(r=n),t):r},t.y=function(n){return arguments.length?(o=En(i=n),t):i},t.clipExtent=function(n){return arguments.length?(a=null==n?sl:n,t):a===sl?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===sl?null:a&&a[1]},t)};var sl=[[-1e6,-1e6],[1e6,1e6]];ao.geom.delaunay=function(n){return ao.geom.voronoi().triangles(n)},ao.geom.quadtree=function(n,t,e,r,i){function u(n){function u(n,t,e,r,i,u,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var l=n.x,f=n.y;if(null!=l)if(xo(l-e)+xo(f-r)<.01)c(n,t,e,r,i,u,o,a);else{var s=n.point;n.x=n.y=n.point=null,c(n,s,l,f,i,u,o,a),c(n,t,e,r,i,u,o,a)}else n.x=e,n.y=r,n.point=t}else c(n,t,e,r,i,u,o,a)}function c(n,t,e,r,i,o,a,l){var c=.5*(i+a),f=.5*(o+l),s=e>=c,h=r>=f,p=h<<1|s;n.leaf=!1,n=n.nodes[p]||(n.nodes[p]=hr()),s?i=c:a=c,h?o=f:l=f,u(n,t,e,r,i,o,a,l)}var f,s,h,p,g,v,d,y,m,M=En(a),x=En(l);if(null!=t)v=t,d=e,y=r,m=i;else if(y=m=-(v=d=1/0),s=[],h=[],g=n.length,o)for(p=0;g>p;++p)f=n[p],f.x<v&&(v=f.x),f.y<d&&(d=f.y),f.x>y&&(y=f.x),f.y>m&&(m=f.y),s.push(f.x),h.push(f.y);else for(p=0;g>p;++p){var b=+M(f=n[p],p),_=+x(f,p);v>b&&(v=b),d>_&&(d=_),b>y&&(y=b),_>m&&(m=_),s.push(b),h.push(_)}var w=y-v,S=m-d;w>S?m=d+w:y=v+S;var k=hr();if(k.add=function(n){u(k,n,+M(n,++p),+x(n,p),v,d,y,m)},k.visit=function(n){pr(n,k,v,d,y,m)},k.find=function(n){return gr(k,n[0],n[1],v,d,y,m)},p=-1,null==t){for(;++p<g;)u(k,n[p],s[p],h[p],v,d,y,m);--p}else n.forEach(k.add);return s=h=n=f=null,k}var o,a=Ce,l=ze;return(o=arguments.length)?(a=fr,l=sr,3===o&&(i=e,r=t,e=t=0),u(n)):(u.x=function(n){return arguments.length?(a=n,u):a},u.y=function(n){return arguments.length?(l=n,u):l},u.extent=function(n){return arguments.length?(null==n?t=e=r=i=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],i=+n[1][1]),u):null==t?null:[[t,e],[r,i]]},u.size=function(n){return arguments.length?(null==n?t=e=r=i=null:(t=e=0,r=+n[0],i=+n[1]),u):null==t?null:[r-t,i-e]},u)},ao.interpolateRgb=vr,ao.interpolateObject=dr,ao.interpolateNumber=yr,ao.interpolateString=mr;var hl=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,pl=new RegExp(hl.source,"g");ao.interpolate=Mr,ao.interpolators=[function(n,t){var e=typeof t;return("string"===e?ua.has(t.toLowerCase())||/^(#|rgb\(|hsl\()/i.test(t)?vr:mr:t instanceof an?vr:Array.isArray(t)?xr:"object"===e&&isNaN(t)?dr:yr)(n,t)}],ao.interpolateArray=xr;var gl=function(){return m},vl=ao.map({linear:gl,poly:Er,quad:function(){return Sr},cubic:function(){return kr},sin:function(){return Ar},exp:function(){return Cr},circle:function(){return zr},elastic:Lr,back:qr,bounce:function(){return Tr}}),dl=ao.map({"in":m,out:_r,"in-out":wr,"out-in":function(n){return wr(_r(n))}});ao.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=vl.get(e)||gl,r=dl.get(r)||m,br(r(e.apply(null,lo.call(arguments,1))))},ao.interpolateHcl=Rr,ao.interpolateHsl=Dr,ao.interpolateLab=Pr,ao.interpolateRound=Ur,ao.transform=function(n){var t=fo.createElementNS(ao.ns.prefix.svg,"g");return(ao.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new jr(e?e.matrix:yl)})(n)},jr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var yl={a:1,b:0,c:0,d:1,e:0,f:0};ao.interpolateTransform=$r,ao.layout={},ao.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Jr(n[e]));return t}},ao.layout.chord=function(){function n(){var n,c,s,h,p,g={},v=[],d=ao.range(u),y=[];for(e=[],r=[],n=0,h=-1;++h<u;){for(c=0,p=-1;++p<u;)c+=i[h][p];v.push(c),y.push(ao.range(u)),n+=c}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&y.forEach(function(n,t){n.sort(function(n,e){return a(i[t][n],i[t][e])})}),n=(Ho-f*u)/n,c=0,h=-1;++h<u;){for(s=c,p=-1;++p<u;){var m=d[h],M=y[m][p],x=i[m][M],b=c,_=c+=x*n;g[m+"-"+M]={index:m,subindex:M,startAngle:b,endAngle:_,value:x}}r[m]={index:m,startAngle:s,endAngle:c,value:v[m]},c+=f}for(h=-1;++h<u;)for(p=h-1;++p<u;){var w=g[h+"-"+p],S=g[p+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}l&&t()}function t(){e.sort(function(n,t){return l((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,i,u,o,a,l,c={},f=0;return c.matrix=function(n){return arguments.length?(u=(i=n)&&i.length,e=r=null,c):i},c.padding=function(n){return arguments.length?(f=n,e=r=null,c):f},c.sortGroups=function(n){return arguments.length?(o=n,e=r=null,c):o},c.sortSubgroups=function(n){return arguments.length?(a=n,e=null,c):a},c.sortChords=function(n){return arguments.length?(l=n,e&&t(),c):l},c.chords=function(){return e||n(),e},c.groups=function(){return r||n(),r},c},ao.layout.force=function(){function n(n){return function(t,e,r,i){if(t.point!==n){var u=t.cx-n.x,o=t.cy-n.y,a=i-e,l=u*u+o*o;if(l>a*a/y){if(v>l){var c=t.charge/l;n.px-=u*c,n.py-=o*c}return!0}if(t.point&&l&&v>l){var c=t.pointCharge/l;n.px-=u*c,n.py-=o*c}}return!t.charge}}function t(n){n.px=ao.event.x,n.py=ao.event.y,l.resume()}var e,r,i,u,o,a,l={},c=ao.dispatch("start","tick","end"),f=[1,1],s=.9,h=ml,p=Ml,g=-30,v=xl,d=.1,y=.64,M=[],x=[];return l.tick=function(){if((i*=.99)<.005)return e=null,c.end({type:"end",alpha:i=0}),!0;var t,r,l,h,p,v,y,m,b,_=M.length,w=x.length;for(r=0;w>r;++r)l=x[r],h=l.source,p=l.target,m=p.x-h.x,b=p.y-h.y,(v=m*m+b*b)&&(v=i*o[r]*((v=Math.sqrt(v))-u[r])/v,m*=v,b*=v,p.x-=m*(y=h.weight+p.weight?h.weight/(h.weight+p.weight):.5),p.y-=b*y,h.x+=m*(y=1-y),h.y+=b*y);if((y=i*d)&&(m=f[0]/2,b=f[1]/2,r=-1,y))for(;++r<_;)l=M[r],l.x+=(m-l.x)*y,l.y+=(b-l.y)*y;if(g)for(ri(t=ao.geom.quadtree(M),i,a),r=-1;++r<_;)(l=M[r]).fixed||t.visit(n(l));for(r=-1;++r<_;)l=M[r],l.fixed?(l.x=l.px,l.y=l.py):(l.x-=(l.px-(l.px=l.x))*s,l.y-=(l.py-(l.py=l.y))*s);c.tick({type:"tick",alpha:i})},l.nodes=function(n){return arguments.length?(M=n,l):M},l.links=function(n){return arguments.length?(x=n,l):x},l.size=function(n){return arguments.length?(f=n,l):f},l.linkDistance=function(n){return arguments.length?(h="function"==typeof n?n:+n,l):h},l.distance=l.linkDistance,l.linkStrength=function(n){return arguments.length?(p="function"==typeof n?n:+n,l):p},l.friction=function(n){return arguments.length?(s=+n,l):s},l.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,l):g},l.chargeDistance=function(n){return arguments.length?(v=n*n,l):Math.sqrt(v)},l.gravity=function(n){return arguments.length?(d=+n,l):d},l.theta=function(n){return arguments.length?(y=n*n,l):Math.sqrt(y)},l.alpha=function(n){return arguments.length?(n=+n,i?n>0?i=n:(e.c=null,e.t=NaN,e=null,c.end({type:"end",alpha:i=0})):n>0&&(c.start({type:"start",alpha:i=n}),e=qn(l.tick)),l):i},l.start=function(){function n(n,r){if(!e){for(e=new Array(i),l=0;i>l;++l)e[l]=[];for(l=0;c>l;++l){var u=x[l];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var o,a=e[t],l=-1,f=a.length;++l<f;)if(!isNaN(o=a[l][n]))return o;return Math.random()*r}var t,e,r,i=M.length,c=x.length,s=f[0],v=f[1];for(t=0;i>t;++t)(r=M[t]).index=t,r.weight=0;for(t=0;c>t;++t)r=x[t],"number"==typeof r.source&&(r.source=M[r.source]),"number"==typeof r.target&&(r.target=M[r.target]),++r.source.weight,++r.target.weight;for(t=0;i>t;++t)r=M[t],isNaN(r.x)&&(r.x=n("x",s)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof h)for(t=0;c>t;++t)u[t]=+h.call(this,x[t],t);else for(t=0;c>t;++t)u[t]=h;if(o=[],"function"==typeof p)for(t=0;c>t;++t)o[t]=+p.call(this,x[t],t);else for(t=0;c>t;++t)o[t]=p;if(a=[],"function"==typeof g)for(t=0;i>t;++t)a[t]=+g.call(this,M[t],t);else for(t=0;i>t;++t)a[t]=g;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){return r||(r=ao.behavior.drag().origin(m).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",ni)),arguments.length?void this.on("mouseover.force",ti).on("mouseout.force",ei).call(r):r},ao.rebind(l,c,"on")};var ml=20,Ml=1,xl=1/0;ao.layout.hierarchy=function(){function n(i){var u,o=[i],a=[];for(i.depth=0;null!=(u=o.pop());)if(a.push(u),(c=e.call(n,u,u.depth))&&(l=c.length)){for(var l,c,f;--l>=0;)o.push(f=c[l]),f.parent=u,f.depth=u.depth+1;r&&(u.value=0),u.children=c}else r&&(u.value=+r.call(n,u,u.depth)||0),delete u.children;return oi(i,function(n){var e,i;t&&(e=n.children)&&e.sort(t),r&&(i=n.parent)&&(i.value+=n.value)}),a}var t=ci,e=ai,r=li;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(ui(t,function(n){n.children&&(n.value=0)}),oi(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ao.layout.partition=function(){function n(t,e,r,i){var u=t.children;if(t.x=e,t.y=t.depth*i,t.dx=r,t.dy=i,u&&(o=u.length)){var o,a,l,c=-1;for(r=t.value?r/t.value:0;++c<o;)n(a=u[c],e,l=a.value*r,i),e+=l}}function t(n){var e=n.children,r=0;if(e&&(i=e.length))for(var i,u=-1;++u<i;)r=Math.max(r,t(e[u]));return 1+r}function e(e,u){var o=r.call(this,e,u);return n(o[0],0,i[0],i[1]/t(o[0])),o}var r=ao.layout.hierarchy(),i=[1,1];return e.size=function(n){return arguments.length?(i=n,e):i},ii(e,r)},ao.layout.pie=function(){function n(o){var a,l=o.length,c=o.map(function(e,r){return+t.call(n,e,r)}),f=+("function"==typeof r?r.apply(this,arguments):r),s=("function"==typeof i?i.apply(this,arguments):i)-f,h=Math.min(Math.abs(s)/l,+("function"==typeof u?u.apply(this,arguments):u)),p=h*(0>s?-1:1),g=ao.sum(c),v=g?(s-l*p)/g:0,d=ao.range(l),y=[];return null!=e&&d.sort(e===bl?function(n,t){return c[t]-c[n]}:function(n,t){return e(o[n],o[t])}),d.forEach(function(n){y[n]={data:o[n],value:a=c[n],startAngle:f,endAngle:f+=a*v+p,padAngle:h}}),y}var t=Number,e=bl,r=0,i=Ho,u=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(i=t,n):i},n.padAngle=function(t){return arguments.length?(u=t,n):u},n};var bl={};ao.layout.stack=function(){function n(a,l){if(!(h=a.length))return a;var c=a.map(function(e,r){return t.call(n,e,r)}),f=c.map(function(t){return t.map(function(t,e){return[u.call(n,t,e),o.call(n,t,e)]})}),s=e.call(n,f,l);c=ao.permute(c,s),f=ao.permute(f,s);var h,p,g,v,d=r.call(n,f,l),y=c[0].length;for(g=0;y>g;++g)for(i.call(n,c[0][g],v=d[g],f[0][g][1]),p=1;h>p;++p)i.call(n,c[p][g],v+=f[p-1][g][1],f[p][g][1]);return a}var t=m,e=gi,r=vi,i=pi,u=si,o=hi;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:_l.get(t)||gi,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:wl.get(t)||vi,n):r},n.x=function(t){return arguments.length?(u=t,n):u},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(i=t,n):i},n};var _l=ao.map({"inside-out":function(n){var t,e,r=n.length,i=n.map(di),u=n.map(yi),o=ao.range(r).sort(function(n,t){return i[n]-i[t]}),a=0,l=0,c=[],f=[];for(t=0;r>t;++t)e=o[t],l>a?(a+=u[e],c.push(e)):(l+=u[e],f.push(e));return f.reverse().concat(c)},reverse:function(n){return ao.range(n.length).reverse()},"default":gi}),wl=ao.map({silhouette:function(n){var t,e,r,i=n.length,u=n[0].length,o=[],a=0,l=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;u>e;++e)l[e]=(a-o[e])/2;return l},wiggle:function(n){var t,e,r,i,u,o,a,l,c,f=n.length,s=n[0],h=s.length,p=[];for(p[0]=l=c=0,e=1;h>e;++e){for(t=0,i=0;f>t;++t)i+=n[t][e][1];for(t=0,u=0,a=s[e][0]-s[e-1][0];f>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;u+=o*n[t][e][1]}p[e]=l-=i?u/i*a:0,c>l&&(c=l)}for(e=0;h>e;++e)p[e]-=c;return p},expand:function(n){var t,e,r,i=n.length,u=n[0].length,o=1/i,a=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];if(r)for(t=0;i>t;t++)n[t][e][1]/=r;else for(t=0;i>t;t++)n[t][e][1]=o}for(e=0;u>e;++e)a[e]=0;return a},zero:vi});ao.layout.histogram=function(){function n(n,u){for(var o,a,l=[],c=n.map(e,this),f=r.call(this,c,u),s=i.call(this,f,c,u),u=-1,h=c.length,p=s.length-1,g=t?1:1/h;++u<p;)o=l[u]=[],o.dx=s[u+1]-(o.x=s[u]),o.y=0;if(p>0)for(u=-1;++u<h;)a=c[u],a>=f[0]&&a<=f[1]&&(o=l[ao.bisect(s,a,1,p)-1],o.y+=g,o.push(n[u]));return l}var t=!0,e=Number,r=bi,i=Mi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=En(t),n):r},n.bins=function(t){return arguments.length?(i="number"==typeof t?function(n){return xi(n,t)}:En(t),n):i},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ao.layout.pack=function(){function n(n,u){var o=e.call(this,n,u),a=o[0],l=i[0],c=i[1],f=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,oi(a,function(n){n.r=+f(n.value)}),oi(a,Ni),r){var s=r*(t?1:Math.max(2*a.r/l,2*a.r/c))/2;oi(a,function(n){n.r+=s}),oi(a,Ni),oi(a,function(n){n.r-=s})}return Ci(a,l/2,c/2,t?1:1/Math.max(2*a.r/l,2*a.r/c)),o}var t,e=ao.layout.hierarchy().sort(_i),r=0,i=[1,1];return n.size=function(t){return arguments.length?(i=t,n):i},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},ii(n,e)},ao.layout.tree=function(){function n(n,i){var f=o.call(this,n,i),s=f[0],h=t(s);if(oi(h,e),h.parent.m=-h.z,ui(h,r),c)ui(s,u);else{var p=s,g=s,v=s;ui(s,function(n){n.x<p.x&&(p=n),n.x>g.x&&(g=n),n.depth>v.depth&&(v=n)});var d=a(p,g)/2-p.x,y=l[0]/(g.x+a(g,p)/2+d),m=l[1]/(v.depth||1);ui(s,function(n){n.x=(n.x+d)*y,n.y=n.depth*m})}return f}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var i,u=t.children,o=0,a=u.length;a>o;++o)r.push((u[o]=i={_:u[o],parent:t,children:(i=u[o].children)&&i.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=i);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Di(n);var u=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-u):n.z=u}else r&&(n.z=r.z+a(n._,r._));n.parent.A=i(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function i(n,t,e){if(t){for(var r,i=n,u=n,o=t,l=i.parent.children[0],c=i.m,f=u.m,s=o.m,h=l.m;o=Ti(o),i=qi(i),o&&i;)l=qi(l),u=Ti(u),u.a=n,r=o.z+s-i.z-c+a(o._,i._),r>0&&(Ri(Pi(o,n,e),n,r),c+=r,f+=r),s+=o.m,c+=i.m,h+=l.m,f+=u.m;o&&!Ti(u)&&(u.t=o,u.m+=s-f),i&&!qi(l)&&(l.t=i,l.m+=c-h,e=n)}return e}function u(n){n.x*=l[0],n.y=n.depth*l[1]}var o=ao.layout.hierarchy().sort(null).value(null),a=Li,l=[1,1],c=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(c=null==(l=t)?u:null,n):c?null:l},n.nodeSize=function(t){return arguments.length?(c=null==(l=t)?null:u,n):c?l:null},ii(n,o)},ao.layout.cluster=function(){function n(n,u){var o,a=t.call(this,n,u),l=a[0],c=0;oi(l,function(n){var t=n.children;t&&t.length?(n.x=ji(t),n.y=Ui(t)):(n.x=o?c+=e(n,o):0,n.y=0,o=n)});var f=Fi(l),s=Hi(l),h=f.x-e(f,s)/2,p=s.x+e(s,f)/2;return oi(l,i?function(n){n.x=(n.x-l.x)*r[0],n.y=(l.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(p-h)*r[0],n.y=(1-(l.y?n.y/l.y:1))*r[1]}),a}var t=ao.layout.hierarchy().sort(null).value(null),e=Li,r=[1,1],i=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(i=null==(r=t),n):i?null:r},n.nodeSize=function(t){return arguments.length?(i=null!=(r=t),n):i?r:null},ii(n,t)},ao.layout.treemap=function(){function n(n,t){for(var e,r,i=-1,u=n.length;++i<u;)r=(e=n[i]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var u=e.children;if(u&&u.length){var o,a,l,c=s(e),f=[],h=u.slice(),g=1/0,v="slice"===p?c.dx:"dice"===p?c.dy:"slice-dice"===p?1&e.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(n(h,c.dx*c.dy/e.value),f.area=0;(l=h.length)>0;)f.push(o=h[l-1]),f.area+=o.area,"squarify"!==p||(a=r(f,v))<=g?(h.pop(),g=a):(f.area-=f.pop().area,i(f,v,c,!1),v=Math.min(c.dx,c.dy),f.length=f.area=0,g=1/0);f.length&&(i(f,v,c,!0),f.length=f.area=0),u.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var u,o=s(t),a=r.slice(),l=[];for(n(a,o.dx*o.dy/t.value),l.area=0;u=a.pop();)l.push(u),l.area+=u.area,null!=u.z&&(i(l,u.z?o.dx:o.dy,o,!a.length),l.length=l.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,i=0,u=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(u>e&&(u=e),e>i&&(i=e));return r*=r,t*=t,r?Math.max(t*i*g/r,r/(t*u*g)):1/0}function i(n,t,e,r){var i,u=-1,o=n.length,a=e.x,c=e.y,f=t?l(n.area/t):0;
+if(t==e.dx){for((r||f>e.dy)&&(f=e.dy);++u<o;)i=n[u],i.x=a,i.y=c,i.dy=f,a+=i.dx=Math.min(e.x+e.dx-a,f?l(i.area/f):0);i.z=!0,i.dx+=e.x+e.dx-a,e.y+=f,e.dy-=f}else{for((r||f>e.dx)&&(f=e.dx);++u<o;)i=n[u],i.x=a,i.y=c,i.dx=f,c+=i.dy=Math.min(e.y+e.dy-c,f?l(i.area/f):0);i.z=!1,i.dy+=e.y+e.dy-c,e.x+=f,e.dx-=f}}function u(r){var i=o||a(r),u=i[0];return u.x=u.y=0,u.value?(u.dx=c[0],u.dy=c[1]):u.dx=u.dy=0,o&&a.revalue(u),n([u],u.dx*u.dy/u.value),(o?e:t)(u),h&&(o=i),i}var o,a=ao.layout.hierarchy(),l=Math.round,c=[1,1],f=null,s=Oi,h=!1,p="squarify",g=.5*(1+Math.sqrt(5));return u.size=function(n){return arguments.length?(c=n,u):c},u.padding=function(n){function t(t){var e=n.call(u,t,t.depth);return null==e?Oi(t):Ii(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return Ii(t,n)}if(!arguments.length)return f;var r;return s=null==(f=n)?Oi:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,u},u.round=function(n){return arguments.length?(l=n?Math.round:Number,u):l!=Number},u.sticky=function(n){return arguments.length?(h=n,o=null,u):h},u.ratio=function(n){return arguments.length?(g=n,u):g},u.mode=function(n){return arguments.length?(p=n+"",u):p},ii(u,a)},ao.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,i;do e=2*Math.random()-1,r=2*Math.random()-1,i=e*e+r*r;while(!i||i>1);return n+t*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var n=ao.random.normal.apply(ao,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ao.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ao.scale={};var Sl={floor:m,ceil:m};ao.scale.linear=function(){return Wi([0,1],[0,1],Mr,!1)};var kl={s:1,g:1,p:1,r:1,e:1};ao.scale.log=function(){return ru(ao.scale.linear().domain([0,1]),10,!0,[1,10])};var Nl=ao.format(".0e"),El={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ao.scale.pow=function(){return iu(ao.scale.linear(),1,[0,1])},ao.scale.sqrt=function(){return ao.scale.pow().exponent(.5)},ao.scale.ordinal=function(){return ou([],{t:"range",a:[[]]})},ao.scale.category10=function(){return ao.scale.ordinal().range(Al)},ao.scale.category20=function(){return ao.scale.ordinal().range(Cl)},ao.scale.category20b=function(){return ao.scale.ordinal().range(zl)},ao.scale.category20c=function(){return ao.scale.ordinal().range(Ll)};var Al=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(xn),Cl=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(xn),zl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(xn),Ll=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(xn);ao.scale.quantile=function(){return au([],[])},ao.scale.quantize=function(){return lu(0,1,[0,1])},ao.scale.threshold=function(){return cu([.5],[0,1])},ao.scale.identity=function(){return fu([0,1])},ao.svg={},ao.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),c=Math.max(0,+r.apply(this,arguments)),f=o.apply(this,arguments)-Io,s=a.apply(this,arguments)-Io,h=Math.abs(s-f),p=f>s?0:1;if(n>c&&(g=c,c=n,n=g),h>=Oo)return t(c,p)+(n?t(n,1-p):"")+"Z";var g,v,d,y,m,M,x,b,_,w,S,k,N=0,E=0,A=[];if((y=(+l.apply(this,arguments)||0)/2)&&(d=u===ql?Math.sqrt(n*n+c*c):+u.apply(this,arguments),p||(E*=-1),c&&(E=tn(d/c*Math.sin(y))),n&&(N=tn(d/n*Math.sin(y)))),c){m=c*Math.cos(f+E),M=c*Math.sin(f+E),x=c*Math.cos(s-E),b=c*Math.sin(s-E);var C=Math.abs(s-f-2*E)<=Fo?0:1;if(E&&yu(m,M,x,b)===p^C){var z=(f+s)/2;m=c*Math.cos(z),M=c*Math.sin(z),x=b=null}}else m=M=0;if(n){_=n*Math.cos(s-N),w=n*Math.sin(s-N),S=n*Math.cos(f+N),k=n*Math.sin(f+N);var L=Math.abs(f-s+2*N)<=Fo?0:1;if(N&&yu(_,w,S,k)===1-p^L){var q=(f+s)/2;_=n*Math.cos(q),w=n*Math.sin(q),S=k=null}}else _=w=0;if(h>Uo&&(g=Math.min(Math.abs(c-n)/2,+i.apply(this,arguments)))>.001){v=c>n^p?0:1;var T=g,R=g;if(Fo>h){var D=null==S?[_,w]:null==x?[m,M]:Re([m,M],[S,k],[x,b],[_,w]),P=m-D[0],U=M-D[1],j=x-D[0],F=b-D[1],H=1/Math.sin(Math.acos((P*j+U*F)/(Math.sqrt(P*P+U*U)*Math.sqrt(j*j+F*F)))/2),O=Math.sqrt(D[0]*D[0]+D[1]*D[1]);R=Math.min(g,(n-O)/(H-1)),T=Math.min(g,(c-O)/(H+1))}if(null!=x){var I=mu(null==S?[_,w]:[S,k],[m,M],c,T,p),Y=mu([x,b],[_,w],c,T,p);g===T?A.push("M",I[0],"A",T,",",T," 0 0,",v," ",I[1],"A",c,",",c," 0 ",1-p^yu(I[1][0],I[1][1],Y[1][0],Y[1][1]),",",p," ",Y[1],"A",T,",",T," 0 0,",v," ",Y[0]):A.push("M",I[0],"A",T,",",T," 0 1,",v," ",Y[0])}else A.push("M",m,",",M);if(null!=S){var Z=mu([m,M],[S,k],n,-R,p),V=mu([_,w],null==x?[m,M]:[x,b],n,-R,p);g===R?A.push("L",V[0],"A",R,",",R," 0 0,",v," ",V[1],"A",n,",",n," 0 ",p^yu(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-p," ",Z[1],"A",R,",",R," 0 0,",v," ",Z[0]):A.push("L",V[0],"A",R,",",R," 0 0,",v," ",Z[0])}else A.push("L",_,",",w)}else A.push("M",m,",",M),null!=x&&A.push("A",c,",",c," 0 ",C,",",p," ",x,",",b),A.push("L",_,",",w),null!=S&&A.push("A",n,",",n," 0 ",L,",",1-p," ",S,",",k);return A.push("Z"),A.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=hu,r=pu,i=su,u=ql,o=gu,a=vu,l=du;return n.innerRadius=function(t){return arguments.length?(e=En(t),n):e},n.outerRadius=function(t){return arguments.length?(r=En(t),n):r},n.cornerRadius=function(t){return arguments.length?(i=En(t),n):i},n.padRadius=function(t){return arguments.length?(u=t==ql?ql:En(t),n):u},n.startAngle=function(t){return arguments.length?(o=En(t),n):o},n.endAngle=function(t){return arguments.length?(a=En(t),n):a},n.padAngle=function(t){return arguments.length?(l=En(t),n):l},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Io;return[Math.cos(t)*n,Math.sin(t)*n]},n};var ql="auto";ao.svg.line=function(){return Mu(m)};var Tl=ao.map({linear:xu,"linear-closed":bu,step:_u,"step-before":wu,"step-after":Su,basis:zu,"basis-open":Lu,"basis-closed":qu,bundle:Tu,cardinal:Eu,"cardinal-open":ku,"cardinal-closed":Nu,monotone:Fu});Tl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Rl=[0,2/3,1/3,0],Dl=[0,1/3,2/3,0],Pl=[0,1/6,2/3,1/6];ao.svg.line.radial=function(){var n=Mu(Hu);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},wu.reverse=Su,Su.reverse=wu,ao.svg.area=function(){return Ou(m)},ao.svg.area.radial=function(){var n=Ou(Hu);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ao.svg.chord=function(){function n(n,a){var l=t(this,u,n,a),c=t(this,o,n,a);return"M"+l.p0+r(l.r,l.p1,l.a1-l.a0)+(e(l,c)?i(l.r,l.p1,l.r,l.p0):i(l.r,l.p1,c.r,c.p0)+r(c.r,c.p1,c.a1-c.a0)+i(c.r,c.p1,l.r,l.p0))+"Z"}function t(n,t,e,r){var i=t.call(n,e,r),u=a.call(n,i,r),o=l.call(n,i,r)-Io,f=c.call(n,i,r)-Io;return{r:u,a0:o,a1:f,p0:[u*Math.cos(o),u*Math.sin(o)],p1:[u*Math.cos(f),u*Math.sin(f)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Fo)+",1 "+t}function i(n,t,e,r){return"Q 0,0 "+r}var u=Me,o=xe,a=Iu,l=gu,c=vu;return n.radius=function(t){return arguments.length?(a=En(t),n):a},n.source=function(t){return arguments.length?(u=En(t),n):u},n.target=function(t){return arguments.length?(o=En(t),n):o},n.startAngle=function(t){return arguments.length?(l=En(t),n):l},n.endAngle=function(t){return arguments.length?(c=En(t),n):c},n},ao.svg.diagonal=function(){function n(n,i){var u=t.call(this,n,i),o=e.call(this,n,i),a=(u.y+o.y)/2,l=[u,{x:u.x,y:a},{x:o.x,y:a},o];return l=l.map(r),"M"+l[0]+"C"+l[1]+" "+l[2]+" "+l[3]}var t=Me,e=xe,r=Yu;return n.source=function(e){return arguments.length?(t=En(e),n):t},n.target=function(t){return arguments.length?(e=En(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ao.svg.diagonal.radial=function(){var n=ao.svg.diagonal(),t=Yu,e=n.projection;return n.projection=function(n){return arguments.length?e(Zu(t=n)):t},n},ao.svg.symbol=function(){function n(n,r){return(Ul.get(t.call(this,n,r))||$u)(e.call(this,n,r))}var t=Xu,e=Vu;return n.type=function(e){return arguments.length?(t=En(e),n):t},n.size=function(t){return arguments.length?(e=En(t),n):e},n};var Ul=ao.map({circle:$u,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Fl)),e=t*Fl;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ao.svg.symbolTypes=Ul.keys();var jl=Math.sqrt(3),Fl=Math.tan(30*Yo);Co.transition=function(n){for(var t,e,r=Hl||++Zl,i=Ku(n),u=[],o=Ol||{time:Date.now(),ease:Nr,delay:0,duration:250},a=-1,l=this.length;++a<l;){u.push(t=[]);for(var c=this[a],f=-1,s=c.length;++f<s;)(e=c[f])&&Qu(e,f,i,r,o),t.push(e)}return Wu(u,i,r)},Co.interrupt=function(n){return this.each(null==n?Il:Bu(Ku(n)))};var Hl,Ol,Il=Bu(Ku()),Yl=[],Zl=0;Yl.call=Co.call,Yl.empty=Co.empty,Yl.node=Co.node,Yl.size=Co.size,ao.transition=function(n,t){return n&&n.transition?Hl?n.transition(t):n:ao.selection().transition(n)},ao.transition.prototype=Yl,Yl.select=function(n){var t,e,r,i=this.id,u=this.namespace,o=[];n=A(n);for(var a=-1,l=this.length;++a<l;){o.push(t=[]);for(var c=this[a],f=-1,s=c.length;++f<s;)(r=c[f])&&(e=n.call(r,r.__data__,f,a))?("__data__"in r&&(e.__data__=r.__data__),Qu(e,f,u,i,r[u][i]),t.push(e)):t.push(null)}return Wu(o,u,i)},Yl.selectAll=function(n){var t,e,r,i,u,o=this.id,a=this.namespace,l=[];n=C(n);for(var c=-1,f=this.length;++c<f;)for(var s=this[c],h=-1,p=s.length;++h<p;)if(r=s[h]){u=r[a][o],e=n.call(r,r.__data__,h,c),l.push(t=[]);for(var g=-1,v=e.length;++g<v;)(i=e[g])&&Qu(i,g,a,o,u),t.push(i)}return Wu(l,a,o)},Yl.filter=function(n){var t,e,r,i=[];"function"!=typeof n&&(n=O(n));for(var u=0,o=this.length;o>u;u++){i.push(t=[]);for(var e=this[u],a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return Wu(i,this.namespace,this.id)},Yl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(i){i[r][e].tween.set(n,t)})},Yl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function i(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function u(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?$r:Mr,a=ao.ns.qualify(n);return Ju(this,"attr."+n,t,a.local?u:i)},Yl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(i));return r&&function(n){this.setAttribute(i,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(i.space,i.local));return r&&function(n){this.setAttributeNS(i.space,i.local,r(n))}}var i=ao.ns.qualify(n);return this.tween("attr."+n,i.local?r:e)},Yl.style=function(n,e,r){function i(){this.style.removeProperty(n)}function u(e){return null==e?i:(e+="",function(){var i,u=t(this).getComputedStyle(this,null).getPropertyValue(n);return u!==e&&(i=Mr(u,e),function(t){this.style.setProperty(n,i(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Ju(this,"style."+n,e,u)},Yl.styleTween=function(n,e,r){function i(i,u){var o=e.call(this,i,u,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,i)},Yl.text=function(n){return Ju(this,"text",n,Gu)},Yl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Yl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ao.ease.apply(ao,arguments)),Y(this,function(r){r[e][t].ease=n}))},Yl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,i,u){r[e][t].delay=+n.call(r,r.__data__,i,u)}:(n=+n,function(r){r[e][t].delay=n}))},Yl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,i,u){r[e][t].duration=Math.max(1,n.call(r,r.__data__,i,u))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Yl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var i=Ol,u=Hl;try{Hl=e,Y(this,function(t,i,u){Ol=t[r][e],n.call(t,t.__data__,i,u)})}finally{Ol=i,Hl=u}}else Y(this,function(i){var u=i[r][e];(u.event||(u.event=ao.dispatch("start","end","interrupt"))).on(n,t)});return this},Yl.transition=function(){for(var n,t,e,r,i=this.id,u=++Zl,o=this.namespace,a=[],l=0,c=this.length;c>l;l++){a.push(n=[]);for(var t=this[l],f=0,s=t.length;s>f;f++)(e=t[f])&&(r=e[o][i],Qu(e,f,o,u,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Wu(a,o,u)},ao.svg.axis=function(){function n(n){n.each(function(){var n,c=ao.select(this),f=this.__chart__||e,s=this.__chart__=e.copy(),h=null==l?s.ticks?s.ticks.apply(s,a):s.domain():l,p=null==t?s.tickFormat?s.tickFormat.apply(s,a):m:t,g=c.selectAll(".tick").data(h,s),v=g.enter().insert("g",".domain").attr("class","tick").style("opacity",Uo),d=ao.transition(g.exit()).style("opacity",Uo).remove(),y=ao.transition(g.order()).style("opacity",1),M=Math.max(i,0)+o,x=Zi(s),b=c.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ao.transition(b));v.append("line"),v.append("text");var w,S,k,N,E=v.select("line"),A=y.select("line"),C=g.select("text").text(p),z=v.select("text"),L=y.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=no,w="x",k="y",S="x2",N="y2",C.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+q*u+"V0H"+x[1]+"V"+q*u)):(n=to,w="y",k="x",S="y2",N="x2",C.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),_.attr("d","M"+q*u+","+x[0]+"H0V"+x[1]+"H"+q*u)),E.attr(N,q*i),z.attr(k,q*M),A.attr(S,0).attr(N,q*i),L.attr(w,0).attr(k,q*M),s.rangeBand){var T=s,R=T.rangeBand()/2;f=s=function(n){return T(n)+R}}else f.rangeBand?f=s:d.call(n,s,f);v.call(n,f,s),y.call(n,s,s)})}var t,e=ao.scale.linear(),r=Vl,i=6,u=6,o=3,a=[10],l=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Xl?t+"":Vl,n):r},n.ticks=function(){return arguments.length?(a=co(arguments),n):a},n.tickValues=function(t){return arguments.length?(l=t,n):l},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(i=+t,u=+arguments[e-1],n):i},n.innerTickSize=function(t){return arguments.length?(i=+t,n):i},n.outerTickSize=function(t){return arguments.length?(u=+t,n):u},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Vl="bottom",Xl={top:1,right:1,bottom:1,left:1};ao.svg.brush=function(){function n(t){t.each(function(){var t=ao.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,m);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return $l[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,s=ao.transition(t),h=ao.transition(o);c&&(l=Zi(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),r(s)),f&&(l=Zi(f),h.attr("y",l[0]).attr("height",l[1]-l[0]),i(s)),e(s)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function i(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function u(){function u(){32==ao.event.keyCode&&(C||(M=null,L[0]-=s[1],L[1]-=h[1],C=2),S())}function v(){32==ao.event.keyCode&&2==C&&(L[0]+=s[1],L[1]+=h[1],C=0,S())}function d(){var n=ao.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ao.event.altKey?(M||(M=[(s[0]+s[1])/2,(h[0]+h[1])/2]),L[0]=s[+(n[0]<M[0])],L[1]=h[+(n[1]<M[1])]):M=null),E&&y(n,c,0)&&(r(k),t=!0),A&&y(n,f,1)&&(i(k),t=!0),t&&(e(k),w({type:"brush",mode:C?"move":"resize"}))}function y(n,t,e){var r,i,u=Zi(t),l=u[0],c=u[1],f=L[e],v=e?h:s,d=v[1]-v[0];return C&&(l-=f,c-=d+f),r=(e?g:p)?Math.max(l,Math.min(c,n[e])):n[e],C?i=(r+=f)+d:(M&&(f=Math.max(l,Math.min(c,2*M[e]-r))),r>f?(i=r,r=f):i=f),v[0]!=r||v[1]!=i?(e?a=null:o=null,v[0]=r,v[1]=i,!0):void 0}function m(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ao.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ao.select(ao.event.target),w=l.of(b,arguments),k=ao.select(b),N=_.datum(),E=!/^(n|s)$/.test(N)&&c,A=!/^(e|w)$/.test(N)&&f,C=_.classed("extent"),z=W(b),L=ao.mouse(b),q=ao.select(t(b)).on("keydown.brush",u).on("keyup.brush",v);if(ao.event.changedTouches?q.on("touchmove.brush",d).on("touchend.brush",m):q.on("mousemove.brush",d).on("mouseup.brush",m),k.interrupt().selectAll("*").interrupt(),C)L[0]=s[0]-L[0],L[1]=h[0]-L[1];else if(N){var T=+/w$/.test(N),R=+/^n/.test(N);x=[s[1-T]-L[0],h[1-R]-L[1]],L[0]=s[T],L[1]=h[R]}else ao.event.altKey&&(M=L.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ao.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,l=N(n,"brushstart","brush","brushend"),c=null,f=null,s=[0,0],h=[0,0],p=!0,g=!0,v=Bl[0];return n.event=function(n){n.each(function(){var n=l.of(this,arguments),t={x:s,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Hl?ao.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,s=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=xr(s,t.x),r=xr(h,t.y);return o=a=null,function(i){s=t.x=e(i),h=t.y=r(i),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,v=Bl[!c<<1|!f],n):c},n.y=function(t){return arguments.length?(f=t,v=Bl[!c<<1|!f],n):f},n.clamp=function(t){return arguments.length?(c&&f?(p=!!t[0],g=!!t[1]):c?p=!!t:f&&(g=!!t),n):c&&f?[p,g]:c?p:f?g:null},n.extent=function(t){var e,r,i,u,l;return arguments.length?(c&&(e=t[0],r=t[1],f&&(e=e[0],r=r[0]),o=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(l=e,e=r,r=l),e==s[0]&&r==s[1]||(s=[e,r])),f&&(i=t[0],u=t[1],c&&(i=i[1],u=u[1]),a=[i,u],f.invert&&(i=f(i),u=f(u)),i>u&&(l=i,i=u,u=l),i==h[0]&&u==h[1]||(h=[i,u])),n):(c&&(o?(e=o[0],r=o[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(l=e,e=r,r=l))),f&&(a?(i=a[0],u=a[1]):(i=h[0],u=h[1],f.invert&&(i=f.invert(i),u=f.invert(u)),i>u&&(l=i,i=u,u=l))),c&&f?[[e,i],[r,u]]:c?[e,r]:f&&[i,u])},n.clear=function(){return n.empty()||(s=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!f&&h[0]==h[1]},ao.rebind(n,l,"on")};var $l={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Bl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Wl=ga.format=xa.timeFormat,Jl=Wl.utc,Gl=Jl("%Y-%m-%dT%H:%M:%S.%LZ");Wl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?eo:Gl,eo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},eo.toString=Gl.toString,ga.second=On(function(n){return new va(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ga.seconds=ga.second.range,ga.seconds.utc=ga.second.utc.range,ga.minute=On(function(n){return new va(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ga.minutes=ga.minute.range,ga.minutes.utc=ga.minute.utc.range,ga.hour=On(function(n){var t=n.getTimezoneOffset()/60;return new va(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ga.hours=ga.hour.range,ga.hours.utc=ga.hour.utc.range,ga.month=On(function(n){return n=ga.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ga.months=ga.month.range,ga.months.utc=ga.month.utc.range;var Kl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Ql=[[ga.second,1],[ga.second,5],[ga.second,15],[ga.second,30],[ga.minute,1],[ga.minute,5],[ga.minute,15],[ga.minute,30],[ga.hour,1],[ga.hour,3],[ga.hour,6],[ga.hour,12],[ga.day,1],[ga.day,2],[ga.week,1],[ga.month,1],[ga.month,3],[ga.year,1]],nc=Wl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",zt]]),tc={range:function(n,t,e){return ao.range(Math.ceil(n/e)*e,+t,e).map(io)},floor:m,ceil:m};Ql.year=ga.year,ga.scale=function(){return ro(ao.scale.linear(),Ql,nc)};var ec=Ql.map(function(n){return[n[0].utc,n[1]]}),rc=Jl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",zt]]);ec.year=ga.year.utc,ga.scale.utc=function(){return ro(ao.scale.linear(),ec,rc)},ao.text=An(function(n){return n.responseText}),ao.json=function(n,t){return Cn(n,"application/json",uo,t)},ao.html=function(n,t){return Cn(n,"text/html",oo,t)},ao.xml=An(function(n){return n.responseXML}),"function"==typeof define&&define.amd?(this.d3=ao,define(ao)):"object"==typeof module&&module.exports?module.exports=ao:this.d3=ao}(); \ No newline at end of file
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/holder.min.js b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/holder.min.js
new file mode 100644
index 0000000..6bfc844
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/holder.min.js
@@ -0,0 +1,12 @@
+/*!
+
+Holder - client side image placeholders
+Version 2.7.1+6hydf
+© 2015 Ivan Malopinsky - http://imsky.co
+
+Site: http://holderjs.com
+Issues: https://github.com/imsky/holder/issues
+License: http://opensource.org/licenses/MIT
+
+*/
+!function(a){if(a.document){var b=a.document;b.querySelectorAll||(b.querySelectorAll=function(c){var d,e=b.createElement("style"),f=[];for(b.documentElement.firstChild.appendChild(e),b._qsa=[],e.styleSheet.cssText=c+"{x-qsa:expression(document._qsa && document._qsa.push(this))}",a.scrollBy(0,0),e.parentNode.removeChild(e);b._qsa.length;)d=b._qsa.shift(),d.style.removeAttribute("x-qsa"),f.push(d);return b._qsa=null,f}),b.querySelector||(b.querySelector=function(a){var c=b.querySelectorAll(a);return c.length?c[0]:null}),b.getElementsByClassName||(b.getElementsByClassName=function(a){return a=String(a).replace(/^|\s+/g,"."),b.querySelectorAll(a)}),Object.keys||(Object.keys=function(a){if(a!==Object(a))throw TypeError("Object.keys called on non-object");var b,c=[];for(b in a)Object.prototype.hasOwnProperty.call(a,b)&&c.push(b);return c}),function(a){var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";a.atob=a.atob||function(a){a=String(a);var c,d=0,e=[],f=0,g=0;if(a=a.replace(/\s/g,""),a.length%4===0&&(a=a.replace(/=+$/,"")),a.length%4===1)throw Error("InvalidCharacterError");if(/[^+/0-9A-Za-z]/.test(a))throw Error("InvalidCharacterError");for(;d<a.length;)c=b.indexOf(a.charAt(d)),f=f<<6|c,g+=6,24===g&&(e.push(String.fromCharCode(f>>16&255)),e.push(String.fromCharCode(f>>8&255)),e.push(String.fromCharCode(255&f)),g=0,f=0),d+=1;return 12===g?(f>>=4,e.push(String.fromCharCode(255&f))):18===g&&(f>>=2,e.push(String.fromCharCode(f>>8&255)),e.push(String.fromCharCode(255&f))),e.join("")},a.btoa=a.btoa||function(a){a=String(a);var c,d,e,f,g,h,i,j=0,k=[];if(/[^\x00-\xFF]/.test(a))throw Error("InvalidCharacterError");for(;j<a.length;)c=a.charCodeAt(j++),d=a.charCodeAt(j++),e=a.charCodeAt(j++),f=c>>2,g=(3&c)<<4|d>>4,h=(15&d)<<2|e>>6,i=63&e,j===a.length+2?(h=64,i=64):j===a.length+1&&(i=64),k.push(b.charAt(f),b.charAt(g),b.charAt(h),b.charAt(i));return k.join("")}}(a),Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(a){var b=this.__proto__||this.constructor.prototype;return a in this&&(!(a in b)||b[a]!==this[a])}),function(){if("performance"in a==!1&&(a.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in a.performance==!1){var b=Date.now();performance.timing&&performance.timing.navigationStart&&(b=performance.timing.navigationStart),a.performance.now=function(){return Date.now()-b}}}(),a.requestAnimationFrame||(a.webkitRequestAnimationFrame?!function(a){a.requestAnimationFrame=function(b){return webkitRequestAnimationFrame(function(){b(a.performance.now())})},a.cancelAnimationFrame=webkitCancelAnimationFrame}(a):a.mozRequestAnimationFrame?!function(a){a.requestAnimationFrame=function(b){return mozRequestAnimationFrame(function(){b(a.performance.now())})},a.cancelAnimationFrame=mozCancelAnimationFrame}(a):!function(a){a.requestAnimationFrame=function(b){return a.setTimeout(b,1e3/60)},a.cancelAnimationFrame=a.clearTimeout}(a))}}(this),function(a,b){"object"==typeof exports&&"object"==typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):"object"==typeof exports?exports.Holder=b():a.Holder=b()}(this,function(){return function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={exports:{},id:d,loaded:!1};return a[d].call(e.exports,e,e.exports,b),e.loaded=!0,e.exports}var c={};return b.m=a,b.c=c,b.p="",b(0)}([function(a,b,c){(function(b){function d(a,b,c,d){var f=e(c.substr(c.lastIndexOf(a.domain)),a);f&&h({mode:null,el:d,flags:f,engineSettings:b})}function e(a,b){var c={theme:B(J.settings.themes.gray,null),stylesheets:b.stylesheets,instanceOptions:b};return a.match(/([\d]+p?)x([\d]+p?)(?:\?|$)/)?f(a,c):g(a,c)}function f(a,b){var c=a.split("?"),d=c[0].split("/");b.holderURL=a;var e=d[1],f=e.match(/([\d]+p?)x([\d]+p?)/);if(!f)return!1;if(b.fluid=-1!==e.indexOf("p"),b.dimensions={width:f[1].replace("p","%"),height:f[2].replace("p","%")},2===c.length){var g=A.parse(c[1]);if(g.bg&&(b.theme.background=(-1===g.bg.indexOf("#")?"#":"")+g.bg),g.fg&&(b.theme.foreground=(-1===g.fg.indexOf("#")?"#":"")+g.fg),g.theme&&b.instanceOptions.themes.hasOwnProperty(g.theme)&&(b.theme=B(b.instanceOptions.themes[g.theme],null)),g.text&&(b.text=g.text),g.textmode&&(b.textmode=g.textmode),g.size&&(b.size=g.size),g.font&&(b.font=g.font),g.align&&(b.align=g.align),b.nowrap=z.truthy(g.nowrap),b.auto=z.truthy(g.auto),z.truthy(g.random)){J.vars.cache.themeKeys=J.vars.cache.themeKeys||Object.keys(b.instanceOptions.themes);var h=J.vars.cache.themeKeys[0|Math.random()*J.vars.cache.themeKeys.length];b.theme=B(b.instanceOptions.themes[h],null)}}return b}function g(a,b){var c=!1,d=String.fromCharCode(11),e=a.replace(/([^\\])\//g,"$1"+d).split(d),f=/%[0-9a-f]{2}/gi,g=b.instanceOptions;b.holderURL=[];for(var h=e.length,i=0;h>i;i++){var j=e[i];if(j.match(f))try{j=decodeURIComponent(j)}catch(k){j=e[i]}var l=!1;if(J.flags.dimensions.match(j))c=!0,b.dimensions=J.flags.dimensions.output(j),l=!0;else if(J.flags.fluid.match(j))c=!0,b.dimensions=J.flags.fluid.output(j),b.fluid=!0,l=!0;else if(J.flags.textmode.match(j))b.textmode=J.flags.textmode.output(j),l=!0;else if(J.flags.colors.match(j)){var m=J.flags.colors.output(j);b.theme=B(b.theme,m),l=!0}else if(g.themes[j])g.themes.hasOwnProperty(j)&&(b.theme=B(g.themes[j],null)),l=!0;else if(J.flags.font.match(j))b.font=J.flags.font.output(j),l=!0;else if(J.flags.auto.match(j))b.auto=!0,l=!0;else if(J.flags.text.match(j))b.text=J.flags.text.output(j),l=!0;else if(J.flags.size.match(j))b.size=J.flags.size.output(j),l=!0;else if(J.flags.random.match(j)){null==J.vars.cache.themeKeys&&(J.vars.cache.themeKeys=Object.keys(g.themes));var n=J.vars.cache.themeKeys[0|Math.random()*J.vars.cache.themeKeys.length];b.theme=B(g.themes[n],null),l=!0}l&&b.holderURL.push(j)}return b.holderURL.unshift(g.domain),b.holderURL=b.holderURL.join("/"),c?b:!1}function h(a){var b=a.mode,c=a.el,d=a.flags,e=a.engineSettings,f=d.dimensions,g=d.theme,h=f.width+"x"+f.height;if(b=null==b?d.fluid?"fluid":"image":b,null!=d.text&&(g.text=d.text,"object"===c.nodeName.toLowerCase())){for(var j=g.text.split("\\n"),k=0;k<j.length;k++)j[k]=z.encodeHtmlEntity(j[k]);g.text=j.join("\\n")}var n=d.holderURL,o=B(e,null);if(d.font&&(g.font=d.font,!o.noFontFallback&&"img"===c.nodeName.toLowerCase()&&J.setup.supportsCanvas&&"svg"===o.renderer&&(o=B(o,{renderer:"canvas"}))),d.font&&"canvas"==o.renderer&&(o.reRender=!0),"background"==b)null==c.getAttribute("data-background-src")&&r(c,{"data-background-src":n});else{var p={};p[J.vars.dataAttr]=n,r(c,p)}d.theme=g,c.holderData={flags:d,engineSettings:o},("image"==b||"fluid"==b)&&r(c,{alt:g.text?g.text+" ["+h+"]":h});var q={mode:b,el:c,holderSettings:{dimensions:f,theme:g,flags:d},engineSettings:o};"image"==b?("html"!=o.renderer&&d.auto||(c.style.width=f.width+"px",c.style.height=f.height+"px"),"html"==o.renderer?c.style.backgroundColor=g.background:(i(q),"exact"==d.textmode&&(c.holderData.resizeUpdate=!0,J.vars.resizableImages.push(c),l(c)))):"background"==b&&"html"!=o.renderer?i(q):"fluid"==b&&(c.holderData.resizeUpdate=!0,"%"==f.height.slice(-1)?c.style.height=f.height:null!=d.auto&&d.auto||(c.style.height=f.height+"px"),"%"==f.width.slice(-1)?c.style.width=f.width:null!=d.auto&&d.auto||(c.style.width=f.width+"px"),("inline"==c.style.display||""===c.style.display||"none"==c.style.display)&&(c.style.display="block"),m(c),"html"==o.renderer?c.style.backgroundColor=g.background:(J.vars.resizableImages.push(c),l(c)))}function i(a){function c(){var b=null;switch(h.renderer){case"canvas":b=L(k,a);break;case"svg":b=M(k,a);break;default:throw"Holder: invalid renderer: "+h.renderer}return b}var d=null,e=a.mode,f=a.holderSettings,g=a.el,h=a.engineSettings;switch(h.renderer){case"svg":if(!J.setup.supportsSVG)return;break;case"canvas":if(!J.setup.supportsCanvas)return;break;default:return}var i={width:f.dimensions.width,height:f.dimensions.height,theme:f.theme,flags:f.flags},k=j(i);if(d=c(),null==d)throw"Holder: couldn't render placeholder";"background"==e?(g.style.backgroundImage="url("+d+")",g.style.backgroundSize=i.width+"px "+i.height+"px"):("img"===g.nodeName.toLowerCase()?r(g,{src:d}):"object"===g.nodeName.toLowerCase()&&(r(g,{data:d}),r(g,{type:"image/svg+xml"})),h.reRender&&b.setTimeout(function(){var a=c();if(null==a)throw"Holder: couldn't render placeholder";"img"===g.nodeName.toLowerCase()?r(g,{src:a}):"object"===g.nodeName.toLowerCase()&&(r(g,{data:a}),r(g,{type:"image/svg+xml"}))},100)),r(g,{"data-holder-rendered":!0})}function j(a){function b(a,b,c,d){b.width=c,b.height=d,a.width=Math.max(a.width,b.width),a.height+=b.height}var c=J.defaults.size;switch(parseFloat(a.theme.size)?c=a.theme.size:parseFloat(a.flags.size)&&(c=a.flags.size),a.font={family:a.theme.font?a.theme.font:"Arial, Helvetica, Open Sans, sans-serif",size:k(a.width,a.height,c),units:a.theme.units?a.theme.units:J.defaults.units,weight:a.theme.fontweight?a.theme.fontweight:"bold"},a.text=a.theme.text||Math.floor(a.width)+"x"+Math.floor(a.height),a.noWrap=a.theme.nowrap||a.flags.nowrap,a.align=a.theme.align||a.flags.align||"center",a.flags.textmode){case"literal":a.text=a.flags.dimensions.width+"x"+a.flags.dimensions.height;break;case"exact":if(!a.flags.exactDimensions)break;a.text=Math.floor(a.flags.exactDimensions.width)+"x"+Math.floor(a.flags.exactDimensions.height)}var d=new y({width:a.width,height:a.height}),e=d.Shape,f=new e.Rect("holderBg",{fill:a.theme.background});f.resize(a.width,a.height),d.root.add(f);var g=new e.Group("holderTextGroup",{text:a.text,align:a.align,font:a.font,fill:a.theme.foreground});g.moveTo(null,null,1),d.root.add(g);var h=g.textPositionData=K(d);if(!h)throw"Holder: staging fallback not supported yet.";g.properties.leading=h.boundingBox.height;var i=null,j=null,l=a.width*J.setup.lineWrapRatio,m=l;if(h.lineCount>1){var n,o=0,p=0,q=0;j=new e.Group("line"+q),("left"===a.align||"right"===a.align)&&(m=a.width*(1-2*(1-J.setup.lineWrapRatio)));for(var r=0;r<h.words.length;r++){var s=h.words[r];i=new e.Text(s.text);var t="\\n"==s.text;!a.noWrap&&(o+s.width>=m||t===!0)&&(b(g,j,o,g.properties.leading),g.add(j),o=0,p+=g.properties.leading,q+=1,j=new e.Group("line"+q),j.y=p),t!==!0&&(i.moveTo(o,0),o+=h.spaceWidth+s.width,j.add(i))}if(b(g,j,o,g.properties.leading),g.add(j),"left"===a.align)g.moveTo(a.width-l,null,null);else if("right"===a.align){for(n in g.children)j=g.children[n],j.moveTo(a.width-j.width,null,null);g.moveTo(0-(a.width-l),null,null)}else{for(n in g.children)j=g.children[n],j.moveTo((g.width-j.width)/2,null,null);g.moveTo((a.width-g.width)/2,null,null)}g.moveTo(null,(a.height-g.height)/2,null),(a.height-g.height)/2<0&&g.moveTo(null,0,null)}else i=new e.Text(a.text),j=new e.Group("line0"),j.add(i),g.add(j),"left"===a.align?g.moveTo(a.width-l,null,null):"right"===a.align?g.moveTo(0-(a.width-l),null,null):g.moveTo((a.width-h.boundingBox.width)/2,null,null),g.moveTo(null,(a.height-h.boundingBox.height)/2,null);return d}function k(a,b,c){var d=parseInt(a,10),e=parseInt(b,10),f=Math.max(d,e),g=Math.min(d,e),h=.8*Math.min(g,f*J.defaults.scale);return Math.round(Math.max(c,h))}function l(a){var b;b=null==a||null==a.nodeType?J.vars.resizableImages:[a];for(var c=0,d=b.length;d>c;c++){var e=b[c];if(e.holderData){var f=e.holderData.flags,g=D(e);if(g){if(!e.holderData.resizeUpdate)continue;if(f.fluid&&f.auto){var h=e.holderData.fluidConfig;switch(h.mode){case"width":g.height=g.width/h.ratio;break;case"height":g.width=g.height*h.ratio}}var j={mode:"image",holderSettings:{dimensions:g,theme:f.theme,flags:f},el:e,engineSettings:e.holderData.engineSettings};"exact"==f.textmode&&(f.exactDimensions=g,j.holderSettings.dimensions=f.dimensions),i(j)}else p(e)}}}function m(a){if(a.holderData){var b=D(a);if(b){var c=a.holderData.flags,d={fluidHeight:"%"==c.dimensions.height.slice(-1),fluidWidth:"%"==c.dimensions.width.slice(-1),mode:null,initialDimensions:b};d.fluidWidth&&!d.fluidHeight?(d.mode="width",d.ratio=d.initialDimensions.width/parseFloat(c.dimensions.height)):!d.fluidWidth&&d.fluidHeight&&(d.mode="height",d.ratio=parseFloat(c.dimensions.width)/d.initialDimensions.height),a.holderData.fluidConfig=d}else p(a)}}function n(){for(var a,c=[],d=Object.keys(J.vars.invisibleImages),e=0,f=d.length;f>e;e++)a=J.vars.invisibleImages[d[e]],D(a)&&"img"==a.nodeName.toLowerCase()&&(c.push(a),delete J.vars.invisibleImages[d[e]]);c.length&&I.run({images:c}),b.requestAnimationFrame(n)}function o(){J.vars.visibilityCheckStarted||(b.requestAnimationFrame(n),J.vars.visibilityCheckStarted=!0)}function p(a){a.holderData.invisibleId||(J.vars.invisibleId+=1,J.vars.invisibleImages["i"+J.vars.invisibleId]=a,a.holderData.invisibleId=J.vars.invisibleId)}function q(a,b){return null==b?document.createElement(a):document.createElementNS(b,a)}function r(a,b){for(var c in b)a.setAttribute(c,b[c])}function s(a,b,c){var d,e;null==a?(a=q("svg",E),d=q("defs",E),e=q("style",E),r(e,{type:"text/css"}),d.appendChild(e),a.appendChild(d)):e=a.querySelector("style"),a.webkitMatchesSelector&&a.setAttribute("xmlns",E);for(var f=0;f<a.childNodes.length;f++)a.childNodes[f].nodeType===F&&a.removeChild(a.childNodes[f]);for(;e.childNodes.length;)e.removeChild(e.childNodes[0]);return r(a,{width:b,height:c,viewBox:"0 0 "+b+" "+c,preserveAspectRatio:"none"}),a}function t(a,c){if(b.XMLSerializer){var d=new XMLSerializer,e="",f=c.stylesheets;if(c.svgXMLStylesheet){for(var g=u(),h=f.length-1;h>=0;h--){var i=g.createProcessingInstruction("xml-stylesheet",'href="'+f[h]+'" rel="stylesheet"');g.insertBefore(i,g.firstChild)}g.removeChild(g.documentElement),e=d.serializeToString(g)}var j=d.serializeToString(a);return j=j.replace(/\&amp;(\#[0-9]{2,}\;)/g,"&$1"),e+j}}function u(){return b.DOMParser?(new DOMParser).parseFromString("<xml />","application/xml"):void 0}function v(a){J.vars.debounceTimer||a.call(this),J.vars.debounceTimer&&b.clearTimeout(J.vars.debounceTimer),J.vars.debounceTimer=b.setTimeout(function(){J.vars.debounceTimer=null,a.call(this)},J.setup.debounce)}function w(){v(function(){l(null)})}var x=c(1),y=c(2),z=c(3),A=c(4),B=z.extend,C=z.getNodeArray,D=z.dimensionCheck,E="http://www.w3.org/2000/svg",F=8,G="2.7.1",H="\nCreated with Holder.js "+G+".\nLearn more at http://holderjs.com\n(c) 2012-2015 Ivan Malopinsky - http://imsky.co\n",I={version:G,addTheme:function(a,b){return null!=a&&null!=b&&(J.settings.themes[a]=b),delete J.vars.cache.themeKeys,this},addImage:function(a,b){var c=document.querySelectorAll(b);if(c.length)for(var d=0,e=c.length;e>d;d++){var f=q("img"),g={};g[J.vars.dataAttr]=a,r(f,g),c[d].appendChild(f)}return this},setResizeUpdate:function(a,b){a.holderData&&(a.holderData.resizeUpdate=!!b,a.holderData.resizeUpdate&&l(a))},run:function(a){a=a||{};var c={},f=B(J.settings,a);J.vars.preempted=!0,J.vars.dataAttr=f.dataAttr||J.vars.dataAttr,c.renderer=f.renderer?f.renderer:J.setup.renderer,-1===J.setup.renderers.join(",").indexOf(c.renderer)&&(c.renderer=J.setup.supportsSVG?"svg":J.setup.supportsCanvas?"canvas":"html");var g=C(f.images),i=C(f.bgnodes),j=C(f.stylenodes),k=C(f.objects);c.stylesheets=[],c.svgXMLStylesheet=!0,c.noFontFallback=f.noFontFallback?f.noFontFallback:!1;for(var l=0;l<j.length;l++){var m=j[l];if(m.attributes.rel&&m.attributes.href&&"stylesheet"==m.attributes.rel.value){var n=m.attributes.href.value,o=q("a");o.href=n;var p=o.protocol+"//"+o.host+o.pathname+o.search;c.stylesheets.push(p)}}for(l=0;l<i.length;l++)if(b.getComputedStyle){var r=b.getComputedStyle(i[l],null).getPropertyValue("background-image"),s=i[l].getAttribute("data-background-src"),t=null;t=null==s?r:s;var u=null,v="?"+f.domain+"/";if(0===t.indexOf(v))u=t.slice(1);else if(-1!=t.indexOf(v)){var w=t.substr(t.indexOf(v)).slice(1),x=w.match(/([^\"]*)"?\)/);null!=x&&(u=x[1])}if(null!=u){var y=e(u,f);y&&h({mode:"background",el:i[l],flags:y,engineSettings:c})}}for(l=0;l<k.length;l++){var A=k[l],D={};try{D.data=A.getAttribute("data"),D.dataSrc=A.getAttribute(J.vars.dataAttr)}catch(E){}var F=null!=D.data&&0===D.data.indexOf(f.domain),G=null!=D.dataSrc&&0===D.dataSrc.indexOf(f.domain);F?d(f,c,D.data,A):G&&d(f,c,D.dataSrc,A)}for(l=0;l<g.length;l++){var H=g[l],I={};try{I.src=H.getAttribute("src"),I.dataSrc=H.getAttribute(J.vars.dataAttr),I.rendered=H.getAttribute("data-holder-rendered")}catch(E){}var K=null!=I.src,L=null!=I.dataSrc&&0===I.dataSrc.indexOf(f.domain),M=null!=I.rendered&&"true"==I.rendered;K?0===I.src.indexOf(f.domain)?d(f,c,I.src,H):L&&(M?d(f,c,I.dataSrc,H):!function(a,b,c,e,f){z.imageExists(a,function(a){a||d(b,c,e,f)})}(I.src,f,c,I.dataSrc,H)):L&&d(f,c,I.dataSrc,H)}return this}},J={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",stylesheets:[],themes:{gray:{background:"#EEEEEE",foreground:"#AAAAAA"},social:{background:"#3a5a97",foreground:"#FFFFFF"},industrial:{background:"#434A52",foreground:"#C2F200"},sky:{background:"#0D8FDB",foreground:"#FFFFFF"},vine:{background:"#39DBAC",foreground:"#1E292C"},lava:{background:"#F8591A",foreground:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16},flags:{dimensions:{regex:/^(\d+)x(\d+)$/,output:function(a){var b=this.regex.exec(a);return{width:+b[1],height:+b[2]}}},fluid:{regex:/^([0-9]+%?)x([0-9]+%?)$/,output:function(a){var b=this.regex.exec(a);return{width:b[1],height:b[2]}}},colors:{regex:/(?:#|\^)([0-9a-f]{3,})\:(?:#|\^)([0-9a-f]{3,})/i,output:function(a){var b=this.regex.exec(a);return{foreground:"#"+b[2],background:"#"+b[1]}}},text:{regex:/text\:(.*)/,output:function(a){return this.regex.exec(a)[1].replace("\\/","/")}},font:{regex:/font\:(.*)/,output:function(a){return this.regex.exec(a)[1]}},auto:{regex:/^auto$/},textmode:{regex:/textmode\:(.*)/,output:function(a){return this.regex.exec(a)[1]}},random:{regex:/^random$/},size:{regex:/size\:(\d+)/,output:function(a){return this.regex.exec(a)[1]}}}},K=function(){var a=null,b=null,c=null;return function(d){var e=d.root;if(J.setup.supportsSVG){var f=!1,g=function(a){return document.createTextNode(a)};(null==a||a.parentNode!==document.body)&&(f=!0),a=s(a,e.properties.width,e.properties.height),a.style.display="block",f&&(b=q("text",E),c=g(null),r(b,{x:0}),b.appendChild(c),a.appendChild(b),document.body.appendChild(a),a.style.visibility="hidden",a.style.position="absolute",a.style.top="-100%",a.style.left="-100%");var h=e.children.holderTextGroup,i=h.properties;r(b,{y:i.font.size,style:z.cssProps({"font-weight":i.font.weight,"font-size":i.font.size+i.font.units,"font-family":i.font.family})}),c.nodeValue=i.text;var j=b.getBBox(),k=Math.ceil(j.width/(e.properties.width*J.setup.lineWrapRatio)),l=i.text.split(" "),m=i.text.match(/\\n/g);k+=null==m?0:m.length,c.nodeValue=i.text.replace(/[ ]+/g,"");var n=b.getComputedTextLength(),o=j.width-n,p=Math.round(o/Math.max(1,l.length-1)),t=[];if(k>1){c.nodeValue="";for(var u=0;u<l.length;u++)if(0!==l[u].length){c.nodeValue=z.decodeHtmlEntity(l[u]);var v=b.getBBox();t.push({text:l[u],width:v.width})}}return a.style.display="none",{spaceWidth:p,lineCount:k,boundingBox:j,words:t}}return!1}}(),L=function(){var a=q("canvas"),b=null;return function(c){null==b&&(b=a.getContext("2d"));var d=c.root;a.width=J.dpr(d.properties.width),a.height=J.dpr(d.properties.height),b.textBaseline="middle",b.fillStyle=d.children.holderBg.properties.fill,b.fillRect(0,0,J.dpr(d.children.holderBg.width),J.dpr(d.children.holderBg.height));{var e=d.children.holderTextGroup;e.properties}b.font=e.properties.font.weight+" "+J.dpr(e.properties.font.size)+e.properties.font.units+" "+e.properties.font.family+", monospace",b.fillStyle=e.properties.fill;for(var f in e.children){var g=e.children[f];for(var h in g.children){var i=g.children[h],j=J.dpr(e.x+g.x+i.x),k=J.dpr(e.y+g.y+i.y+e.properties.leading/2);b.fillText(i.properties.text,j,k)}}return a.toDataURL("image/png")}}(),M=function(){if(b.XMLSerializer){var a=u(),c=s(null,0,0),d=q("rect",E);return c.appendChild(d),function(b,e){var f=b.root;s(c,f.properties.width,f.properties.height);for(var g=c.querySelectorAll("g"),h=0;h<g.length;h++)g[h].parentNode.removeChild(g[h]);var i=e.holderSettings.flags.holderURL,j="holder_"+(Number(new Date)+32768+(0|32768*Math.random())).toString(16),k=q("g",E),l=f.children.holderTextGroup,m=l.properties,n=q("g",E),o=l.textPositionData,p="#"+j+" text { "+z.cssProps({fill:m.fill,"font-weight":m.font.weight,"font-family":m.font.family+", monospace","font-size":m.font.size+m.font.units})+" } ",u=a.createComment("\nSource URL: "+i+H),v=a.createCDATASection(p),w=c.querySelector("style");r(k,{id:j}),c.insertBefore(u,c.firstChild),w.appendChild(v),k.appendChild(d),k.appendChild(n),c.appendChild(k),r(d,{width:f.children.holderBg.width,height:f.children.holderBg.height,fill:f.children.holderBg.properties.fill}),l.y+=.8*o.boundingBox.height;for(var x in l.children){var y=l.children[x];for(var A in y.children){var B=y.children[A],C=l.x+y.x+B.x,D=l.y+y.y+B.y,F=q("text",E),G=document.createTextNode(null);r(F,{x:C,y:D}),G.nodeValue=B.properties.text,F.appendChild(G),n.appendChild(F)}}var I=N(t(c,e.engineSettings),"background"===e.mode);return I}}}(),N=function(){var a="data:image/svg+xml;charset=UTF-8,",b="data:image/svg+xml;charset=UTF-8;base64,";return function(c,d){return d?b+btoa(unescape(encodeURIComponent(c))):a+encodeURIComponent(c)}}();for(var O in J.flags)J.flags.hasOwnProperty(O)&&(J.flags[O].match=function(a){return a.match(this.regex)});J.setup={renderer:"html",debounce:100,ratio:1,supportsCanvas:!1,supportsSVG:!1,lineWrapRatio:.9,renderers:["html","canvas","svg"]},J.dpr=function(a){return a*J.setup.ratio},J.vars={preempted:!1,resizableImages:[],invisibleImages:{},invisibleId:0,visibilityCheckStarted:!1,debounceTimer:null,cache:{},dataAttr:"data-src"},function(){var a=1,c=1,d=q("canvas"),e=null;d.getContext&&-1!=d.toDataURL("image/png").indexOf("data:image/png")&&(J.setup.renderer="canvas",e=d.getContext("2d"),J.setup.supportsCanvas=!0),J.setup.supportsCanvas&&(a=b.devicePixelRatio||1,c=e.webkitBackingStorePixelRatio||e.mozBackingStorePixelRatio||e.msBackingStorePixelRatio||e.oBackingStorePixelRatio||e.backingStorePixelRatio||1),J.setup.ratio=a/c,document.createElementNS&&document.createElementNS(E,"svg").createSVGRect&&(J.setup.renderer="svg",J.setup.supportsSVG=!0)}(),o(),x&&x(function(){J.vars.preempted||I.run(),b.addEventListener?(b.addEventListener("resize",w,!1),b.addEventListener("orientationchange",w,!1)):b.attachEvent("onresize",w),"object"==typeof b.Turbolinks&&b.document.addEventListener("page:change",function(){I.run()})}),a.exports=I}).call(b,function(){return this}())},function(a){function b(a){function b(a){if(!v){if(!g.body)return e(b);for(v=!0;a=w.shift();)e(a)}}function c(a){(t||a.type===i||g[m]===l)&&(d(),b())}function d(){t?(g[s](q,c,j),a[s](i,c,j)):(g[o](r,c),a[o](k,c))}function e(a,b){setTimeout(a,+b>=0?b:1)}function f(a){v?e(a):w.push(a)}null==document.readyState&&document.addEventListener&&(document.addEventListener("DOMContentLoaded",function y(){document.removeEventListener("DOMContentLoaded",y,!1),document.readyState="complete"},!1),document.readyState="loading");var g=a.document,h=g.documentElement,i="load",j=!1,k="on"+i,l="complete",m="readyState",n="attachEvent",o="detachEvent",p="addEventListener",q="DOMContentLoaded",r="onreadystatechange",s="removeEventListener",t=p in g,u=j,v=j,w=[];if(g[m]===l)e(b);else if(t)g[p](q,c,j),a[p](i,c,j);else{g[n](r,c),a[n](k,c);try{u=null==a.frameElement&&h}catch(x){}u&&u.doScroll&&!function z(){if(!v){try{u.doScroll("left")}catch(a){return e(z,50)}d(),b()}}()}return f.version="1.4.0",f.isReady=function(){return v},f}a.exports="undefined"!=typeof window&&b(window)},function(a,b,c){var d=c(5),e=function(a){function b(a,b){for(var c in b)a[c]=b[c];return a}var c=1,e=d.defclass({constructor:function(a){c++,this.parent=null,this.children={},this.id=c,this.name="n"+c,null!=a&&(this.name=a),this.x=0,this.y=0,this.z=0,this.width=0,this.height=0},resize:function(a,b){null!=a&&(this.width=a),null!=b&&(this.height=b)},moveTo:function(a,b,c){this.x=null!=a?a:this.x,this.y=null!=b?b:this.y,this.z=null!=c?c:this.z},add:function(a){var b=a.name;if(null!=this.children[b])throw"SceneGraph: child with that name already exists: "+b;this.children[b]=a,a.parent=this}}),f=d(e,function(b){this.constructor=function(){b.constructor.call(this,"root"),this.properties=a}}),g=d(e,function(a){function c(c,d){if(a.constructor.call(this,c),this.properties={fill:"#000"},null!=d)b(this.properties,d);else if(null!=c&&"string"!=typeof c)throw"SceneGraph: invalid node name"}this.Group=d.extend(this,{constructor:c,type:"group"}),this.Rect=d.extend(this,{constructor:c,type:"rect"}),this.Text=d.extend(this,{constructor:function(a){c.call(this),this.properties.text=a},type:"text"})}),h=new f;return this.Shape=g,this.root=h,this};a.exports=e},function(a,b){(function(a){b.extend=function(a,b){var c={};for(var d in a)a.hasOwnProperty(d)&&(c[d]=a[d]);if(null!=b)for(var e in b)b.hasOwnProperty(e)&&(c[e]=b[e]);return c},b.cssProps=function(a){var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(c+":"+a[c]);return b.join(";")},b.encodeHtmlEntity=function(a){for(var b=[],c=0,d=a.length-1;d>=0;d--)c=a.charCodeAt(d),b.unshift(c>128?["&#",c,";"].join(""):a[d]);return b.join("")},b.getNodeArray=function(b){var c=null;return"string"==typeof b?c=document.querySelectorAll(b):a.NodeList&&b instanceof a.NodeList?c=b:a.Node&&b instanceof a.Node?c=[b]:a.HTMLCollection&&b instanceof a.HTMLCollection?c=b:b instanceof Array?c=b:null===b&&(c=[]),c},b.imageExists=function(a,b){var c=new Image;c.onerror=function(){b.call(this,!1)},c.onload=function(){b.call(this,!0)},c.src=a},b.decodeHtmlEntity=function(a){return a.replace(/&#(\d+);/g,function(a,b){return String.fromCharCode(b)})},b.dimensionCheck=function(a){var b={height:a.clientHeight,width:a.clientWidth};return b.height&&b.width?b:!1},b.truthy=function(a){return"string"==typeof a?"true"===a||"yes"===a||"1"===a||"on"===a||"✓"===a:!!a}}).call(b,function(){return this}())},function(a,b,c){var d=encodeURIComponent,e=decodeURIComponent,f=c(6),g=c(7),h=/(\w+)\[(\d+)\]/,i=/\w+\.\w+/;b.parse=function(a){if("string"!=typeof a)return{};if(a=f(a),""===a)return{};"?"===a.charAt(0)&&(a=a.slice(1));for(var b={},c=a.split("&"),d=0;d<c.length;d++){var g,j,k,l=c[d].split("="),m=e(l[0]);if(g=h.exec(m))b[g[1]]=b[g[1]]||[],b[g[1]][g[2]]=e(l[1]);else if(g=i.test(m)){for(g=m.split("."),j=b;g.length;)if(k=g.shift(),k.length){if(j[k]){if(j[k]&&"object"!=typeof j[k])break}else j[k]={};g.length||(j[k]=e(l[1])),j=j[k]}}else b[l[0]]=null==l[1]?"":e(l[1])}return b},b.stringify=function(a){if(!a)return"";var b=[];for(var c in a){var e=a[c];if("array"!=g(e))b.push(d(c)+"="+d(a[c]));else for(var f=0;f<e.length;++f)b.push(d(c+"["+f+"]")+"="+d(e[f]))}return b.join("&")}},function(a){var b=function(){},c=Array.prototype.slice,d=function(a,d){var e=b.prototype="function"==typeof a?a.prototype:a,f=new b,g=d.apply(f,c.call(arguments,2).concat(e));if("object"==typeof g)for(var h in g)f[h]=g[h];if(!f.hasOwnProperty("constructor"))return f;var i=f.constructor;return i.prototype=f,i};d.defclass=function(a){var b=a.constructor;return b.prototype=a,b},d.extend=function(a,b){return d(a,function(a){return this.uber=a,b})},a.exports=d},function(a,b){function c(a){return a.replace(/^\s*|\s*$/g,"")}b=a.exports=c,b.left=function(a){return a.replace(/^\s*/,"")},b.right=function(a){return a.replace(/\s*$/,"")}},function(a){var b=Object.prototype.toString;a.exports=function(a){switch(b.call(a)){case"[object Date]":return"date";case"[object RegExp]":return"regexp";case"[object Arguments]":return"arguments";case"[object Array]":return"array";case"[object Error]":return"error"}return null===a?"null":void 0===a?"undefined":a!==a?"nan":a&&1===a.nodeType?"element":(a=a.valueOf?a.valueOf():Object.prototype.valueOf.apply(a),typeof a)}}])}),function(a,b){b&&(Holder=a.Holder)}(this,"undefined"!=typeof Meteor&&"undefined"!=typeof Package);
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/html5shiv.min.js b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/html5shiv.min.js
new file mode 100644
index 0000000..45ea723
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/html5shiv.min.js
@@ -0,0 +1,326 @@
+/**
+* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
+*/
+;(function(window, document) {
+/*jshint evil:true */
+ /** version */
+ var version = '3.7.3';
+
+ /** Preset options */
+ var options = window.html5 || {};
+
+ /** Used to skip problem elements */
+ var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
+
+ /** Not all elements can be cloned in IE **/
+ var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
+
+ /** Detect whether the browser supports default html5 styles */
+ var supportsHtml5Styles;
+
+ /** Name of the expando, to work with multiple documents or to re-shiv one document */
+ var expando = '_html5shiv';
+
+ /** The id for the the documents expando */
+ var expanID = 0;
+
+ /** Cached data for each document */
+ var expandoData = {};
+
+ /** Detect whether the browser supports unknown elements */
+ var supportsUnknownElements;
+
+ (function() {
+ try {
+ var a = document.createElement('a');
+ a.innerHTML = '<xyz></xyz>';
+ //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
+ supportsHtml5Styles = ('hidden' in a);
+
+ supportsUnknownElements = a.childNodes.length == 1 || (function() {
+ // assign a false positive if unable to shiv
+ (document.createElement)('a');
+ var frag = document.createDocumentFragment();
+ return (
+ typeof frag.cloneNode == 'undefined' ||
+ typeof frag.createDocumentFragment == 'undefined' ||
+ typeof frag.createElement == 'undefined'
+ );
+ }());
+ } catch(e) {
+ // assign a false positive if detection fails => unable to shiv
+ supportsHtml5Styles = true;
+ supportsUnknownElements = true;
+ }
+
+ }());
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * Creates a style sheet with the given CSS text and adds it to the document.
+ * @private
+ * @param {Document} ownerDocument The document.
+ * @param {String} cssText The CSS text.
+ * @returns {StyleSheet} The style element.
+ */
+ function addStyleSheet(ownerDocument, cssText) {
+ var p = ownerDocument.createElement('p'),
+ parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
+
+ p.innerHTML = 'x<style>' + cssText + '</style>';
+ return parent.insertBefore(p.lastChild, parent.firstChild);
+ }
+
+ /**
+ * Returns the value of `html5.elements` as an array.
+ * @private
+ * @returns {Array} An array of shived element node names.
+ */
+ function getElements() {
+ var elements = html5.elements;
+ return typeof elements == 'string' ? elements.split(' ') : elements;
+ }
+
+ /**
+ * Extends the built-in list of html5 elements
+ * @memberOf html5
+ * @param {String|Array} newElements whitespace separated list or array of new element names to shiv
+ * @param {Document} ownerDocument The context document.
+ */
+ function addElements(newElements, ownerDocument) {
+ var elements = html5.elements;
+ if(typeof elements != 'string'){
+ elements = elements.join(' ');
+ }
+ if(typeof newElements != 'string'){
+ newElements = newElements.join(' ');
+ }
+ html5.elements = elements +' '+ newElements;
+ shivDocument(ownerDocument);
+ }
+
+ /**
+ * Returns the data associated to the given document
+ * @private
+ * @param {Document} ownerDocument The document.
+ * @returns {Object} An object of data.
+ */
+ function getExpandoData(ownerDocument) {
+ var data = expandoData[ownerDocument[expando]];
+ if (!data) {
+ data = {};
+ expanID++;
+ ownerDocument[expando] = expanID;
+ expandoData[expanID] = data;
+ }
+ return data;
+ }
+
+ /**
+ * returns a shived element for the given nodeName and document
+ * @memberOf html5
+ * @param {String} nodeName name of the element
+ * @param {Document|DocumentFragment} ownerDocument The context document.
+ * @returns {Object} The shived element.
+ */
+ function createElement(nodeName, ownerDocument, data){
+ if (!ownerDocument) {
+ ownerDocument = document;
+ }
+ if(supportsUnknownElements){
+ return ownerDocument.createElement(nodeName);
+ }
+ if (!data) {
+ data = getExpandoData(ownerDocument);
+ }
+ var node;
+
+ if (data.cache[nodeName]) {
+ node = data.cache[nodeName].cloneNode();
+ } else if (saveClones.test(nodeName)) {
+ node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
+ } else {
+ node = data.createElem(nodeName);
+ }
+
+ // Avoid adding some elements to fragments in IE < 9 because
+ // * Attributes like `name` or `type` cannot be set/changed once an element
+ // is inserted into a document/fragment
+ // * Link elements with `src` attributes that are inaccessible, as with
+ // a 403 response, will cause the tab/window to crash
+ // * Script elements appended to fragments will execute when their `src`
+ // or `text` property is set
+ return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
+ }
+
+ /**
+ * returns a shived DocumentFragment for the given document
+ * @memberOf html5
+ * @param {Document} ownerDocument The context document.
+ * @returns {Object} The shived DocumentFragment.
+ */
+ function createDocumentFragment(ownerDocument, data){
+ if (!ownerDocument) {
+ ownerDocument = document;
+ }
+ if(supportsUnknownElements){
+ return ownerDocument.createDocumentFragment();
+ }
+ data = data || getExpandoData(ownerDocument);
+ var clone = data.frag.cloneNode(),
+ i = 0,
+ elems = getElements(),
+ l = elems.length;
+ for(;i<l;i++){
+ clone.createElement(elems[i]);
+ }
+ return clone;
+ }
+
+ /**
+ * Shivs the `createElement` and `createDocumentFragment` methods of the document.
+ * @private
+ * @param {Document|DocumentFragment} ownerDocument The document.
+ * @param {Object} data of the document.
+ */
+ function shivMethods(ownerDocument, data) {
+ if (!data.cache) {
+ data.cache = {};
+ data.createElem = ownerDocument.createElement;
+ data.createFrag = ownerDocument.createDocumentFragment;
+ data.frag = data.createFrag();
+ }
+
+
+ ownerDocument.createElement = function(nodeName) {
+ //abort shiv
+ if (!html5.shivMethods) {
+ return data.createElem(nodeName);
+ }
+ return createElement(nodeName, ownerDocument, data);
+ };
+
+ ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
+ 'var n=f.cloneNode(),c=n.createElement;' +
+ 'h.shivMethods&&(' +
+ // unroll the `createElement` calls
+ getElements().join().replace(/[\w\-:]+/g, function(nodeName) {
+ data.createElem(nodeName);
+ data.frag.createElement(nodeName);
+ return 'c("' + nodeName + '")';
+ }) +
+ ');return n}'
+ )(html5, data.frag);
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * Shivs the given document.
+ * @memberOf html5
+ * @param {Document} ownerDocument The document to shiv.
+ * @returns {Document} The shived document.
+ */
+ function shivDocument(ownerDocument) {
+ if (!ownerDocument) {
+ ownerDocument = document;
+ }
+ var data = getExpandoData(ownerDocument);
+
+ if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
+ data.hasCSS = !!addStyleSheet(ownerDocument,
+ // corrects block display not defined in IE6/7/8/9
+ 'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
+ // adds styling not present in IE6/7/8/9
+ 'mark{background:#FF0;color:#000}' +
+ // hides non-rendered elements
+ 'template{display:none}'
+ );
+ }
+ if (!supportsUnknownElements) {
+ shivMethods(ownerDocument, data);
+ }
+ return ownerDocument;
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * The `html5` object is exposed so that more elements can be shived and
+ * existing shiving can be detected on iframes.
+ * @type Object
+ * @example
+ *
+ * // options can be changed before the script is included
+ * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
+ */
+ var html5 = {
+
+ /**
+ * An array or space separated string of node names of the elements to shiv.
+ * @memberOf html5
+ * @type Array|String
+ */
+ 'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video',
+
+ /**
+ * current version of html5shiv
+ */
+ 'version': version,
+
+ /**
+ * A flag to indicate that the HTML5 style sheet should be inserted.
+ * @memberOf html5
+ * @type Boolean
+ */
+ 'shivCSS': (options.shivCSS !== false),
+
+ /**
+ * Is equal to true if a browser supports creating unknown/HTML5 elements
+ * @memberOf html5
+ * @type boolean
+ */
+ 'supportsUnknownElements': supportsUnknownElements,
+
+ /**
+ * A flag to indicate that the document's `createElement` and `createDocumentFragment`
+ * methods should be overwritten.
+ * @memberOf html5
+ * @type Boolean
+ */
+ 'shivMethods': (options.shivMethods !== false),
+
+ /**
+ * A string to describe the type of `html5` object ("default" or "default print").
+ * @memberOf html5
+ * @type String
+ */
+ 'type': 'default',
+
+ // shivs the document according to the specified `html5` object options
+ 'shivDocument': shivDocument,
+
+ //creates a shived element
+ createElement: createElement,
+
+ //creates a shived documentFragment
+ createDocumentFragment: createDocumentFragment,
+
+ //extends list of elements
+ addElements: addElements
+ };
+
+ /*--------------------------------------------------------------------------*/
+
+ // expose html5
+ window.html5 = html5;
+
+ // shiv the document
+ shivDocument(document);
+
+ if(typeof module == 'object' && module.exports){
+ module.exports = html5;
+ }
+
+}(typeof window !== "undefined" ? window : this, document));
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/jquery.min.js b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/jquery.min.js
new file mode 100644
index 0000000..4c5be4c
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/jquery.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v3.1.1 | (c) jQuery Foundation | jquery.org/license */
+!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.1.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=r.isArray(d)))?(e?(e=!1,f=c&&r.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e);return!1}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}return!1}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,C=/^.[^:#\[\.,]*$/;function D(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):C.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:parents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return J(a,"nextSibling")},prev:function(a){return J(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/[^\x20\t\r\n\f]+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,M,e),g(f,c,N,e)):(f++,j.call(a,g(f,c,M,e),g(f,c,N,e),g(f,c,M,c.notifyWith))):(d!==M&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(O(a,g.done(h(c)).resolve,g.reject),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener("DOMContentLoaded",R),
+a.removeEventListener("load",R),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",R),a.addEventListener("load",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},T=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function U(){this.expando=r.expando+U.uid++}U.uid=1,U.prototype={cache:function(a){var b=a[this.expando];return b||(b={},T(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){r.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(K)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var V=new U,W=new U,X=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Y=/[A-Z]/g;function Z(a){return"true"===a||"false"!==a&&("null"===a?null:a===+a+""?+a:X.test(a)?JSON.parse(a):a)}function $(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Y,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c=Z(c)}catch(e){}W.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return W.hasData(a)||V.hasData(a)},data:function(a,b,c){return W.access(a,b,c)},removeData:function(a,b){W.remove(a,b)},_data:function(a,b,c){return V.access(a,b,c)},_removeData:function(a,b){V.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=W.get(f),1===f.nodeType&&!V.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),$(f,d,e[d])));V.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){W.set(this,a)}):S(this,function(b){var c;if(f&&void 0===b){if(c=W.get(f,a),void 0!==c)return c;if(c=$(f,a),void 0!==c)return c}else this.each(function(){W.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return V.get(a,c)||V.access(a,c,{empty:r.Callbacks("once memory").add(function(){V.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=V.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var _=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,aa=new RegExp("^(?:([+-])=|)("+_+")([a-z%]*)$","i"),ba=["Top","Right","Bottom","Left"],ca=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},da=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function ea(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&aa.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var fa={};function ga(a){var b,c=a.ownerDocument,d=a.nodeName,e=fa[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),fa[d]=e,e)}function ha(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=V.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&ca(d)&&(e[f]=ga(d))):"none"!==c&&(e[f]="none",V.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ha(this,!0)},hide:function(){return ha(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){ca(this)?r(this).show():r(this).hide()})}});var ia=/^(?:checkbox|radio)$/i,ja=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,ka=/^$|\/(?:java|ecma)script/i,la={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};la.optgroup=la.option,la.tbody=la.tfoot=la.colgroup=la.caption=la.thead,la.th=la.td;function ma(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function na(a,b){for(var c=0,d=a.length;c<d;c++)V.set(a[c],"globalEval",!b||V.get(b[c],"globalEval"))}var oa=/<|&#?\w+;/;function pa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(oa.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ja.exec(f)||["",""])[1].toLowerCase(),i=la[h]||la._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=ma(l.appendChild(f),"script"),j&&na(g),c){k=0;while(f=g[k++])ka.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var qa=d.documentElement,ra=/^key/,sa=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ta=/^([^.]*)(?:\.(.+)|)/;function ua(){return!0}function va(){return!1}function wa(){try{return d.activeElement}catch(a){}}function xa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)xa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=va;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(qa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;while(j--)h=ta.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||"").match(K)||[""],j=b.length;while(j--)if(h=ta.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g,h=[],i=b.delegateCount,j=a.target;if(i&&j.nodeType&&!("click"===a.type&&a.button>=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c<i;c++)d=b[c],e=d.selector+" ",void 0===g[e]&&(g[e]=d.needsContext?r(e,this).index(j)>-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i<b.length&&h.push({elem:j,handlers:b.slice(i)}),h},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==wa()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===wa()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&r.nodeName(this,"input"))return this.click(),!1},_default:function(a){return r.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ua:va,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:va,isPropagationStopped:va,isImmediatePropagationStopped:va,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ua,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ua,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ua,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&ra.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&sa.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return xa(this,a,b,c,d)},one:function(a,b,c,d){return xa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=va),this.each(function(){r.event.remove(this,a,c,b)})}});var ya=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,za=/<script|<style|<link/i,Aa=/checked\s*(?:[^=]|=\s*.checked.)/i,Ba=/^true\/(.*)/,Ca=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Da(a,b){return r.nodeName(a,"table")&&r.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function Ea(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Fa(a){var b=Ba.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ga(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}W.hasData(a)&&(h=W.access(a),i=r.extend({},h),W.set(b,i))}}function Ha(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ia.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ia(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&Aa.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ia(f,b,c,d)});if(m&&(e=pa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(ma(e,"script"),Ea),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,ma(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Fa),l=0;l<i;l++)j=h[l],ka.test(j.type||"")&&!V.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Ca,""),k))}return a}function Ja(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(ma(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&na(ma(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(ya,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=ma(h),f=ma(a),d=0,e=f.length;d<e;d++)Ha(f[d],g[d]);if(b)if(c)for(f=f||ma(a),g=g||ma(h),d=0,e=f.length;d<e;d++)Ga(f[d],g[d]);else Ga(a,h);return g=ma(h,"script"),g.length>0&&na(g,!i&&ma(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ja(this,a,!0)},remove:function(a){return Ja(this,a)},text:function(a){return S(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ia(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Da(this,a);b.appendChild(a)}})},prepend:function(){return Ia(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Da(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ia(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ia(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(ma(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return S(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!za.test(a)&&!la[(ja.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(ma(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ia(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(ma(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var Ka=/^margin/,La=new RegExp("^("+_+")(?!px)[a-z%]+$","i"),Ma=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",qa.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,qa.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Na(a,b,c){var d,e,f,g,h=a.style;return c=c||Ma(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&La.test(g)&&Ka.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Oa(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Pa=/^(none|table(?!-c[ea]).+)/,Qa={position:"absolute",visibility:"hidden",display:"block"},Ra={letterSpacing:"0",fontWeight:"400"},Sa=["Webkit","Moz","ms"],Ta=d.createElement("div").style;function Ua(a){if(a in Ta)return a;var b=a[0].toUpperCase()+a.slice(1),c=Sa.length;while(c--)if(a=Sa[c]+b,a in Ta)return a}function Va(a,b,c){var d=aa.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Wa(a,b,c,d,e){var f,g=0;for(f=c===(d?"border":"content")?4:"width"===b?1:0;f<4;f+=2)"margin"===c&&(g+=r.css(a,c+ba[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+ba[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+ba[f]+"Width",!0,e))):(g+=r.css(a,"padding"+ba[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+ba[f]+"Width",!0,e)));return g}function Xa(a,b,c){var d,e=!0,f=Ma(a),g="border-box"===r.css(a,"boxSizing",!1,f);if(a.getClientRects().length&&(d=a.getBoundingClientRect()[b]),d<=0||null==d){if(d=Na(a,b,f),(d<0||null==d)&&(d=a.style[b]),La.test(d))return d;e=g&&(o.boxSizingReliable()||d===a.style[b]),d=parseFloat(d)||0}return d+Wa(a,b,c||(g?"border":"content"),e,f)+"px"}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Na(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=a.style;return b=r.cssProps[h]||(r.cssProps[h]=Ua(h)||h),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=aa.exec(c))&&e[1]&&(c=ea(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b);return b=r.cssProps[h]||(r.cssProps[h]=Ua(h)||h),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Na(a,b,d)),"normal"===e&&b in Ra&&(e=Ra[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Pa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?Xa(a,b,d):da(a,Qa,function(){return Xa(a,b,d)})},set:function(a,c,d){var e,f=d&&Ma(a),g=d&&Wa(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=aa.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Va(a,c,g)}}}),r.cssHooks.marginLeft=Oa(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Na(a,"marginLeft"))||a.getBoundingClientRect().left-da(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px"}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];d<4;d++)e[a+ba[d]+b]=f[d]||f[d-2]||f[0];return e}},Ka.test(a)||(r.cssHooks[a+b].set=Va)}),r.fn.extend({css:function(a,b){return S(this,function(a,b,c){var d,e,f={},g=0;if(r.isArray(b)){for(d=Ma(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function Ya(a,b,c,d,e){return new Ya.prototype.init(a,b,c,d,e)}r.Tween=Ya,Ya.prototype={constructor:Ya,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=Ya.propHooks[this.prop];return a&&a.get?a.get(this):Ya.propHooks._default.get(this)},run:function(a){var b,c=Ya.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Ya.propHooks._default.set(this),this}},Ya.prototype.init.prototype=Ya.prototype,Ya.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Ya.propHooks.scrollTop=Ya.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=Ya.prototype.init,r.fx.step={};var Za,$a,_a=/^(?:toggle|show|hide)$/,ab=/queueHooks$/;function bb(){$a&&(a.requestAnimationFrame(bb),r.fx.tick())}function cb(){return a.setTimeout(function(){Za=void 0}),Za=r.now()}function db(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ba[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function eb(a,b,c){for(var d,e=(hb.tweeners[b]||[]).concat(hb.tweeners["*"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function fb(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&ca(a),q=V.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],_a.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=V.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ha([a],!0),j=a.style.display||j,k=r.css(a,"display"),ha([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=V.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ha([a],!0),m.done(function(){p||ha([a]),V.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=eb(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function gb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],r.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function hb(a,b,c){var d,e,f=0,g=hb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Za||cb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:Za||cb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(gb(k,j.opts.specialEasing);f<g;f++)if(d=hb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,eb,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}r.Animation=r.extend(hb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return ea(c.elem,a,aa.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(K);for(var c,d=0,e=a.length;d<e;d++)c=a[d],hb.tweeners[c]=hb.tweeners[c]||[],hb.tweeners[c].unshift(b)},prefilters:[fb],prefilter:function(a,b){b?hb.prefilters.unshift(a):hb.prefilters.push(a)}}),r.speed=function(a,b,c){var e=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off||d.hidden?e.duration=0:"number"!=typeof e.duration&&(e.duration in r.fx.speeds?e.duration=r.fx.speeds[e.duration]:e.duration=r.fx.speeds._default),null!=e.queue&&e.queue!==!0||(e.queue="fx"),e.old=e.complete,e.complete=function(){r.isFunction(e.old)&&e.old.call(this),e.queue&&r.dequeue(this,e.queue)},e},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(ca).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=hb(this,r.extend({},a),f);(e||V.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=V.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&ab.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=V.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(db(b,!0),a,d,e)}}),r.each({slideDown:db("show"),slideUp:db("hide"),slideToggle:db("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(Za=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),Za=void 0},r.fx.timer=function(a){r.timers.push(a),a()?r.fx.start():r.timers.pop()},r.fx.interval=13,r.fx.start=function(){$a||($a=a.requestAnimationFrame?a.requestAnimationFrame(bb):a.setInterval(r.fx.tick,r.fx.interval))},r.fx.stop=function(){a.cancelAnimationFrame?a.cancelAnimationFrame($a):a.clearInterval($a),$a=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var ib,jb=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return S(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?ib:void 0)),
+void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&r.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),ib={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=jb[b]||r.find.attr;jb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=jb[g],jb[g]=e,e=null!=c(a,b,d)?g:null,jb[g]=f),e}});var kb=/^(?:input|select|textarea|button)$/i,lb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):kb.test(a.nodeName)||lb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function mb(a){var b=a.match(K)||[];return b.join(" ")}function nb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,nb(this)))});if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=nb(c),d=1===c.nodeType&&" "+mb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=mb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,nb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=nb(c),d=1===c.nodeType&&" "+mb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=mb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,nb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=nb(this),b&&V.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":V.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+mb(nb(c))+" ").indexOf(b)>-1)return!0;return!1}});var ob=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":r.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(ob,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:mb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d<i;d++)if(c=e[d],(c.selected||d===f)&&!c.disabled&&(!c.parentNode.disabled||!r.nodeName(c.parentNode,"optgroup"))){if(b=r(c).val(),g)return b;h.push(b)}return h},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(r.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,"events")||{})[b.type]&&V.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var tb=/\[\]$/,ub=/\r?\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)xb(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ia.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,"\r\n")}}):{name:b.name,value:c.replace(ub,"\r\n")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\/\//,Fb={},Gb={},Hb="*/".concat("*"),Ib=d.createElement("a");Ib.href=qb.href;function Jb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(K)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Nb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:"GET",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Hb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+"").replace(Eb,qb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(K)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+"//"+Ib.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(yb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,"$1"),n=(sb.test(f)?"&":"?")+"_="+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Hb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&"withCredentials"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;if(o.cors||Pb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Qb=[],Rb=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Qb.pop()||r.expando+"_"+rb++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Rb.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Rb.test(b.data)&&"data");if(h||"jsonp"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Rb,"$1"+e):b.jsonp!==!1&&(b.url+=(sb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Qb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=B.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=pa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=mb(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length};function Sb(a){return r.isWindow(a)?a:9===a.nodeType&&a.defaultView}r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),d.width||d.height?(e=f.ownerDocument,c=Sb(e),b=e.documentElement,{top:d.top+c.pageYOffset-b.clientTop,left:d.left+c.pageXOffset-b.clientLeft}):d):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),r.nodeName(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||qa})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return S(this,function(a,d,e){var f=Sb(a);return void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Oa(o.pixelPosition,function(a,c){if(c)return c=Na(a,b),La.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return S(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.parseJSON=JSON.parse,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var Tb=a.jQuery,Ub=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Ub),b&&a.jQuery===r&&(a.jQuery=Tb),r},b||(a.jQuery=a.$=r),r});
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/nv.d3.min.js b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/nv.d3.min.js
new file mode 100644
index 0000000..801e721
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/nv.d3.min.js
@@ -0,0 +1,8 @@
+/* nvd3 version 1.8.1 (https://github.com/novus/nvd3) 2015-06-15 */
+!function(){var a={};a.dev=!1,a.tooltip=a.tooltip||{},a.utils=a.utils||{},a.models=a.models||{},a.charts={},a.logs={},a.dom={},a.dispatch=d3.dispatch("render_start","render_end"),Function.prototype.bind||(Function.prototype.bind=function(a){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var b=Array.prototype.slice.call(arguments,1),c=this,d=function(){},e=function(){return c.apply(this instanceof d&&a?this:a,b.concat(Array.prototype.slice.call(arguments)))};return d.prototype=this.prototype,e.prototype=new d,e}),a.dev&&(a.dispatch.on("render_start",function(){a.logs.startTime=+new Date}),a.dispatch.on("render_end",function(){a.logs.endTime=+new Date,a.logs.totalTime=a.logs.endTime-a.logs.startTime,a.log("total",a.logs.totalTime)})),a.log=function(){if(a.dev&&window.console&&console.log&&console.log.apply)console.log.apply(console,arguments);else if(a.dev&&window.console&&"function"==typeof console.log&&Function.prototype.bind){var b=Function.prototype.bind.call(console.log,console);b.apply(console,arguments)}return arguments[arguments.length-1]},a.deprecated=function(a,b){console&&console.warn&&console.warn("nvd3 warning: `"+a+"` has been deprecated. ",b||"")},a.render=function(b){b=b||1,a.render.active=!0,a.dispatch.render_start();var c=function(){for(var d,e,f=0;b>f&&(e=a.render.queue[f]);f++)d=e.generate(),typeof e.callback==typeof Function&&e.callback(d);a.render.queue.splice(0,f),a.render.queue.length?setTimeout(c):(a.dispatch.render_end(),a.render.active=!1)};setTimeout(c)},a.render.active=!1,a.render.queue=[],a.addGraph=function(b){typeof arguments[0]==typeof Function&&(b={generate:arguments[0],callback:arguments[1]}),a.render.queue.push(b),a.render.active||a.render()},"undefined"!=typeof module&&"undefined"!=typeof exports&&(module.exports=a),"undefined"!=typeof window&&(window.nv=a),a.dom.write=function(a){return void 0!==window.fastdom?fastdom.write(a):a()},a.dom.read=function(a){return void 0!==window.fastdom?fastdom.read(a):a()},a.interactiveGuideline=function(){"use strict";function b(l){l.each(function(l){function m(){var a=d3.mouse(this),d=a[0],e=a[1],i=!0,j=!1;if(k&&(d=d3.event.offsetX,e=d3.event.offsetY,"svg"!==d3.event.target.tagName&&(i=!1),d3.event.target.className.baseVal.match("nv-legend")&&(j=!0)),i&&(d-=f.left,e-=f.top),0>d||0>e||d>o||e>p||d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement||j){if(k&&d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement&&(void 0===d3.event.relatedTarget.className||d3.event.relatedTarget.className.match(c.nvPointerEventsClass)))return;return h.elementMouseout({mouseX:d,mouseY:e}),b.renderGuideLine(null),void c.hidden(!0)}c.hidden(!1);var l=g.invert(d);h.elementMousemove({mouseX:d,mouseY:e,pointXValue:l}),"dblclick"===d3.event.type&&h.elementDblclick({mouseX:d,mouseY:e,pointXValue:l}),"click"===d3.event.type&&h.elementClick({mouseX:d,mouseY:e,pointXValue:l})}var n=d3.select(this),o=d||960,p=e||400,q=n.selectAll("g.nv-wrap.nv-interactiveLineLayer").data([l]),r=q.enter().append("g").attr("class"," nv-wrap nv-interactiveLineLayer");r.append("g").attr("class","nv-interactiveGuideLine"),j&&(j.on("touchmove",m).on("mousemove",m,!0).on("mouseout",m,!0).on("dblclick",m).on("click",m),b.guideLine=null,b.renderGuideLine=function(c){i&&(b.guideLine&&b.guideLine.attr("x1")===c||a.dom.write(function(){var b=q.select(".nv-interactiveGuideLine").selectAll("line").data(null!=c?[a.utils.NaNtoZero(c)]:[],String);b.enter().append("line").attr("class","nv-guideline").attr("x1",function(a){return a}).attr("x2",function(a){return a}).attr("y1",p).attr("y2",0),b.exit().remove()}))})})}var c=a.models.tooltip();c.duration(0).hideDelay(0)._isInteractiveLayer(!0).hidden(!1);var d=null,e=null,f={left:0,top:0},g=d3.scale.linear(),h=d3.dispatch("elementMousemove","elementMouseout","elementClick","elementDblclick"),i=!0,j=null,k="ActiveXObject"in window;return b.dispatch=h,b.tooltip=c,b.margin=function(a){return arguments.length?(f.top="undefined"!=typeof a.top?a.top:f.top,f.left="undefined"!=typeof a.left?a.left:f.left,b):f},b.width=function(a){return arguments.length?(d=a,b):d},b.height=function(a){return arguments.length?(e=a,b):e},b.xScale=function(a){return arguments.length?(g=a,b):g},b.showGuideLine=function(a){return arguments.length?(i=a,b):i},b.svgContainer=function(a){return arguments.length?(j=a,b):j},b},a.interactiveBisect=function(a,b,c){"use strict";if(!(a instanceof Array))return null;var d;d="function"!=typeof c?function(a){return a.x}:c;var e=function(a,b){return d(a)-b},f=d3.bisector(e).left,g=d3.max([0,f(a,b)-1]),h=d(a[g]);if("undefined"==typeof h&&(h=g),h===b)return g;var i=d3.min([g+1,a.length-1]),j=d(a[i]);return"undefined"==typeof j&&(j=i),Math.abs(j-b)>=Math.abs(h-b)?g:i},a.nearestValueIndex=function(a,b,c){"use strict";var d=1/0,e=null;return a.forEach(function(a,f){var g=Math.abs(b-a);null!=a&&d>=g&&c>g&&(d=g,e=f)}),e},function(){"use strict";a.models.tooltip=function(){function b(){if(k){var a=d3.select(k);"svg"!==a.node().tagName&&(a=a.select("svg"));var b=a.node()?a.attr("viewBox"):null;if(b){b=b.split(" ");var c=parseInt(a.style("width"),10)/b[2];p.left=p.left*c,p.top=p.top*c}}}function c(){if(!n){var a;a=k?k:document.body,n=d3.select(a).append("div").attr("class","nvtooltip "+(j?j:"xy-tooltip")).attr("id",v),n.style("top",0).style("left",0),n.style("opacity",0),n.selectAll("div, table, td, tr").classed(w,!0),n.classed(w,!0),o=n.node()}}function d(){if(r&&B(e)){b();var f=p.left,g=null!==i?i:p.top;return a.dom.write(function(){c();var b=A(e);b&&(o.innerHTML=b),k&&u?a.dom.read(function(){var a=k.getElementsByTagName("svg")[0],b={left:0,top:0};if(a){var c=a.getBoundingClientRect(),d=k.getBoundingClientRect(),e=c.top;if(0>e){var i=k.getBoundingClientRect();e=Math.abs(e)>i.height?0:e}b.top=Math.abs(e-d.top),b.left=Math.abs(c.left-d.left)}f+=k.offsetLeft+b.left-2*k.scrollLeft,g+=k.offsetTop+b.top-2*k.scrollTop,h&&h>0&&(g=Math.floor(g/h)*h),C([f,g])}):C([f,g])}),d}}var e=null,f="w",g=25,h=0,i=null,j=null,k=null,l=!0,m=400,n=null,o=null,p={left:null,top:null},q={left:0,top:0},r=!0,s=100,t=!0,u=!1,v="nvtooltip-"+Math.floor(1e5*Math.random()),w="nv-pointer-events-none",x=function(a){return a},y=function(a){return a},z=function(a){return a},A=function(a){if(null===a)return"";var b=d3.select(document.createElement("table"));if(t){var c=b.selectAll("thead").data([a]).enter().append("thead");c.append("tr").append("td").attr("colspan",3).append("strong").classed("x-value",!0).html(y(a.value))}var d=b.selectAll("tbody").data([a]).enter().append("tbody"),e=d.selectAll("tr").data(function(a){return a.series}).enter().append("tr").classed("highlight",function(a){return a.highlight});e.append("td").classed("legend-color-guide",!0).append("div").style("background-color",function(a){return a.color}),e.append("td").classed("key",!0).html(function(a,b){return z(a.key,b)}),e.append("td").classed("value",!0).html(function(a,b){return x(a.value,b)}),e.selectAll("td").each(function(a){if(a.highlight){var b=d3.scale.linear().domain([0,1]).range(["#fff",a.color]),c=.6;d3.select(this).style("border-bottom-color",b(c)).style("border-top-color",b(c))}});var f=b.node().outerHTML;return void 0!==a.footer&&(f+="<div class='footer'>"+a.footer+"</div>"),f},B=function(a){if(a&&a.series){if(a.series instanceof Array)return!!a.series.length;if(a.series instanceof Object)return a.series=[a.series],!0}return!1},C=function(b){o&&a.dom.read(function(){var c,d,e=parseInt(o.offsetHeight,10),h=parseInt(o.offsetWidth,10),i=a.utils.windowSize().width,j=a.utils.windowSize().height,k=window.pageYOffset,p=window.pageXOffset;j=window.innerWidth>=document.body.scrollWidth?j:j-16,i=window.innerHeight>=document.body.scrollHeight?i:i-16;var r,t,u=function(a){var b=d;do isNaN(a.offsetTop)||(b+=a.offsetTop),a=a.offsetParent;while(a);return b},v=function(a){var b=c;do isNaN(a.offsetLeft)||(b+=a.offsetLeft),a=a.offsetParent;while(a);return b};switch(f){case"e":c=b[0]-h-g,d=b[1]-e/2,r=v(o),t=u(o),p>r&&(c=b[0]+g>p?b[0]+g:p-r+c),k>t&&(d=k-t+d),t+e>k+j&&(d=k+j-t+d-e);break;case"w":c=b[0]+g,d=b[1]-e/2,r=v(o),t=u(o),r+h>i&&(c=b[0]-h-g),k>t&&(d=k+5),t+e>k+j&&(d=k+j-t+d-e);break;case"n":c=b[0]-h/2-5,d=b[1]+g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),t+e>k+j&&(d=k+j-t+d-e);break;case"s":c=b[0]-h/2,d=b[1]-e-g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),k>t&&(d=k);break;case"none":c=b[0],d=b[1]-g,r=v(o),t=u(o)}c-=q.left,d-=q.top;var w=o.getBoundingClientRect(),k=window.pageYOffset||document.documentElement.scrollTop,p=window.pageXOffset||document.documentElement.scrollLeft,x="translate("+(w.left+p)+"px, "+(w.top+k)+"px)",y="translate("+c+"px, "+d+"px)",z=d3.interpolateString(x,y),A=n.style("opacity")<.1;l?n.transition().delay(m).duration(0).style("opacity",0):n.interrupt().transition().duration(A?0:s).styleTween("transform",function(){return z},"important").style("-webkit-transform",y).style("opacity",1)})};return d.nvPointerEventsClass=w,d.options=a.utils.optionsFunc.bind(d),d._options=Object.create({},{duration:{get:function(){return s},set:function(a){s=a}},gravity:{get:function(){return f},set:function(a){f=a}},distance:{get:function(){return g},set:function(a){g=a}},snapDistance:{get:function(){return h},set:function(a){h=a}},classes:{get:function(){return j},set:function(a){j=a}},chartContainer:{get:function(){return k},set:function(a){k=a}},fixedTop:{get:function(){return i},set:function(a){i=a}},enabled:{get:function(){return r},set:function(a){r=a}},hideDelay:{get:function(){return m},set:function(a){m=a}},contentGenerator:{get:function(){return A},set:function(a){A=a}},valueFormatter:{get:function(){return x},set:function(a){x=a}},headerFormatter:{get:function(){return y},set:function(a){y=a}},keyFormatter:{get:function(){return z},set:function(a){z=a}},headerEnabled:{get:function(){return t},set:function(a){t=a}},_isInteractiveLayer:{get:function(){return u},set:function(a){u=!!a}},position:{get:function(){return p},set:function(a){p.left=void 0!==a.left?a.left:p.left,p.top=void 0!==a.top?a.top:p.top}},offset:{get:function(){return q},set:function(a){q.left=void 0!==a.left?a.left:q.left,q.top=void 0!==a.top?a.top:q.top}},hidden:{get:function(){return l},set:function(a){l!=a&&(l=!!a,d())}},data:{get:function(){return e},set:function(a){a.point&&(a.value=a.point.x,a.series=a.series||{},a.series.value=a.point.y,a.series.color=a.point.color||a.series.color),e=a}},tooltipElem:{get:function(){return o},set:function(){}},id:{get:function(){return v},set:function(){}}}),a.utils.initOptions(d),d}}(),a.utils.windowSize=function(){var a={width:640,height:480};return window.innerWidth&&window.innerHeight?(a.width=window.innerWidth,a.height=window.innerHeight,a):"CSS1Compat"==document.compatMode&&document.documentElement&&document.documentElement.offsetWidth?(a.width=document.documentElement.offsetWidth,a.height=document.documentElement.offsetHeight,a):document.body&&document.body.offsetWidth?(a.width=document.body.offsetWidth,a.height=document.body.offsetHeight,a):a},a.utils.windowResize=function(b){return window.addEventListener?window.addEventListener("resize",b):a.log("ERROR: Failed to bind to window.resize with: ",b),{callback:b,clear:function(){window.removeEventListener("resize",b)}}},a.utils.getColor=function(b){if(void 0===b)return a.utils.defaultColor();if(Array.isArray(b)){var c=d3.scale.ordinal().range(b);return function(a,b){var d=void 0===b?a:b;return a.color||c(d)}}return b},a.utils.defaultColor=function(){return a.utils.getColor(d3.scale.category20().range())},a.utils.customTheme=function(a,b,c){b=b||function(a){return a.key},c=c||d3.scale.category20().range();var d=c.length;return function(e){var f=b(e);return"function"==typeof a[f]?a[f]():void 0!==a[f]?a[f]:(d||(d=c.length),d-=1,c[d])}},a.utils.pjax=function(b,c){var d=function(d){d3.html(d,function(d){var e=d3.select(c).node();e.parentNode.replaceChild(d3.select(d).select(c).node(),e),a.utils.pjax(b,c)})};d3.selectAll(b).on("click",function(){history.pushState(this.href,this.textContent,this.href),d(this.href),d3.event.preventDefault()}),d3.select(window).on("popstate",function(){d3.event.state&&d(d3.event.state)})},a.utils.calcApproxTextWidth=function(a){if("function"==typeof a.style&&"function"==typeof a.text){var b=parseInt(a.style("font-size").replace("px",""),10),c=a.text().length;return c*b*.5}return 0},a.utils.NaNtoZero=function(a){return"number"!=typeof a||isNaN(a)||null===a||1/0===a||a===-1/0?0:a},d3.selection.prototype.watchTransition=function(a){var b=[this].concat([].slice.call(arguments,1));return a.transition.apply(a,b)},a.utils.renderWatch=function(b,c){if(!(this instanceof a.utils.renderWatch))return new a.utils.renderWatch(b,c);var d=void 0!==c?c:250,e=[],f=this;this.models=function(a){return a=[].slice.call(arguments,0),a.forEach(function(a){a.__rendered=!1,function(a){a.dispatch.on("renderEnd",function(){a.__rendered=!0,f.renderEnd("model")})}(a),e.indexOf(a)<0&&e.push(a)}),this},this.reset=function(a){void 0!==a&&(d=a),e=[]},this.transition=function(a,b,c){if(b=arguments.length>1?[].slice.call(arguments,1):[],c=b.length>1?b.pop():void 0!==d?d:250,a.__rendered=!1,e.indexOf(a)<0&&e.push(a),0===c)return a.__rendered=!0,a.delay=function(){return this},a.duration=function(){return this},a;a.__rendered=0===a.length?!0:a.every(function(a){return!a.length})?!0:!1;var g=0;return a.transition().duration(c).each(function(){++g}).each("end",function(){0===--g&&(a.__rendered=!0,f.renderEnd.apply(this,b))})},this.renderEnd=function(){e.every(function(a){return a.__rendered})&&(e.forEach(function(a){a.__rendered=!1}),b.renderEnd.apply(this,arguments))}},a.utils.deepExtend=function(b){var c=arguments.length>1?[].slice.call(arguments,1):[];c.forEach(function(c){for(var d in c){var e=b[d]instanceof Array,f="object"==typeof b[d],g="object"==typeof c[d];f&&!e&&g?a.utils.deepExtend(b[d],c[d]):b[d]=c[d]}})},a.utils.state=function(){if(!(this instanceof a.utils.state))return new a.utils.state;var b={},c=function(){},d=function(){return{}},e=null,f=null;this.dispatch=d3.dispatch("change","set"),this.dispatch.on("set",function(a){c(a,!0)}),this.getter=function(a){return d=a,this},this.setter=function(a,b){return b||(b=function(){}),c=function(c,d){a(c),d&&b()},this},this.init=function(b){e=e||{},a.utils.deepExtend(e,b)};var g=function(){var a=d();if(JSON.stringify(a)===JSON.stringify(b))return!1;for(var c in a)void 0===b[c]&&(b[c]={}),b[c]=a[c],f=!0;return!0};this.update=function(){e&&(c(e,!1),e=null),g.call(this)&&this.dispatch.change(b)}},a.utils.optionsFunc=function(a){return a&&d3.map(a).forEach(function(a,b){"function"==typeof this[a]&&this[a](b)}.bind(this)),this},a.utils.calcTicksX=function(b,c){var d=1,e=0;for(e;e<c.length;e+=1){var f=c[e]&&c[e].values?c[e].values.length:0;d=f>d?f:d}return a.log("Requested number of ticks: ",b),a.log("Calculated max values to be: ",d),b=b>d?b=d-1:b,b=1>b?1:b,b=Math.floor(b),a.log("Calculating tick count as: ",b),b},a.utils.calcTicksY=function(b,c){return a.utils.calcTicksX(b,c)},a.utils.initOption=function(a,b){a._calls&&a._calls[b]?a[b]=a._calls[b]:(a[b]=function(c){return arguments.length?(a._overrides[b]=!0,a._options[b]=c,a):a._options[b]},a["_"+b]=function(c){return arguments.length?(a._overrides[b]||(a._options[b]=c),a):a._options[b]})},a.utils.initOptions=function(b){b._overrides=b._overrides||{};var c=Object.getOwnPropertyNames(b._options||{}),d=Object.getOwnPropertyNames(b._calls||{});c=c.concat(d);for(var e in c)a.utils.initOption(b,c[e])},a.utils.inheritOptionsD3=function(a,b,c){a._d3options=c.concat(a._d3options||[]),c.unshift(b),c.unshift(a),d3.rebind.apply(this,c)},a.utils.arrayUnique=function(a){return a.sort().filter(function(b,c){return!c||b!=a[c-1]})},a.utils.symbolMap=d3.map(),a.utils.symbol=function(){function b(b,e){var f=c.call(this,b,e),g=d.call(this,b,e);return-1!==d3.svg.symbolTypes.indexOf(f)?d3.svg.symbol().type(f).size(g)():a.utils.symbolMap.get(f)(g)}var c,d=64;return b.type=function(a){return arguments.length?(c=d3.functor(a),b):c},b.size=function(a){return arguments.length?(d=d3.functor(a),b):d},b},a.utils.inheritOptions=function(b,c){var d=Object.getOwnPropertyNames(c._options||{}),e=Object.getOwnPropertyNames(c._calls||{}),f=c._inherited||[],g=c._d3options||[],h=d.concat(e).concat(f).concat(g);h.unshift(c),h.unshift(b),d3.rebind.apply(this,h),b._inherited=a.utils.arrayUnique(d.concat(e).concat(f).concat(d).concat(b._inherited||[])),b._d3options=a.utils.arrayUnique(g.concat(b._d3options||[]))},a.utils.initSVG=function(a){a.classed({"nvd3-svg":!0})},a.utils.sanitizeHeight=function(a,b){return a||parseInt(b.style("height"),10)||400},a.utils.sanitizeWidth=function(a,b){return a||parseInt(b.style("width"),10)||960},a.utils.availableHeight=function(b,c,d){return a.utils.sanitizeHeight(b,c)-d.top-d.bottom},a.utils.availableWidth=function(b,c,d){return a.utils.sanitizeWidth(b,c)-d.left-d.right},a.utils.noData=function(b,c){var d=b.options(),e=d.margin(),f=d.noData(),g=null==f?["No Data Available."]:[f],h=a.utils.availableHeight(d.height(),c,e),i=a.utils.availableWidth(d.width(),c,e),j=e.left+i/2,k=e.top+h/2;c.selectAll("g").remove();var l=c.selectAll(".nv-noData").data(g);l.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),l.attr("x",j).attr("y",k).text(function(a){return a})},a.models.axis=function(){"use strict";function b(g){return s.reset(),g.each(function(b){var g=d3.select(this);a.utils.initSVG(g);var p=g.selectAll("g.nv-wrap.nv-axis").data([b]),q=p.enter().append("g").attr("class","nvd3 nv-wrap nv-axis"),t=(q.append("g"),p.select("g"));null!==n?c.ticks(n):("top"==c.orient()||"bottom"==c.orient())&&c.ticks(Math.abs(d.range()[1]-d.range()[0])/100),t.watchTransition(s,"axis").call(c),r=r||c.scale();var u=c.tickFormat();null==u&&(u=r.tickFormat());var v=t.selectAll("text.nv-axislabel").data([h||null]);v.exit().remove();var w,x,y;switch(c.orient()){case"top":v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",0).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b))+",0)"}).select("text").attr("dy","-0.5em").attr("y",-c.tickPadding()).attr("text-anchor","middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max top").attr("transform",function(b,c){return"translate("+a.utils.NaNtoZero(d.range()[c])+",0)"}));break;case"bottom":w=o+36;var z=30,A=0,B=t.selectAll("g").select("text"),C="";if(j%360){B.each(function(){var a=this.getBoundingClientRect(),b=a.width;A=a.height,b>z&&(z=b)}),C="rotate("+j+" 0,"+(A/2+c.tickPadding())+")";var D=Math.abs(Math.sin(j*Math.PI/180));w=(D?D*z:z)+30,B.attr("transform",C).style("text-anchor",j%360>0?"start":"end")}v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",w).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data([d.domain()[0],d.domain()[d.domain().length-1]]),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"}).select("text").attr("dy",".71em").attr("y",c.tickPadding()).attr("transform",C).style("text-anchor",j?j%360>0?"start":"end":"middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max bottom").attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"})),l&&B.attr("transform",function(a,b){return"translate(0,"+(b%2==0?"0":"12")+")"});break;case"right":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"begin").attr("transform",k?"rotate(90)":"").attr("y",k?-Math.max(e.right,f)+12:-10).attr("x",k?d3.max(d.range())/2:c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(d(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",c.tickPadding()).style("text-anchor","start").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1));break;case"left":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"end").attr("transform",k?"rotate(-90)":"").attr("y",k?-Math.max(e.left,f)+25-(o||0):-10).attr("x",k?-d3.max(d.range())/2:-c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(r(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",-c.tickPadding()).attr("text-anchor","end").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1))}if(v.text(function(a){return a}),!i||"left"!==c.orient()&&"right"!==c.orient()||(t.selectAll("g").each(function(a){d3.select(this).select("text").attr("opacity",1),(d(a)<d.range()[1]+10||d(a)>d.range()[0]-10)&&((a>1e-10||-1e-10>a)&&d3.select(this).attr("opacity",0),d3.select(this).select("text").attr("opacity",0))}),d.domain()[0]==d.domain()[1]&&0==d.domain()[0]&&p.selectAll("g.nv-axisMaxMin").style("opacity",function(a,b){return b?0:1})),i&&("top"===c.orient()||"bottom"===c.orient())){var E=[];p.selectAll("g.nv-axisMaxMin").each(function(a,b){try{E.push(b?d(a)-this.getBoundingClientRect().width-4:d(a)+this.getBoundingClientRect().width+4)}catch(c){E.push(b?d(a)-4:d(a)+4)}}),t.selectAll("g").each(function(a){(d(a)<E[0]||d(a)>E[1])&&(a>1e-10||-1e-10>a?d3.select(this).remove():d3.select(this).select("text").remove())})}t.selectAll(".tick").filter(function(a){return!parseFloat(Math.round(1e5*a)/1e6)&&void 0!==a}).classed("zero",!0),r=d.copy()}),s.renderEnd("axis immediate"),b}var c=d3.svg.axis(),d=d3.scale.linear(),e={top:0,right:0,bottom:0,left:0},f=75,g=60,h=null,i=!0,j=0,k=!0,l=!1,m=!1,n=null,o=0,p=250,q=d3.dispatch("renderEnd");c.scale(d).orient("bottom").tickFormat(function(a){return a});var r,s=a.utils.renderWatch(q,p);return b.axis=c,b.dispatch=q,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{axisLabelDistance:{get:function(){return o},set:function(a){o=a}},staggerLabels:{get:function(){return l},set:function(a){l=a}},rotateLabels:{get:function(){return j},set:function(a){j=a}},rotateYLabel:{get:function(){return k},set:function(a){k=a}},showMaxMin:{get:function(){return i},set:function(a){i=a}},axisLabel:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return g},set:function(a){g=a}},ticks:{get:function(){return n},set:function(a){n=a}},width:{get:function(){return f},set:function(a){f=a}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},duration:{get:function(){return p},set:function(a){p=a,s.reset(p)}},scale:{get:function(){return d},set:function(e){d=e,c.scale(d),m="function"==typeof d.rangeBands,a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"])}}}),a.utils.initOptions(b),a.utils.inheritOptionsD3(b,c,["orient","tickValues","tickSubdivide","tickSize","tickPadding","tickFormat"]),a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"]),b},a.models.boxPlot=function(){"use strict";function b(l){return v.reset(),l.each(function(b){var l=j-i.left-i.right,p=k-i.top-i.bottom;r=d3.select(this),a.utils.initSVG(r),m.domain(c||b.map(function(a,b){return o(a,b)})).rangeBands(e||[0,l],.1);var w=[];if(!d){var x=d3.min(b.map(function(a){var b=[];return b.push(a.values.Q1),a.values.hasOwnProperty("whisker_low")&&null!==a.values.whisker_low&&b.push(a.values.whisker_low),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.min(b)})),y=d3.max(b.map(function(a){var b=[];return b.push(a.values.Q3),a.values.hasOwnProperty("whisker_high")&&null!==a.values.whisker_high&&b.push(a.values.whisker_high),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.max(b)}));w=[x,y]}n.domain(d||w),n.range(f||[p,0]),g=g||m,h=h||n.copy().range([n(0),n(0)]);{var z=r.selectAll("g.nv-wrap").data([b]);z.enter().append("g").attr("class","nvd3 nv-wrap")}z.attr("transform","translate("+i.left+","+i.top+")");var A=z.selectAll(".nv-boxplot").data(function(a){return a}),B=A.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);A.attr("class","nv-boxplot").attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}).classed("hover",function(a){return a.hover}),A.watchTransition(v,"nv-boxplot: boxplots").style("stroke-opacity",1).style("fill-opacity",.75).delay(function(a,c){return c*t/b.length}).attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}),A.exit().remove(),B.each(function(a,b){var c=d3.select(this);["low","high"].forEach(function(d){a.values.hasOwnProperty("whisker_"+d)&&null!==a.values["whisker_"+d]&&(c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-whisker nv-boxplot-"+d),c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-tick nv-boxplot-"+d))})});var C=A.selectAll(".nv-boxplot-outlier").data(function(a){return a.values.hasOwnProperty("outliers")&&null!==a.values.outliers?a.values.outliers:[]});C.enter().append("circle").style("fill",function(a,b,c){return q(a,c)}).style("stroke",function(a,b,c){return q(a,c)}).on("mouseover",function(a,b,c){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:a,color:q(a,c)},e:d3.event})}).on("mouseout",function(a,b,c){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:a,color:q(a,c)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),C.attr("class","nv-boxplot-outlier"),C.watchTransition(v,"nv-boxplot: nv-boxplot-outlier").attr("cx",.45*m.rangeBand()).attr("cy",function(a){return n(a)}).attr("r","3"),C.exit().remove();var D=function(){return null===u?.9*m.rangeBand():Math.min(75,.9*m.rangeBand())},E=function(){return.45*m.rangeBand()-D()/2},F=function(){return.45*m.rangeBand()+D()/2};["low","high"].forEach(function(a){var b="low"===a?"Q1":"Q3";A.select("line.nv-boxplot-whisker.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",.45*m.rangeBand()).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",.45*m.rangeBand()).attr("y2",function(a){return n(a.values[b])}),A.select("line.nv-boxplot-tick.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",E).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",F).attr("y2",function(b){return n(b.values["whisker_"+a])})}),["low","high"].forEach(function(a){B.selectAll(".nv-boxplot-"+a).on("mouseover",function(b,c,d){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mouseout",function(b,c,d){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})})}),B.append("rect").attr("class","nv-boxplot-box").on("mouseover",function(a,b){d3.select(this).classed("hover",!0),s.elementMouseover({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),s.elementMouseout({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),A.select("rect.nv-boxplot-box").watchTransition(v,"nv-boxplot: boxes").attr("y",function(a){return n(a.values.Q3)}).attr("width",D).attr("x",E).attr("height",function(a){return Math.abs(n(a.values.Q3)-n(a.values.Q1))||1}).style("fill",function(a,b){return a.color||q(a,b)}).style("stroke",function(a,b){return a.color||q(a,b)}),B.append("line").attr("class","nv-boxplot-median"),A.select("line.nv-boxplot-median").watchTransition(v,"nv-boxplot: boxplots line").attr("x1",E).attr("y1",function(a){return n(a.values.Q2)}).attr("x2",F).attr("y2",function(a){return n(a.values.Q2)}),g=m.copy(),h=n.copy()}),v.renderEnd("nv-boxplot immediate"),b}var c,d,e,f,g,h,i={top:0,right:0,bottom:0,left:0},j=960,k=500,l=Math.floor(1e4*Math.random()),m=d3.scale.ordinal(),n=d3.scale.linear(),o=function(a){return a.x},p=function(a){return a.y},q=a.utils.defaultColor(),r=null,s=d3.dispatch("elementMouseover","elementMouseout","elementMousemove","renderEnd"),t=250,u=null,v=a.utils.renderWatch(s,t);return b.dispatch=s,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},maxBoxWidth:{get:function(){return u},set:function(a){u=a}},x:{get:function(){return o},set:function(a){o=a}},y:{get:function(){return p},set:function(a){p=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return l},set:function(a){l=a}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}},duration:{get:function(){return t},set:function(a){t=a,v.reset(t)}}}),a.utils.initOptions(b),b},a.models.boxPlotChart=function(){"use strict";function b(k){return t.reset(),t.models(e),l&&t.models(f),m&&t.models(g),k.each(function(k){var p=d3.select(this);a.utils.initSVG(p);var t=(i||parseInt(p.style("width"))||960)-h.left-h.right,u=(j||parseInt(p.style("height"))||400)-h.top-h.bottom;if(b.update=function(){r.beforeUpdate(),p.transition().duration(s).call(b)},b.container=this,!(k&&k.length&&k.filter(function(a){return a.values.hasOwnProperty("Q1")&&a.values.hasOwnProperty("Q2")&&a.values.hasOwnProperty("Q3")}).length)){var v=p.selectAll(".nv-noData").data([q]);return v.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),v.attr("x",h.left+t/2).attr("y",h.top+u/2).text(function(a){return a}),b}p.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var w=p.selectAll("g.nv-wrap.nv-boxPlotWithAxes").data([k]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-boxPlotWithAxes").append("g"),y=x.append("defs"),z=w.select("g");
+x.append("g").attr("class","nv-x nv-axis"),x.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),x.append("g").attr("class","nv-barsWrap"),z.attr("transform","translate("+h.left+","+h.top+")"),n&&z.select(".nv-y.nv-axis").attr("transform","translate("+t+",0)"),e.width(t).height(u);var A=z.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));if(A.transition().call(e),y.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),z.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(o?2:1)).attr("height",16).attr("x",-c.rangeBand()/(o?1:2)),l){f.scale(c).ticks(a.utils.calcTicksX(t/100,k)).tickSize(-u,0),z.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),z.select(".nv-x.nv-axis").call(f);var B=z.select(".nv-x.nv-axis").selectAll("g");o&&B.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}m&&(g.scale(d).ticks(Math.floor(u/36)).tickSize(-t,0),z.select(".nv-y.nv-axis").call(g)),z.select(".nv-zeroLine line").attr("x1",0).attr("x2",t).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("nv-boxplot chart immediate"),b}var c,d,e=a.models.boxPlot(),f=a.models.axis(),g=a.models.axis(),h={top:15,right:10,bottom:50,left:60},i=null,j=null,k=a.utils.getColor(),l=!0,m=!0,n=!1,o=!1,p=a.models.tooltip(),q="No Data Available.",r=d3.dispatch("tooltipShow","tooltipHide","beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(n?"right":"left").tickFormat(d3.format(",.1f")),p.duration(0);var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){p.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(a){p.data(a).hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){p.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.boxplot=e,b.xAxis=f,b.yAxis=g,b.tooltip=p,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},staggerLabels:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return l},set:function(a){l=a}},showYAxis:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return tooltips},set:function(a){tooltips=a}},tooltipContent:{get:function(){return p},set:function(a){p=a}},noData:{get:function(){return q},set:function(a){q=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!==a.top?a.top:h.top,h.right=void 0!==a.right?a.right:h.right,h.bottom=void 0!==a.bottom?a.bottom:h.bottom,h.left=void 0!==a.left?a.left:h.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}},rightAlignYAxis:{get:function(){return n},set:function(a){n=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.bullet=function(){"use strict";function b(d){return d.each(function(b,d){var p=m-c.left-c.right,s=n-c.top-c.bottom;o=d3.select(this),a.utils.initSVG(o);{var t=f.call(this,b,d).slice().sort(d3.descending),u=g.call(this,b,d).slice().sort(d3.descending),v=h.call(this,b,d).slice().sort(d3.descending),w=i.call(this,b,d).slice(),x=j.call(this,b,d).slice(),y=k.call(this,b,d).slice(),z=d3.scale.linear().domain(d3.extent(d3.merge([l,t]))).range(e?[p,0]:[0,p]);this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range())}this.__chart__=z;var A=d3.min(t),B=d3.max(t),C=t[1],D=o.selectAll("g.nv-wrap.nv-bullet").data([b]),E=D.enter().append("g").attr("class","nvd3 nv-wrap nv-bullet"),F=E.append("g"),G=D.select("g");F.append("rect").attr("class","nv-range nv-rangeMax"),F.append("rect").attr("class","nv-range nv-rangeAvg"),F.append("rect").attr("class","nv-range nv-rangeMin"),F.append("rect").attr("class","nv-measure"),D.attr("transform","translate("+c.left+","+c.top+")");var H=function(a){return Math.abs(z(a)-z(0))},I=function(a){return z(0>a?a:0)};G.select("rect.nv-rangeMax").attr("height",s).attr("width",H(B>0?B:A)).attr("x",I(B>0?B:A)).datum(B>0?B:A),G.select("rect.nv-rangeAvg").attr("height",s).attr("width",H(C)).attr("x",I(C)).datum(C),G.select("rect.nv-rangeMin").attr("height",s).attr("width",H(B)).attr("x",I(B)).attr("width",H(B>0?A:B)).attr("x",I(B>0?A:B)).datum(B>0?A:B),G.select("rect.nv-measure").style("fill",q).attr("height",s/3).attr("y",s/3).attr("width",0>v?z(0)-z(v[0]):z(v[0])-z(0)).attr("x",I(v)).on("mouseover",function(){r.elementMouseover({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mouseout",function(){r.elementMouseout({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})});var J=s/6,K=u.map(function(a,b){return{value:a,label:x[b]}});F.selectAll("path.nv-markerTriangle").data(K).enter().append("path").attr("class","nv-markerTriangle").attr("transform",function(a){return"translate("+z(a.value)+","+s/2+")"}).attr("d","M0,"+J+"L"+J+","+-J+" "+-J+","+-J+"Z").on("mouseover",function(a){r.elementMouseover({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill"),pos:[z(a.value),s/2]})}).on("mousemove",function(a){r.elementMousemove({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a){r.elementMouseout({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}),D.selectAll(".nv-range").on("mouseover",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseover({value:a,label:c,color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseout({value:a,label:c,color:d3.select(this).style("fill")})})}),b}var c={top:0,right:0,bottom:0,left:0},d="left",e=!1,f=function(a){return a.ranges},g=function(a){return a.markers?a.markers:[0]},h=function(a){return a.measures},i=function(a){return a.rangeLabels?a.rangeLabels:[]},j=function(a){return a.markerLabels?a.markerLabels:[]},k=function(a){return a.measureLabels?a.measureLabels:[]},l=[0],m=380,n=30,o=null,p=null,q=a.utils.getColor(["#1f77b4"]),r=d3.dispatch("elementMouseover","elementMouseout","elementMousemove");return b.dispatch=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return f},set:function(a){f=a}},markers:{get:function(){return g},set:function(a){g=a}},measures:{get:function(){return h},set:function(a){h=a}},forceX:{get:function(){return l},set:function(a){l=a}},width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},tickFormat:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},orient:{get:function(){return d},set:function(a){d=a,e="right"==d||"bottom"==d}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.bulletChart=function(){"use strict";function b(d){return d.each(function(e,o){var p=d3.select(this);a.utils.initSVG(p);var q=a.utils.availableWidth(k,p,g),r=l-g.top-g.bottom;if(b.update=function(){b(d)},b.container=this,!e||!h.call(this,e,o))return a.utils.noData(b,p),b;p.selectAll(".nv-noData").remove();var s=h.call(this,e,o).slice().sort(d3.descending),t=i.call(this,e,o).slice().sort(d3.descending),u=j.call(this,e,o).slice().sort(d3.descending),v=p.selectAll("g.nv-wrap.nv-bulletChart").data([e]),w=v.enter().append("g").attr("class","nvd3 nv-wrap nv-bulletChart"),x=w.append("g"),y=v.select("g");x.append("g").attr("class","nv-bulletWrap"),x.append("g").attr("class","nv-titles"),v.attr("transform","translate("+g.left+","+g.top+")");var z=d3.scale.linear().domain([0,Math.max(s[0],t[0],u[0])]).range(f?[q,0]:[0,q]),A=this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range());this.__chart__=z;var B=x.select(".nv-titles").append("g").attr("text-anchor","end").attr("transform","translate(-6,"+(l-g.top-g.bottom)/2+")");B.append("text").attr("class","nv-title").text(function(a){return a.title}),B.append("text").attr("class","nv-subtitle").attr("dy","1em").text(function(a){return a.subtitle}),c.width(q).height(r);var C=y.select(".nv-bulletWrap");d3.transition(C).call(c);var D=m||z.tickFormat(q/100),E=y.selectAll("g.nv-tick").data(z.ticks(n?n:q/50),function(a){return this.textContent||D(a)}),F=E.enter().append("g").attr("class","nv-tick").attr("transform",function(a){return"translate("+A(a)+",0)"}).style("opacity",1e-6);F.append("line").attr("y1",r).attr("y2",7*r/6),F.append("text").attr("text-anchor","middle").attr("dy","1em").attr("y",7*r/6).text(D);var G=d3.transition(E).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1);G.select("line").attr("y1",r).attr("y2",7*r/6),G.select("text").attr("y",7*r/6),d3.transition(E.exit()).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1e-6).remove()}),d3.timer.flush(),b}var c=a.models.bullet(),d=a.models.tooltip(),e="left",f=!1,g={top:5,right:40,bottom:20,left:120},h=function(a){return a.ranges},i=function(a){return a.markers?a.markers:[0]},j=function(a){return a.measures},k=null,l=55,m=null,n=null,o=null,p=d3.dispatch("tooltipShow","tooltipHide");return d.duration(0).headerEnabled(!1),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.label,value:a.value,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.bullet=c,b.dispatch=p,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return h},set:function(a){h=a}},markers:{get:function(){return i},set:function(a){i=a}},measures:{get:function(){return j},set:function(a){j=a}},width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},tickFormat:{get:function(){return m},set:function(a){m=a}},ticks:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return o},set:function(a){o=a}},tooltips:{get:function(){return d.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),d.enabled(!!b)}},tooltipContent:{get:function(){return d.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),d.contentGenerator(b)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},orient:{get:function(){return e},set:function(a){e=a,f="right"==e||"bottom"==e}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.candlestickBar=function(){"use strict";function b(x){return x.each(function(b){c=d3.select(this);var x=a.utils.availableWidth(i,c,h),y=a.utils.availableHeight(j,c,h);a.utils.initSVG(c);var A=x/b[0].values.length*.45;l.domain(d||d3.extent(b[0].values.map(n).concat(t))),l.range(v?f||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:f||[5+A/2,x-A/2-5]),m.domain(e||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(g||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var B=d3.select(this).selectAll("g.nv-wrap.nv-candlestickBar").data([b[0].values]),C=B.enter().append("g").attr("class","nvd3 nv-wrap nv-candlestickBar"),D=C.append("defs"),E=C.append("g"),F=B.select("g");E.append("g").attr("class","nv-ticks"),B.attr("transform","translate("+h.left+","+h.top+")"),c.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:k})}),D.append("clipPath").attr("id","nv-chart-clip-path-"+k).append("rect"),B.select("#nv-chart-clip-path-"+k+" rect").attr("width",x).attr("height",y),F.attr("clip-path",w?"url(#nv-chart-clip-path-"+k+")":"");var G=B.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});G.exit().remove();{var H=G.enter().append("g").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b});H.append("line").attr("class","nv-candlestick-lines").attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),H.append("rect").attr("class","nv-candlestick-rects nv-bars").attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}c.selectAll(".nv-candlestick-lines").transition().attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),c.selectAll(".nv-candlestick-rects").transition().attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}),b}var c,d,e,f,g,h={top:0,right:0,bottom:0,left:0},i=null,j=null,k=Math.floor(1e4*Math.random()),l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,d){b.clearHighlights(),c.select(".nv-candlestickBar .nv-tick-0-"+a).classed("hover",d)},b.clearHighlights=function(){c.select(".nv-candlestickBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return k},set:function(a){k=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!=a.top?a.top:h.top,h.right=void 0!=a.right?a.right:h.right,h.bottom=void 0!=a.bottom?a.bottom:h.bottom,h.left=void 0!=a.left?a.left:h.left}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.cumulativeLineChart=function(){"use strict";function b(l){return H.reset(),H.models(f),r&&H.models(g),s&&H.models(h),l.each(function(l){function A(){d3.select(b.container).style("cursor","ew-resize")}function E(){G.x=d3.event.x,G.i=Math.round(F.invert(G.x)),K()}function H(){d3.select(b.container).style("cursor","auto"),y.index=G.i,C.stateChange(y)}function K(){bb.data([G]);var a=b.duration();b.duration(0),b.update(),b.duration(a)}var L=d3.select(this);a.utils.initSVG(L),L.classed("nv-chart-"+x,!0);var M=this,N=a.utils.availableWidth(o,L,m),O=a.utils.availableHeight(p,L,m);if(b.update=function(){0===D?L.call(b):L.transition().duration(D).call(b)},b.container=this,y.setter(J(l),b.update).getter(I(l)).update(),y.disabled=l.map(function(a){return!!a.disabled}),!z){var P;z={};for(P in y)z[P]=y[P]instanceof Array?y[P].slice(0):y[P]}var Q=d3.behavior.drag().on("dragstart",A).on("drag",E).on("dragend",H);if(!(l&&l.length&&l.filter(function(a){return a.values.length}).length))return a.utils.noData(b,L),b;if(L.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale(),w)f.yDomain(null);else{var R=l.filter(function(a){return!a.disabled}).map(function(a){var b=d3.extent(a.values,f.y());return b[0]<-.95&&(b[0]=-.95),[(b[0]-b[1])/(1+b[1]),(b[1]-b[0])/(1+b[0])]}),S=[d3.min(R,function(a){return a[0]}),d3.max(R,function(a){return a[1]})];f.yDomain(S)}F.domain([0,l[0].values.length-1]).range([0,N]).clamp(!0);var l=c(G.i,l),T=v?"none":"all",U=L.selectAll("g.nv-wrap.nv-cumulativeLine").data([l]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-cumulativeLine").append("g"),W=U.select("g");if(V.append("g").attr("class","nv-interactive"),V.append("g").attr("class","nv-x nv-axis").style("pointer-events","none"),V.append("g").attr("class","nv-y nv-axis"),V.append("g").attr("class","nv-background"),V.append("g").attr("class","nv-linesWrap").style("pointer-events",T),V.append("g").attr("class","nv-avgLinesWrap").style("pointer-events","none"),V.append("g").attr("class","nv-legendWrap"),V.append("g").attr("class","nv-controlsWrap"),q&&(i.width(N),W.select(".nv-legendWrap").datum(l).call(i),m.top!=i.height()&&(m.top=i.height(),O=a.utils.availableHeight(p,L,m)),W.select(".nv-legendWrap").attr("transform","translate(0,"+-m.top+")")),u){var X=[{key:"Re-scale y-axis",disabled:!w}];j.width(140).color(["#444","#444","#444"]).rightAlign(!1).margin({top:5,right:0,bottom:5,left:20}),W.select(".nv-controlsWrap").datum(X).attr("transform","translate(0,"+-m.top+")").call(j)}U.attr("transform","translate("+m.left+","+m.top+")"),t&&W.select(".nv-y.nv-axis").attr("transform","translate("+N+",0)");var Y=l.filter(function(a){return a.tempDisabled});U.select(".tempDisabled").remove(),Y.length&&U.append("text").attr("class","tempDisabled").attr("x",N/2).attr("y","-.71em").style("text-anchor","end").text(Y.map(function(a){return a.key}).join(", ")+" values cannot be calculated for this time period."),v&&(k.width(N).height(O).margin({left:m.left,top:m.top}).svgContainer(L).xScale(d),U.select(".nv-interactive").call(k)),V.select(".nv-background").append("rect"),W.select(".nv-background rect").attr("width",N).attr("height",O),f.y(function(a){return a.display.y}).width(N).height(O).color(l.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!l[b].disabled&&!l[b].tempDisabled}));var Z=W.select(".nv-linesWrap").datum(l.filter(function(a){return!a.disabled&&!a.tempDisabled}));Z.call(f),l.forEach(function(a,b){a.seriesIndex=b});var $=l.filter(function(a){return!a.disabled&&!!B(a)}),_=W.select(".nv-avgLinesWrap").selectAll("line").data($,function(a){return a.key}),ab=function(a){var b=e(B(a));return 0>b?0:b>O?O:b};_.enter().append("line").style("stroke-width",2).style("stroke-dasharray","10,10").style("stroke",function(a){return f.color()(a,a.seriesIndex)}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.style("stroke-opacity",function(a){var b=e(B(a));return 0>b||b>O?0:1}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.exit().remove();var bb=Z.selectAll(".nv-indexLine").data([G]);bb.enter().append("rect").attr("class","nv-indexLine").attr("width",3).attr("x",-2).attr("fill","red").attr("fill-opacity",.5).style("pointer-events","all").call(Q),bb.attr("transform",function(a){return"translate("+F(a.i)+",0)"}).attr("height",O),r&&(g.scale(d)._ticks(a.utils.calcTicksX(N/70,l)).tickSize(-O,0),W.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),W.select(".nv-x.nv-axis").call(g)),s&&(h.scale(e)._ticks(a.utils.calcTicksY(O/36,l)).tickSize(-N,0),W.select(".nv-y.nv-axis").call(h)),W.select(".nv-background rect").on("click",function(){G.x=d3.mouse(this)[0],G.i=Math.round(F.invert(G.x)),y.index=G.i,C.stateChange(y),K()}),f.dispatch.on("elementClick",function(a){G.i=a.pointIndex,G.x=F(G.i),y.index=G.i,C.stateChange(y),K()}),j.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,w=!a.disabled,y.rescaleY=w,C.stateChange(y),b.update()}),i.dispatch.on("stateChange",function(a){for(var c in a)y[c]=a[c];C.stateChange(y),b.update()}),k.dispatch.on("elementMousemove",function(c){f.clearHighlights();var d,e,i,j=[];if(l.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g,h){e=a.interactiveBisect(g.values,c.pointXValue,b.x()),f.highlightPoint(h,e,!0);var k=g.values[e];"undefined"!=typeof k&&("undefined"==typeof d&&(d=k),"undefined"==typeof i&&(i=b.xScale()(b.x()(k,e))),j.push({key:g.key,value:b.y()(k,e),color:n(g,g.seriesIndex)}))}),j.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(j.map(function(a){return a.value}),o,q);null!==r&&(j[r].highlight=!0)}var s=g.tickFormat()(b.x()(d,e),e);k.tooltip.position({left:i+m.left,top:c.mouseY+m.top}).chartContainer(M.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:s,series:j})(),k.renderGuideLine(i)}),k.dispatch.on("elementMouseout",function(){f.clearHighlights()}),C.on("changeState",function(a){"undefined"!=typeof a.disabled&&(l.forEach(function(b,c){b.disabled=a.disabled[c]}),y.disabled=a.disabled),"undefined"!=typeof a.index&&(G.i=a.index,G.x=F(G.i),y.index=a.index,bb.data([G])),"undefined"!=typeof a.rescaleY&&(w=a.rescaleY),b.update()})}),H.renderEnd("cumulativeLineChart immediate"),b}function c(a,b){return K||(K=f.y()),b.map(function(b){if(!b.values)return b;var c=b.values[a];if(null==c)return b;var d=K(c,a);return-.95>d&&!E?(b.tempDisabled=!0,b):(b.tempDisabled=!1,b.values=b.values.map(function(a,b){return a.display={y:(K(a,b)-d)/(1+d)},a}),b)})}var d,e,f=a.models.line(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.models.legend(),k=a.interactiveGuideline(),l=a.models.tooltip(),m={top:30,right:30,bottom:50,left:60},n=a.utils.defaultColor(),o=null,p=null,q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=!0,x=f.id(),y=a.utils.state(),z=null,A=null,B=function(a){return a.average},C=d3.dispatch("stateChange","changeState","renderEnd"),D=250,E=!1;y.index=0,y.rescaleY=w,g.orient("bottom").tickPadding(7),h.orient(t?"right":"left"),l.valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)}),j.updateState(!1);var F=d3.scale.linear(),G={i:0,x:0},H=a.utils.renderWatch(C,D),I=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),index:G.i,rescaleY:w}}},J=function(a){return function(b){void 0!==b.index&&(G.i=b.index),void 0!==b.rescaleY&&(w=b.rescaleY),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};f.dispatch.on("elementMouseover.tooltip",function(a){var c={x:b.x()(a.point),y:b.y()(a.point),color:a.point.color};a.point=c,l.data(a).position(a.pos).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){l.hidden(!0)});var K=null;return b.dispatch=C,b.lines=f,b.legend=i,b.controls=j,b.xAxis=g,b.yAxis=h,b.interactiveLayer=k,b.state=y,b.tooltip=l,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return o},set:function(a){o=a}},height:{get:function(){return p},set:function(a){p=a}},rescaleY:{get:function(){return w},set:function(a){w=a}},showControls:{get:function(){return u},set:function(a){u=a}},showLegend:{get:function(){return q},set:function(a){q=a}},average:{get:function(){return B},set:function(a){B=a}},defaultState:{get:function(){return z},set:function(a){z=a}},noData:{get:function(){return A},set:function(a){A=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},noErrorCheck:{get:function(){return E},set:function(a){E=a}},tooltips:{get:function(){return l.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),l.enabled(!!b)}},tooltipContent:{get:function(){return l.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),l.contentGenerator(b)}},margin:{get:function(){return m},set:function(a){m.top=void 0!==a.top?a.top:m.top,m.right=void 0!==a.right?a.right:m.right,m.bottom=void 0!==a.bottom?a.bottom:m.bottom,m.left=void 0!==a.left?a.left:m.left}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),i.color(n)}},useInteractiveGuideline:{get:function(){return v},set:function(a){v=a,a===!0&&(b.interactive(!1),b.useVoronoi(!1))}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,h.orient(a?"right":"left")}},duration:{get:function(){return D},set:function(a){D=a,f.duration(D),g.duration(D),h.duration(D),H.reset(D)}}}),a.utils.inheritOptions(b,f),a.utils.initOptions(b),b},a.models.discreteBar=function(){"use strict";function b(m){return y.reset(),m.each(function(b){var m=k-j.left-j.right,x=l-j.top-j.bottom;c=d3.select(this),a.utils.initSVG(c),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var z=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),y0:a.y0}})});n.domain(d||d3.merge(z).map(function(a){return a.x})).rangeBands(f||[0,m],.1),o.domain(e||d3.extent(d3.merge(z).map(function(a){return a.y}).concat(r))),o.range(t?g||[x-(o.domain()[0]<0?12:0),o.domain()[1]>0?12:0]:g||[x,0]),h=h||n,i=i||o.copy().range([o(0),o(0)]);{var A=c.selectAll("g.nv-wrap.nv-discretebar").data([b]),B=A.enter().append("g").attr("class","nvd3 nv-wrap nv-discretebar"),C=B.append("g");A.select("g")}C.append("g").attr("class","nv-groups"),A.attr("transform","translate("+j.left+","+j.top+")");var D=A.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});D.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),D.exit().watchTransition(y,"discreteBar: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),D.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),D.watchTransition(y,"discreteBar: groups").style("stroke-opacity",1).style("fill-opacity",.75);var E=D.selectAll("g.nv-bar").data(function(a){return a.values});E.exit().remove();var F=E.enter().append("g").attr("transform",function(a,b){return"translate("+(n(p(a,b))+.05*n.rangeBand())+", "+o(0)+")"}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),v.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),v.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){v.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){v.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()});F.append("rect").attr("height",0).attr("width",.9*n.rangeBand()/b.length),t?(F.append("text").attr("text-anchor","middle"),E.select("text").text(function(a,b){return u(q(a,b))}).watchTransition(y,"discreteBar: bars text").attr("x",.9*n.rangeBand()/2).attr("y",function(a,b){return q(a,b)<0?o(q(a,b))-o(0)+12:-4})):E.selectAll("text").remove(),E.attr("class",function(a,b){return q(a,b)<0?"nv-bar negative":"nv-bar positive"}).style("fill",function(a,b){return a.color||s(a,b)}).style("stroke",function(a,b){return a.color||s(a,b)}).select("rect").attr("class",w).watchTransition(y,"discreteBar: bars rect").attr("width",.9*n.rangeBand()/b.length),E.watchTransition(y,"discreteBar: bars").attr("transform",function(a,b){var c=n(p(a,b))+.05*n.rangeBand(),d=q(a,b)<0?o(0):o(0)-o(q(a,b))<1?o(0)-1:o(q(a,b));return"translate("+c+", "+d+")"}).select("rect").attr("height",function(a,b){return Math.max(Math.abs(o(q(a,b))-o(e&&e[0]||0))||1)}),h=n.copy(),i=o.copy()}),y.renderEnd("discreteBar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=d3.scale.ordinal(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=[0],s=a.utils.defaultColor(),t=!1,u=d3.format(",.2f"),v=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),w="discreteBar",x=250,y=a.utils.renderWatch(v,x);return b.dispatch=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},forceY:{get:function(){return r},set:function(a){r=a}},showValues:{get:function(){return t},set:function(a){t=a}},x:{get:function(){return p},set:function(a){p=a}},y:{get:function(){return q},set:function(a){q=a}},xScale:{get:function(){return n},set:function(a){n=a}},yScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},valueFormat:{get:function(){return u},set:function(a){u=a}},id:{get:function(){return m},set:function(a){m=a}},rectClass:{get:function(){return w},set:function(a){w=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b)}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x)}}}),a.utils.initOptions(b),b},a.models.discreteBarChart=function(){"use strict";function b(h){return t.reset(),t.models(e),m&&t.models(f),n&&t.models(g),h.each(function(h){var l=d3.select(this);a.utils.initSVG(l);var q=a.utils.availableWidth(j,l,i),t=a.utils.availableHeight(k,l,i);if(b.update=function(){r.beforeUpdate(),l.transition().duration(s).call(b)},b.container=this,!(h&&h.length&&h.filter(function(a){return a.values.length}).length))return a.utils.noData(b,l),b;l.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var u=l.selectAll("g.nv-wrap.nv-discreteBarWithAxes").data([h]),v=u.enter().append("g").attr("class","nvd3 nv-wrap nv-discreteBarWithAxes").append("g"),w=v.append("defs"),x=u.select("g");v.append("g").attr("class","nv-x nv-axis"),v.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),v.append("g").attr("class","nv-barsWrap"),x.attr("transform","translate("+i.left+","+i.top+")"),o&&x.select(".nv-y.nv-axis").attr("transform","translate("+q+",0)"),e.width(q).height(t);var y=x.select(".nv-barsWrap").datum(h.filter(function(a){return!a.disabled}));if(y.transition().call(e),w.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),x.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(p?2:1)).attr("height",16).attr("x",-c.rangeBand()/(p?1:2)),m){f.scale(c)._ticks(a.utils.calcTicksX(q/100,h)).tickSize(-t,0),x.select(".nv-x.nv-axis").attr("transform","translate(0,"+(d.range()[0]+(e.showValues()&&d.domain()[0]<0?16:0))+")"),x.select(".nv-x.nv-axis").call(f);
+var z=x.select(".nv-x.nv-axis").selectAll("g");p&&z.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}n&&(g.scale(d)._ticks(a.utils.calcTicksY(t/36,h)).tickSize(-q,0),x.select(".nv-y.nv-axis").call(g)),x.select(".nv-zeroLine line").attr("x1",0).attr("x2",q).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("discreteBar chart immediate"),b}var c,d,e=a.models.discreteBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.tooltip(),i={top:15,right:10,bottom:50,left:60},j=null,k=null,l=a.utils.getColor(),m=!0,n=!0,o=!1,p=!1,q=null,r=d3.dispatch("beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(o?"right":"left").tickFormat(d3.format(",.1f")),h.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).keyFormatter(function(a,b){return f.tickFormat()(a,b)});var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},h.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){h.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){h.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.discretebar=e,b.xAxis=f,b.yAxis=g,b.tooltip=h,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},staggerLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return m},set:function(a){m=a}},showYAxis:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return q},set:function(a){q=a}},tooltips:{get:function(){return h.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),h.enabled(!!b)}},tooltipContent:{get:function(){return h.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),h.contentGenerator(b)}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),e.color(l)}},rightAlignYAxis:{get:function(){return o},set:function(a){o=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.distribution=function(){"use strict";function b(k){return m.reset(),k.each(function(b){var k=(e-("x"===g?d.left+d.right:d.top+d.bottom),"x"==g?"y":"x"),l=d3.select(this);a.utils.initSVG(l),c=c||j;var n=l.selectAll("g.nv-distribution").data([b]),o=n.enter().append("g").attr("class","nvd3 nv-distribution"),p=(o.append("g"),n.select("g"));n.attr("transform","translate("+d.left+","+d.top+")");var q=p.selectAll("g.nv-dist").data(function(a){return a},function(a){return a.key});q.enter().append("g"),q.attr("class",function(a,b){return"nv-dist nv-series-"+b}).style("stroke",function(a,b){return i(a,b)});var r=q.selectAll("line.nv-dist"+g).data(function(a){return a.values});r.enter().append("line").attr(g+"1",function(a,b){return c(h(a,b))}).attr(g+"2",function(a,b){return c(h(a,b))}),m.transition(q.exit().selectAll("line.nv-dist"+g),"dist exit").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}).style("stroke-opacity",0).remove(),r.attr("class",function(a,b){return"nv-dist"+g+" nv-dist"+g+"-"+b}).attr(k+"1",0).attr(k+"2",f),m.transition(r,"dist").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}),c=j.copy()}),m.renderEnd("distribution immediate"),b}var c,d={top:0,right:0,bottom:0,left:0},e=400,f=8,g="x",h=function(a){return a[g]},i=a.utils.defaultColor(),j=d3.scale.linear(),k=250,l=d3.dispatch("renderEnd"),m=a.utils.renderWatch(l,k);return b.options=a.utils.optionsFunc.bind(b),b.dispatch=l,b.margin=function(a){return arguments.length?(d.top="undefined"!=typeof a.top?a.top:d.top,d.right="undefined"!=typeof a.right?a.right:d.right,d.bottom="undefined"!=typeof a.bottom?a.bottom:d.bottom,d.left="undefined"!=typeof a.left?a.left:d.left,b):d},b.width=function(a){return arguments.length?(e=a,b):e},b.axis=function(a){return arguments.length?(g=a,b):g},b.size=function(a){return arguments.length?(f=a,b):f},b.getData=function(a){return arguments.length?(h=d3.functor(a),b):h},b.scale=function(a){return arguments.length?(j=a,b):j},b.color=function(c){return arguments.length?(i=a.utils.getColor(c),b):i},b.duration=function(a){return arguments.length?(k=a,m.reset(k),b):k},b},a.models.furiousLegend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?g(a,b):"#fff":m?void 0:a.disabled?g(a,b):"#fff"}function r(a,b){return m&&"furious"==o?a.disengaged?"#fff":g(a,b):a.disabled?"#fff":g(a,b)}return p.each(function(b){var p=d-c.left-c.right,s=d3.select(this);a.utils.initSVG(s);var t=s.selectAll("g.nv-legend").data([b]),u=(t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),t.select("g"));t.attr("transform","translate("+c.left+","+c.top+")");var v,w=u.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),x=w.enter().append("g").attr("class","nv-series");if("classic"==o)x.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),v=w.select("circle");else if("furious"==o){x.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),v=w.select("rect"),x.append("g").attr("class","nv-check-box").property("innerHTML",'<path d="M0.5,5 L22.5,5 L22.5,26.5 L0.5,26.5 L0.5,5 Z" class="nv-box"></path><path d="M5.5,12.8618467 L11.9185089,19.2803556 L31,0.198864511" class="nv-check"></path>').attr("transform","translate(-10,-8)scale(0.5)");var y=w.select(".nv-check-box");y.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}x.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var z=w.select("text.nv-legend-text");w.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=w.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=w.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),w.classed("nv-disabled",function(a){return a.userDisabled}),w.exit().remove(),z.attr("fill",q).text(f);var A;switch(o){case"furious":A=23;break;case"classic":A=20}if(h){var B=[];w.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}B.push(b+i)});for(var C=0,D=0,E=[];p>D&&C<B.length;)E[C]=B[C],D+=B[C++];for(0===C&&(C=1);D>p&&C>1;){E=[],C--;for(var F=0;F<B.length;F++)B[F]>(E[F%C]||0)&&(E[F%C]=B[F]);D=E.reduce(function(a,b){return a+b})}for(var G=[],H=0,I=0;C>H;H++)G[H]=I,I+=E[H];w.attr("transform",function(a,b){return"translate("+G[b%C]+","+(5+Math.floor(b/C)*A)+")"}),j?u.attr("transform","translate("+(d-c.right-D)+","+c.top+")"):u.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(B.length/C)*A}else{var J,K=5,L=5,M=0;w.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return J=L,d<c.left+c.right+J+a&&(L=J=5,K+=A),L+=a,L>M&&(M=L),"translate("+J+","+K+")"}),u.attr("transform","translate("+(d-c.right-M)+","+c.top+")"),e=c.top+c.bottom+K+15}"furious"==o&&v.attr("width",function(a,b){return z[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),v.style("fill",r).style("stroke",function(a,b){return a.color||g(a,b)})}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=28,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBar=function(){"use strict";function b(x){return x.each(function(b){w.reset(),k=d3.select(this);var x=a.utils.availableWidth(h,k,g),y=a.utils.availableHeight(i,k,g);a.utils.initSVG(k),l.domain(c||d3.extent(b[0].values.map(n).concat(p))),l.range(r?e||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:e||[0,x]),m.domain(d||d3.extent(b[0].values.map(o).concat(q))).range(f||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var z=k.selectAll("g.nv-wrap.nv-historicalBar-"+j).data([b[0].values]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBar-"+j),B=A.append("defs"),C=A.append("g"),D=z.select("g");C.append("g").attr("class","nv-bars"),z.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){u.chartClick({data:a,index:b,pos:d3.event,id:j})}),B.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),z.select("#nv-chart-clip-path-"+j+" rect").attr("width",x).attr("height",y),D.attr("clip-path",s?"url(#nv-chart-clip-path-"+j+")":"");var E=z.select(".nv-bars").selectAll(".nv-bar").data(function(a){return a},function(a,b){return n(a,b)});E.exit().remove(),E.enter().append("rect").attr("x",0).attr("y",function(b,c){return a.utils.NaNtoZero(m(Math.max(0,o(b,c))))}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.abs(m(o(b,c))-m(0)))}).attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).on("mouseover",function(a,b){v&&(d3.select(this).classed("hover",!0),u.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mouseout",function(a,b){v&&(d3.select(this).classed("hover",!1),u.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mousemove",function(a,b){v&&u.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v&&(u.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}).on("dblclick",function(a,b){v&&(u.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}),E.attr("fill",function(a,b){return t(a,b)}).attr("class",function(a,b,c){return(o(a,b)<0?"nv-bar negative":"nv-bar positive")+" nv-bar-"+c+"-"+b}).watchTransition(w,"bars").attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).attr("width",x/b[0].values.length*.9),E.watchTransition(w,"bars").attr("y",function(b,c){var d=o(b,c)<0?m(0):m(0)-m(o(b,c))<1?m(0)-1:m(o(b,c));return a.utils.NaNtoZero(d)}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.max(Math.abs(m(o(b,c))-m(0)),1))})}),w.renderEnd("historicalBar immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=[],q=[0],r=!1,s=!0,t=a.utils.defaultColor(),u=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),v=!0,w=a.utils.renderWatch(u,0);return b.highlightPoint=function(a,b){k.select(".nv-bars .nv-bar-0-"+a).classed("hover",b)},b.clearHighlights=function(){k.select(".nv-bars .nv-bar.hover").classed("hover",!1)},b.dispatch=u,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},forceX:{get:function(){return p},set:function(a){p=a}},forceY:{get:function(){return q},set:function(a){q=a}},padData:{get:function(){return r},set:function(a){r=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},clipEdge:{get:function(){return s},set:function(a){s=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return v},set:function(a){v=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return t},set:function(b){t=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBarChart=function(b){"use strict";function c(b){return b.each(function(k){z.reset(),z.models(f),q&&z.models(g),r&&z.models(h);var w=d3.select(this),A=this;a.utils.initSVG(w);var B=a.utils.availableWidth(n,w,l),C=a.utils.availableHeight(o,w,l);if(c.update=function(){w.transition().duration(y).call(c)},c.container=this,u.disabled=k.map(function(a){return!!a.disabled}),!v){var D;v={};for(D in u)v[D]=u[D]instanceof Array?u[D].slice(0):u[D]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(c,w),c;w.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale();var E=w.selectAll("g.nv-wrap.nv-historicalBarChart").data([k]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBarChart").append("g"),G=E.select("g");F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-barsWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),p&&(i.width(B),G.select(".nv-legendWrap").datum(k).call(i),l.top!=i.height()&&(l.top=i.height(),C=a.utils.availableHeight(o,w,l)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-l.top+")")),E.attr("transform","translate("+l.left+","+l.top+")"),s&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),t&&(j.width(B).height(C).margin({left:l.left,top:l.top}).svgContainer(w).xScale(d),E.select(".nv-interactive").call(j)),f.width(B).height(C).color(k.map(function(a,b){return a.color||m(a,b)}).filter(function(a,b){return!k[b].disabled}));var H=G.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));H.transition().call(f),q&&(g.scale(d)._ticks(a.utils.calcTicksX(B/100,k)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),G.select(".nv-x.nv-axis").transition().call(g)),r&&(h.scale(e)._ticks(a.utils.calcTicksY(C/36,k)).tickSize(-B,0),G.select(".nv-y.nv-axis").transition().call(h)),j.dispatch.on("elementMousemove",function(b){f.clearHighlights();var d,e,i,n=[];k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g){e=a.interactiveBisect(g.values,b.pointXValue,c.x()),f.highlightPoint(e,!0);var h=g.values[e];void 0!==h&&(void 0===d&&(d=h),void 0===i&&(i=c.xScale()(c.x()(h,e))),n.push({key:g.key,value:c.y()(h,e),color:m(g,g.seriesIndex),data:g.values[e]}))});var o=g.tickFormat()(c.x()(d,e));j.tooltip.position({left:i+l.left,top:b.mouseY+l.top}).chartContainer(A.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:o,index:e,series:n})(),j.renderGuideLine(i)}),j.dispatch.on("elementMouseout",function(){x.tooltipHide(),f.clearHighlights()}),i.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,k.filter(function(a){return!a.disabled}).length||k.map(function(a){return a.disabled=!1,E.selectAll(".nv-series").classed("disabled",!1),a}),u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),b.transition().call(c)}),i.dispatch.on("legendDblclick",function(a){k.forEach(function(a){a.disabled=!0}),a.disabled=!1,u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),c.update()}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),c.update()})}),z.renderEnd("historicalBarChart immediate"),c}var d,e,f=b||a.models.historicalBar(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:90,bottom:50,left:90},m=a.utils.defaultColor(),n=null,o=null,p=!1,q=!0,r=!0,s=!1,t=!1,u={},v=null,w=null,x=d3.dispatch("tooltipHide","stateChange","changeState","renderEnd"),y=250;g.orient("bottom").tickPadding(7),h.orient(s?"right":"left"),k.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)});var z=a.utils.renderWatch(x,0);return f.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:c.x()(a.data),value:c.y()(a.data),color:a.color},k.data(a).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),f.dispatch.on("elementMousemove.tooltip",function(){k.position({top:d3.event.pageY,left:d3.event.pageX})()}),c.dispatch=x,c.bars=f,c.legend=i,c.xAxis=g,c.yAxis=h,c.interactiveLayer=j,c.tooltip=k,c.options=a.utils.optionsFunc.bind(c),c._options=Object.create({},{width:{get:function(){return n},set:function(a){n=a}},height:{get:function(){return o},set:function(a){o=a}},showLegend:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return q},set:function(a){q=a}},showYAxis:{get:function(){return r},set:function(a){r=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b),i.color(m),f.color(m)}},duration:{get:function(){return y},set:function(a){y=a,z.reset(y),h.duration(y),g.duration(y)}},rightAlignYAxis:{get:function(){return s},set:function(a){s=a,h.orient(a?"right":"left")}},useInteractiveGuideline:{get:function(){return t},set:function(a){t=a,a===!0&&c.interactive(!1)}}}),a.utils.inheritOptions(c,f),a.utils.initOptions(c),c},a.models.ohlcBarChart=function(){var b=a.models.historicalBarChart(a.models.ohlcBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open<c.close?"2ca02c":"d62728";return'<h3 style="color: #'+d+'">'+a.value+"</h3><table><tr><td>open:</td><td>"+b.yAxis.tickFormat()(c.open)+"</td></tr><tr><td>close:</td><td>"+b.yAxis.tickFormat()(c.close)+"</td></tr><tr><td>high</td><td>"+b.yAxis.tickFormat()(c.high)+"</td></tr><tr><td>low:</td><td>"+b.yAxis.tickFormat()(c.low)+"</td></tr></table>"}),b},a.models.candlestickBarChart=function(){var b=a.models.historicalBarChart(a.models.candlestickBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open<c.close?"2ca02c":"d62728";return'<h3 style="color: #'+d+'">'+a.value+"</h3><table><tr><td>open:</td><td>"+b.yAxis.tickFormat()(c.open)+"</td></tr><tr><td>close:</td><td>"+b.yAxis.tickFormat()(c.close)+"</td></tr><tr><td>high</td><td>"+b.yAxis.tickFormat()(c.high)+"</td></tr><tr><td>low:</td><td>"+b.yAxis.tickFormat()(c.low)+"</td></tr></table>"}),b},a.models.legend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?"#000":"#fff":m?void 0:(a.color||(a.color=g(a,b)),a.disabled?a.color:"#fff")}function r(a,b){return m&&"furious"==o&&a.disengaged?"#eee":a.color||g(a,b)}function s(a){return m&&"furious"==o?1:a.disabled?0:1}return p.each(function(b){var g=d-c.left-c.right,p=d3.select(this);a.utils.initSVG(p);var t=p.selectAll("g.nv-legend").data([b]),u=t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),v=t.select("g");t.attr("transform","translate("+c.left+","+c.top+")");var w,x,y=v.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),z=y.enter().append("g").attr("class","nv-series");switch(o){case"furious":x=23;break;case"classic":x=20}if("classic"==o)z.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),w=y.select("circle");else if("furious"==o){z.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),w=y.select(".nv-legend-symbol"),z.append("g").attr("class","nv-check-box").property("innerHTML",'<path d="M0.5,5 L22.5,5 L22.5,26.5 L0.5,26.5 L0.5,5 Z" class="nv-box"></path><path d="M5.5,12.8618467 L11.9185089,19.2803556 L31,0.198864511" class="nv-check"></path>').attr("transform","translate(-10,-8)scale(0.5)");var A=y.select(".nv-check-box");A.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}z.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var B=y.select("text.nv-legend-text");y.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=y.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=y.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),y.classed("nv-disabled",function(a){return a.userDisabled}),y.exit().remove(),B.attr("fill",q).text(f);var C=0;if(h){var D=[];y.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}D.push(b+i)});var E=0,F=[];for(C=0;g>C&&E<D.length;)F[E]=D[E],C+=D[E++];for(0===E&&(E=1);C>g&&E>1;){F=[],E--;for(var G=0;G<D.length;G++)D[G]>(F[G%E]||0)&&(F[G%E]=D[G]);C=F.reduce(function(a,b){return a+b})}for(var H=[],I=0,J=0;E>I;I++)H[I]=J,J+=F[I];y.attr("transform",function(a,b){return"translate("+H[b%E]+","+(5+Math.floor(b/E)*x)+")"}),j?v.attr("transform","translate("+(d-c.right-C)+","+c.top+")"):v.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(D.length/E)*x}else{var K,L=5,M=5,N=0;y.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return K=M,d<c.left+c.right+K+a&&(M=K=5,L+=x),M+=a,M>N&&(N=M),K+N>C&&(C=K+N),"translate("+K+","+L+")"}),v.attr("transform","translate("+(d-c.right-N)+","+c.top+")"),e=c.top+c.bottom+L+15}if("furious"==o){w.attr("width",function(a,b){return B[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),u.insert("rect",":first-child").attr("class","nv-legend-bg").attr("fill","#eee").attr("opacity",0);var O=v.select(".nv-legend-bg");O.transition().duration(300).attr("x",-x).attr("width",C+x-12).attr("height",e+10).attr("y",-c.top-10).attr("opacity",m?1:0)}w.style("fill",r).style("fill-opacity",s).style("stroke",r)}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=32,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.line=function(){"use strict";function b(r){return v.reset(),v.models(e),r.each(function(b){i=d3.select(this);var r=a.utils.availableWidth(g,i,f),s=a.utils.availableHeight(h,i,f);a.utils.initSVG(i),c=e.xScale(),d=e.yScale(),t=t||c,u=u||d;var w=i.selectAll("g.nv-wrap.nv-line").data([b]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-line"),y=x.append("defs"),z=x.append("g"),A=w.select("g");z.append("g").attr("class","nv-groups"),z.append("g").attr("class","nv-scatterWrap"),w.attr("transform","translate("+f.left+","+f.top+")"),e.width(r).height(s);var B=w.select(".nv-scatterWrap");B.call(e),y.append("clipPath").attr("id","nv-edge-clip-"+e.id()).append("rect"),w.select("#nv-edge-clip-"+e.id()+" rect").attr("width",r).attr("height",s>0?s:0),A.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":""),B.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":"");var C=w.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});C.enter().append("g").style("stroke-opacity",1e-6).style("stroke-width",function(a){return a.strokeWidth||j}).style("fill-opacity",1e-6),C.exit().remove(),C.attr("class",function(a,b){return(a.classed||"")+" nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return k(a,b)}).style("stroke",function(a,b){return k(a,b)}),C.watchTransition(v,"line: groups").style("stroke-opacity",1).style("fill-opacity",function(a){return a.fillOpacity||.5});var D=C.selectAll("path.nv-area").data(function(a){return o(a)?[a]:[]});D.enter().append("path").attr("class","nv-area").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y0(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))}).y1(function(){return u(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])}),C.exit().selectAll("path.nv-area").remove(),D.watchTransition(v,"line: areaPaths").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y0(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))}).y1(function(){return d(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])});var E=C.selectAll("path.nv-line").data(function(a){return[a.values]});E.enter().append("path").attr("class","nv-line").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))})),E.watchTransition(v,"line: linePaths").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))})),t=c.copy(),u=d.copy()}),v.renderEnd("line immediate"),b}var c,d,e=a.models.scatter(),f={top:0,right:0,bottom:0,left:0},g=960,h=500,i=null,j=1.5,k=a.utils.defaultColor(),l=function(a){return a.x},m=function(a){return a.y},n=function(a,b){return!isNaN(m(a,b))&&null!==m(a,b)},o=function(a){return a.area},p=!1,q="linear",r=250,s=d3.dispatch("elementClick","elementMouseover","elementMouseout","renderEnd");e.pointSize(16).pointDomain([16,256]);var t,u,v=a.utils.renderWatch(s,r);return b.dispatch=s,b.scatter=e,e.dispatch.on("elementClick",function(){s.elementClick.apply(this,arguments)}),e.dispatch.on("elementMouseover",function(){s.elementMouseover.apply(this,arguments)}),e.dispatch.on("elementMouseout",function(){s.elementMouseout.apply(this,arguments)}),b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},defined:{get:function(){return n},set:function(a){n=a}},interpolate:{get:function(){return q},set:function(a){q=a}},clipEdge:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}},duration:{get:function(){return r},set:function(a){r=a,v.reset(r),e.duration(r)}},isArea:{get:function(){return o},set:function(a){o=d3.functor(a)}},x:{get:function(){return l},set:function(a){l=a,e.x(a)}},y:{get:function(){return m},set:function(a){m=a,e.y(a)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.lineChart=function(){"use strict";function b(j){return y.reset(),y.models(e),p&&y.models(f),q&&y.models(g),j.each(function(j){var v=d3.select(this),y=this;a.utils.initSVG(v);var B=a.utils.availableWidth(m,v,k),C=a.utils.availableHeight(n,v,k);if(b.update=function(){0===x?v.call(b):v.transition().duration(x).call(b)},b.container=this,t.setter(A(j),b.update).getter(z(j)).update(),t.disabled=j.map(function(a){return!!a.disabled}),!u){var D;u={};for(D in t)u[D]=t[D]instanceof Array?t[D].slice(0):t[D]
+}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,v),b;v.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var E=v.selectAll("g.nv-wrap.nv-lineChart").data([j]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-lineChart").append("g"),G=E.select("g");F.append("rect").style("opacity",0),F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-linesWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),G.select("rect").attr("width",B).attr("height",C>0?C:0),o&&(h.width(B),G.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),C=a.utils.availableHeight(n,v,k)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-k.top+")")),E.attr("transform","translate("+k.left+","+k.top+")"),r&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),s&&(i.width(B).height(C).margin({left:k.left,top:k.top}).svgContainer(v).xScale(c),E.select(".nv-interactive").call(i)),e.width(B).height(C).color(j.map(function(a,b){return a.color||l(a,b)}).filter(function(a,b){return!j[b].disabled}));var H=G.select(".nv-linesWrap").datum(j.filter(function(a){return!a.disabled}));H.call(e),p&&(f.scale(c)._ticks(a.utils.calcTicksX(B/100,j)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),G.select(".nv-x.nv-axis").call(f)),q&&(g.scale(d)._ticks(a.utils.calcTicksY(C/36,j)).tickSize(-B,0),G.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)t[c]=a[c];w.stateChange(t),b.update()}),i.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,h,m,n=[];if(j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,g){h=a.interactiveBisect(f.values,c.pointXValue,b.x());var i=f.values[h],j=b.y()(i,h);null!=j&&e.highlightPoint(g,h,!0),void 0!==i&&(void 0===d&&(d=i),void 0===m&&(m=b.xScale()(b.x()(i,h))),n.push({key:f.key,value:j,color:l(f,f.seriesIndex)}))}),n.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(n.map(function(a){return a.value}),o,q);null!==r&&(n[r].highlight=!0)}var s=f.tickFormat()(b.x()(d,h));i.tooltip.position({left:c.mouseX+k.left,top:c.mouseY+k.top}).chartContainer(y.parentNode).valueFormatter(function(a){return null==a?"N/A":g.tickFormat()(a)}).data({value:s,index:h,series:n})(),i.renderGuideLine(m)}),i.dispatch.on("elementClick",function(c){var d,f=[];j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(e){var g=a.interactiveBisect(e.values,c.pointXValue,b.x()),h=e.values[g];if("undefined"!=typeof h){"undefined"==typeof d&&(d=b.xScale()(b.x()(h,g)));var i=b.yScale()(b.y()(h,g));f.push({point:h,pointIndex:g,pos:[d,i],seriesIndex:e.seriesIndex,series:e})}}),e.dispatch.elementClick(f)}),i.dispatch.on("elementMouseout",function(){e.clearHighlights()}),w.on("changeState",function(a){"undefined"!=typeof a.disabled&&j.length===a.disabled.length&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),t.disabled=a.disabled),b.update()})}),y.renderEnd("lineChart immediate"),b}var c,d,e=a.models.line(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.interactiveGuideline(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=a.utils.defaultColor(),m=null,n=null,o=!0,p=!0,q=!0,r=!1,s=!1,t=a.utils.state(),u=null,v=null,w=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),x=250;f.orient("bottom").tickPadding(7),g.orient(r?"right":"left"),j.valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)});var y=a.utils.renderWatch(w,x),z=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},A=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){j.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),b.dispatch=w,b.lines=e,b.legend=h,b.xAxis=f,b.yAxis=g,b.interactiveLayer=i,b.tooltip=j,b.dispatch=w,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return p},set:function(a){p=a}},showYAxis:{get:function(){return q},set:function(a){q=a}},defaultState:{get:function(){return u},set:function(a){u=a}},noData:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x),e.duration(x),f.duration(x),g.duration(x)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),h.color(l),e.color(l)}},rightAlignYAxis:{get:function(){return r},set:function(a){r=a,g.orient(r?"right":"left")}},useInteractiveGuideline:{get:function(){return s},set:function(a){s=a,s&&(e.interactive(!1),e.useVoronoi(!1))}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.linePlusBarChart=function(){"use strict";function b(v){return v.each(function(v){function J(a){var b=+("e"==a),c=b?1:-1,d=X/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function S(){u.empty()||u.extent(I),kb.data([u.empty()?e.domain():I]).each(function(a){var b=e(a[0])-e.range()[0],c=e.range()[1]-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>c?0:c)})}function T(){I=u.empty()?null:u.extent(),c=u.empty()?e.domain():u.extent(),K.brush({extent:c,brush:u}),S(),l.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),j.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var b=db.select(".nv-focus .nv-barsWrap").datum(Z.length?Z.map(function(a){return{key:a.key,values:a.values.filter(function(a,b){return l.x()(a,b)>=c[0]&&l.x()(a,b)<=c[1]})}}):[{values:[]}]),h=db.select(".nv-focus .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$.map(function(a){return{area:a.area,fillOpacity:a.fillOpacity,key:a.key,values:a.values.filter(function(a,b){return j.x()(a,b)>=c[0]&&j.x()(a,b)<=c[1]})}}));d=Z.length?l.xScale():j.xScale(),n.scale(d)._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-W,0),n.domain([Math.ceil(c[0]),Math.floor(c[1])]),db.select(".nv-x.nv-axis").transition().duration(L).call(n),b.transition().duration(L).call(l),h.transition().duration(L).call(j),db.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),p.scale(f)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(-V,0),q.scale(g)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(Z.length?0:-V,0),db.select(".nv-focus .nv-y1.nv-axis").style("opacity",Z.length?1:0),db.select(".nv-focus .nv-y2.nv-axis").style("opacity",$.length&&!$[0].disabled?1:0).attr("transform","translate("+d.range()[1]+",0)"),db.select(".nv-focus .nv-y1.nv-axis").transition().duration(L).call(p),db.select(".nv-focus .nv-y2.nv-axis").transition().duration(L).call(q)}var U=d3.select(this);a.utils.initSVG(U);var V=a.utils.availableWidth(y,U,w),W=a.utils.availableHeight(z,U,w)-(E?H:0),X=H-x.top-x.bottom;if(b.update=function(){U.transition().duration(L).call(b)},b.container=this,M.setter(R(v),b.update).getter(Q(v)).update(),M.disabled=v.map(function(a){return!!a.disabled}),!N){var Y;N={};for(Y in M)N[Y]=M[Y]instanceof Array?M[Y].slice(0):M[Y]}if(!(v&&v.length&&v.filter(function(a){return a.values.length}).length))return a.utils.noData(b,U),b;U.selectAll(".nv-noData").remove();var Z=v.filter(function(a){return!a.disabled&&a.bar}),$=v.filter(function(a){return!a.bar});d=l.xScale(),e=o.scale(),f=l.yScale(),g=j.yScale(),h=m.yScale(),i=k.yScale();var _=v.filter(function(a){return!a.disabled&&a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})}),ab=v.filter(function(a){return!a.disabled&&!a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})});d.range([0,V]),e.domain(d3.extent(d3.merge(_.concat(ab)),function(a){return a.x})).range([0,V]);var bb=U.selectAll("g.nv-wrap.nv-linePlusBar").data([v]),cb=bb.enter().append("g").attr("class","nvd3 nv-wrap nv-linePlusBar").append("g"),db=bb.select("g");cb.append("g").attr("class","nv-legendWrap");var eb=cb.append("g").attr("class","nv-focus");eb.append("g").attr("class","nv-x nv-axis"),eb.append("g").attr("class","nv-y1 nv-axis"),eb.append("g").attr("class","nv-y2 nv-axis"),eb.append("g").attr("class","nv-barsWrap"),eb.append("g").attr("class","nv-linesWrap");var fb=cb.append("g").attr("class","nv-context");if(fb.append("g").attr("class","nv-x nv-axis"),fb.append("g").attr("class","nv-y1 nv-axis"),fb.append("g").attr("class","nv-y2 nv-axis"),fb.append("g").attr("class","nv-barsWrap"),fb.append("g").attr("class","nv-linesWrap"),fb.append("g").attr("class","nv-brushBackground"),fb.append("g").attr("class","nv-x nv-brush"),D){var gb=t.align()?V/2:V,hb=t.align()?gb:0;t.width(gb),db.select(".nv-legendWrap").datum(v.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(a.bar?O:P),a})).call(t),w.top!=t.height()&&(w.top=t.height(),W=a.utils.availableHeight(z,U,w)-H),db.select(".nv-legendWrap").attr("transform","translate("+hb+","+-w.top+")")}bb.attr("transform","translate("+w.left+","+w.top+")"),db.select(".nv-context").style("display",E?"initial":"none"),m.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),k.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var ib=db.select(".nv-context .nv-barsWrap").datum(Z.length?Z:[{values:[]}]),jb=db.select(".nv-context .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$);db.select(".nv-context").attr("transform","translate(0,"+(W+w.bottom+x.top)+")"),ib.transition().call(m),jb.transition().call(k),G&&(o._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-X,0),db.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+h.range()[0]+")"),db.select(".nv-context .nv-x.nv-axis").transition().call(o)),F&&(r.scale(h)._ticks(X/36).tickSize(-V,0),s.scale(i)._ticks(X/36).tickSize(Z.length?0:-V,0),db.select(".nv-context .nv-y3.nv-axis").style("opacity",Z.length?1:0).attr("transform","translate(0,"+e.range()[0]+")"),db.select(".nv-context .nv-y2.nv-axis").style("opacity",$.length?1:0).attr("transform","translate("+e.range()[1]+",0)"),db.select(".nv-context .nv-y1.nv-axis").transition().call(r),db.select(".nv-context .nv-y2.nv-axis").transition().call(s)),u.x(e).on("brush",T),I&&u.extent(I);var kb=db.select(".nv-brushBackground").selectAll("g").data([I||u.extent()]),lb=kb.enter().append("g");lb.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",X),lb.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",X);var mb=db.select(".nv-x.nv-brush").call(u);mb.selectAll("rect").attr("height",X),mb.selectAll(".resize").append("path").attr("d",J),t.dispatch.on("stateChange",function(a){for(var c in a)M[c]=a[c];K.stateChange(M),b.update()}),K.on("changeState",function(a){"undefined"!=typeof a.disabled&&(v.forEach(function(b,c){b.disabled=a.disabled[c]}),M.disabled=a.disabled),b.update()}),T()}),b}var c,d,e,f,g,h,i,j=a.models.line(),k=a.models.line(),l=a.models.historicalBar(),m=a.models.historicalBar(),n=a.models.axis(),o=a.models.axis(),p=a.models.axis(),q=a.models.axis(),r=a.models.axis(),s=a.models.axis(),t=a.models.legend(),u=d3.svg.brush(),v=a.models.tooltip(),w={top:30,right:30,bottom:30,left:60},x={top:0,right:30,bottom:20,left:60},y=null,z=null,A=function(a){return a.x},B=function(a){return a.y},C=a.utils.defaultColor(),D=!0,E=!0,F=!1,G=!0,H=50,I=null,J=null,K=d3.dispatch("brush","stateChange","changeState"),L=0,M=a.utils.state(),N=null,O=" (left axis)",P=" (right axis)";j.clipEdge(!0),k.interactive(!1),n.orient("bottom").tickPadding(5),p.orient("left"),q.orient("right"),o.orient("bottom").tickPadding(5),r.orient("left"),s.orient("right"),v.headerEnabled(!0).headerFormatter(function(a,b){return n.tickFormat()(a,b)});var Q=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},R=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return j.dispatch.on("elementMouseover.tooltip",function(a){v.duration(100).valueFormatter(function(a,b){return q.tickFormat()(a,b)}).data(a).position(a.pos).hidden(!1)}),j.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={value:b.y()(a.data),color:a.color},v.duration(0).valueFormatter(function(a,b){return p.tickFormat()(a,b)}).data(a).hidden(!1)}),l.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMousemove.tooltip",function(){v.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=K,b.legend=t,b.lines=j,b.lines2=k,b.bars=l,b.bars2=m,b.xAxis=n,b.x2Axis=o,b.y1Axis=p,b.y2Axis=q,b.y3Axis=r,b.y4Axis=s,b.tooltip=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return y},set:function(a){y=a}},height:{get:function(){return z},set:function(a){z=a}},showLegend:{get:function(){return D},set:function(a){D=a}},brushExtent:{get:function(){return I},set:function(a){I=a}},noData:{get:function(){return J},set:function(a){J=a}},focusEnable:{get:function(){return E},set:function(a){E=a}},focusHeight:{get:function(){return H},set:function(a){H=a}},focusShowAxisX:{get:function(){return G},set:function(a){G=a}},focusShowAxisY:{get:function(){return F},set:function(a){F=a}},legendLeftAxisHint:{get:function(){return O},set:function(a){O=a}},legendRightAxisHint:{get:function(){return P},set:function(a){P=a}},tooltips:{get:function(){return v.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),v.enabled(!!b)}},tooltipContent:{get:function(){return v.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),v.contentGenerator(b)}},margin:{get:function(){return w},set:function(a){w.top=void 0!==a.top?a.top:w.top,w.right=void 0!==a.right?a.right:w.right,w.bottom=void 0!==a.bottom?a.bottom:w.bottom,w.left=void 0!==a.left?a.left:w.left}},duration:{get:function(){return L},set:function(a){L=a}},color:{get:function(){return C},set:function(b){C=a.utils.getColor(b),t.color(C)}},x:{get:function(){return A},set:function(a){A=a,j.x(a),k.x(a),l.x(a),m.x(a)}},y:{get:function(){return B},set:function(a){B=a,j.y(a),k.y(a),l.y(a),m.y(a)}}}),a.utils.inheritOptions(b,j),a.utils.initOptions(b),b},a.models.lineWithFocusChart=function(){"use strict";function b(o){return o.each(function(o){function z(a){var b=+("e"==a),c=b?1:-1,d=M/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function G(){n.empty()||n.extent(y),U.data([n.empty()?e.domain():y]).each(function(a){var b=e(a[0])-c.range()[0],d=K-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>d?0:d)})}function H(){y=n.empty()?null:n.extent();var a=n.empty()?e.domain():n.extent();if(!(Math.abs(a[0]-a[1])<=1)){A.brush({extent:a,brush:n}),G();var b=Q.select(".nv-focus .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}).map(function(b){return{key:b.key,area:b.area,values:b.values.filter(function(b,c){return g.x()(b,c)>=a[0]&&g.x()(b,c)<=a[1]})}}));b.transition().duration(B).call(g),Q.select(".nv-focus .nv-x.nv-axis").transition().duration(B).call(i),Q.select(".nv-focus .nv-y.nv-axis").transition().duration(B).call(j)}}var I=d3.select(this),J=this;a.utils.initSVG(I);var K=a.utils.availableWidth(t,I,q),L=a.utils.availableHeight(u,I,q)-v,M=v-r.top-r.bottom;if(b.update=function(){I.transition().duration(B).call(b)},b.container=this,C.setter(F(o),b.update).getter(E(o)).update(),C.disabled=o.map(function(a){return!!a.disabled}),!D){var N;D={};for(N in C)D[N]=C[N]instanceof Array?C[N].slice(0):C[N]}if(!(o&&o.length&&o.filter(function(a){return a.values.length}).length))return a.utils.noData(b,I),b;I.selectAll(".nv-noData").remove(),c=g.xScale(),d=g.yScale(),e=h.xScale(),f=h.yScale();var O=I.selectAll("g.nv-wrap.nv-lineWithFocusChart").data([o]),P=O.enter().append("g").attr("class","nvd3 nv-wrap nv-lineWithFocusChart").append("g"),Q=O.select("g");P.append("g").attr("class","nv-legendWrap");var R=P.append("g").attr("class","nv-focus");R.append("g").attr("class","nv-x nv-axis"),R.append("g").attr("class","nv-y nv-axis"),R.append("g").attr("class","nv-linesWrap"),R.append("g").attr("class","nv-interactive");var S=P.append("g").attr("class","nv-context");S.append("g").attr("class","nv-x nv-axis"),S.append("g").attr("class","nv-y nv-axis"),S.append("g").attr("class","nv-linesWrap"),S.append("g").attr("class","nv-brushBackground"),S.append("g").attr("class","nv-x nv-brush"),x&&(m.width(K),Q.select(".nv-legendWrap").datum(o).call(m),q.top!=m.height()&&(q.top=m.height(),L=a.utils.availableHeight(u,I,q)-v),Q.select(".nv-legendWrap").attr("transform","translate(0,"+-q.top+")")),O.attr("transform","translate("+q.left+","+q.top+")"),w&&(p.width(K).height(L).margin({left:q.left,top:q.top}).svgContainer(I).xScale(c),O.select(".nv-interactive").call(p)),g.width(K).height(L).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),h.defined(g.defined()).width(K).height(M).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),Q.select(".nv-context").attr("transform","translate(0,"+(L+q.bottom+r.top)+")");var T=Q.select(".nv-context .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}));d3.transition(T).call(h),i.scale(c)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-L,0),j.scale(d)._ticks(a.utils.calcTicksY(L/36,o)).tickSize(-K,0),Q.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+L+")"),n.x(e).on("brush",function(){H()}),y&&n.extent(y);var U=Q.select(".nv-brushBackground").selectAll("g").data([y||n.extent()]),V=U.enter().append("g");V.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",M),V.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",M);var W=Q.select(".nv-x.nv-brush").call(n);W.selectAll("rect").attr("height",M),W.selectAll(".resize").append("path").attr("d",z),H(),k.scale(e)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-M,0),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),d3.transition(Q.select(".nv-context .nv-x.nv-axis")).call(k),l.scale(f)._ticks(a.utils.calcTicksY(M/36,o)).tickSize(-K,0),d3.transition(Q.select(".nv-context .nv-y.nv-axis")).call(l),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),m.dispatch.on("stateChange",function(a){for(var c in a)C[c]=a[c];A.stateChange(C),b.update()}),p.dispatch.on("elementMousemove",function(c){g.clearHighlights();var d,f,h,k=[];if(o.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(i,j){var l=n.empty()?e.domain():n.extent(),m=i.values.filter(function(a,b){return g.x()(a,b)>=l[0]&&g.x()(a,b)<=l[1]});f=a.interactiveBisect(m,c.pointXValue,g.x());var o=m[f],p=b.y()(o,f);null!=p&&g.highlightPoint(j,f,!0),void 0!==o&&(void 0===d&&(d=o),void 0===h&&(h=b.xScale()(b.x()(o,f))),k.push({key:i.key,value:b.y()(o,f),color:s(i,i.seriesIndex)}))}),k.length>2){var l=b.yScale().invert(c.mouseY),m=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),r=.03*m,t=a.nearestValueIndex(k.map(function(a){return a.value}),l,r);null!==t&&(k[t].highlight=!0)}var u=i.tickFormat()(b.x()(d,f));p.tooltip.position({left:c.mouseX+q.left,top:c.mouseY+q.top}).chartContainer(J.parentNode).valueFormatter(function(a){return null==a?"N/A":j.tickFormat()(a)}).data({value:u,index:f,series:k})(),p.renderGuideLine(h)}),p.dispatch.on("elementMouseout",function(){g.clearHighlights()}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&o.forEach(function(b,c){b.disabled=a.disabled[c]}),b.update()})}),b}var c,d,e,f,g=a.models.line(),h=a.models.line(),i=a.models.axis(),j=a.models.axis(),k=a.models.axis(),l=a.models.axis(),m=a.models.legend(),n=d3.svg.brush(),o=a.models.tooltip(),p=a.interactiveGuideline(),q={top:30,right:30,bottom:30,left:60},r={top:0,right:30,bottom:20,left:60},s=a.utils.defaultColor(),t=null,u=null,v=50,w=!1,x=!0,y=null,z=null,A=d3.dispatch("brush","stateChange","changeState"),B=250,C=a.utils.state(),D=null;g.clipEdge(!0).duration(0),h.interactive(!1),i.orient("bottom").tickPadding(5),j.orient("left"),k.orient("bottom").tickPadding(5),l.orient("left"),o.valueFormatter(function(a,b){return j.tickFormat()(a,b)}).headerFormatter(function(a,b){return i.tickFormat()(a,b)});var E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return g.dispatch.on("elementMouseover.tooltip",function(a){o.data(a).position(a.pos).hidden(!1)}),g.dispatch.on("elementMouseout.tooltip",function(){o.hidden(!0)}),b.dispatch=A,b.legend=m,b.lines=g,b.lines2=h,b.xAxis=i,b.yAxis=j,b.x2Axis=k,b.y2Axis=l,b.interactiveLayer=p,b.tooltip=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return t},set:function(a){t=a}},height:{get:function(){return u},set:function(a){u=a}},focusHeight:{get:function(){return v},set:function(a){v=a}},showLegend:{get:function(){return x},set:function(a){x=a}},brushExtent:{get:function(){return y},set:function(a){y=a}},defaultState:{get:function(){return D},set:function(a){D=a}},noData:{get:function(){return z},set:function(a){z=a}},tooltips:{get:function(){return o.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),o.enabled(!!b)}},tooltipContent:{get:function(){return o.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),o.contentGenerator(b)}},margin:{get:function(){return q},set:function(a){q.top=void 0!==a.top?a.top:q.top,q.right=void 0!==a.right?a.right:q.right,q.bottom=void 0!==a.bottom?a.bottom:q.bottom,q.left=void 0!==a.left?a.left:q.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b),m.color(s)}},interpolate:{get:function(){return g.interpolate()},set:function(a){g.interpolate(a),h.interpolate(a)}},xTickFormat:{get:function(){return i.tickFormat()},set:function(a){i.tickFormat(a),k.tickFormat(a)}},yTickFormat:{get:function(){return j.tickFormat()},set:function(a){j.tickFormat(a),l.tickFormat(a)}},duration:{get:function(){return B},set:function(a){B=a,j.duration(B),l.duration(B),i.duration(B),k.duration(B)}},x:{get:function(){return g.x()},set:function(a){g.x(a),h.x(a)}},y:{get:function(){return g.y()},set:function(a){g.y(a),h.y(a)}},useInteractiveGuideline:{get:function(){return w},set:function(a){w=a,w&&(g.interactive(!1),g.useVoronoi(!1))}}}),a.utils.inheritOptions(b,g),a.utils.initOptions(b),b},a.models.multiBar=function(){"use strict";function b(E){return C.reset(),E.each(function(b){var E=k-j.left-j.right,F=l-j.top-j.bottom;p=d3.select(this),a.utils.initSVG(p);var G=0;if(x&&b.length&&(x=[{values:b[0].values.map(function(a){return{x:a.x,y:0,series:a.series,size:.01}})}]),u){var H=d3.layout.stack().offset(v).values(function(a){return a.values}).y(r)(!b.length&&x?x:b);H.forEach(function(a,c){a.nonStackable?(b[c].nonStackableSeries=G++,H[c]=b[c]):c>0&&H[c-1].nonStackable&&H[c].values.map(function(a,b){a.y0-=H[c-1].values[b].y,a.y1=a.y0+a.y})}),b=H}b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),u&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a,f){if(!b[f].nonStackable){var g=a.values[c];g.size=Math.abs(g.y),g.y<0?(g.y1=e,e-=g.size):(g.y1=g.size+d,d+=g.size)}})});var I=d&&e?[]:b.map(function(a,b){return a.values.map(function(a,c){return{x:q(a,c),y:r(a,c),y0:a.y0,y1:a.y1,idx:b}})});m.domain(d||d3.merge(I).map(function(a){return a.x})).rangeBands(f||[0,E],A),n.domain(e||d3.extent(d3.merge(I).map(function(a){var c=a.y;return u&&!b[a.idx].nonStackable&&(c=a.y>0?a.y1:a.y1+a.y),c}).concat(s))).range(g||[F,0]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]+.01*n.domain()[0],n.domain()[1]-.01*n.domain()[1]]:[-1,1]),h=h||m,i=i||n;var J=p.selectAll("g.nv-wrap.nv-multibar").data([b]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multibar"),L=K.append("defs"),M=K.append("g"),N=J.select("g");M.append("g").attr("class","nv-groups"),J.attr("transform","translate("+j.left+","+j.top+")"),L.append("clipPath").attr("id","nv-edge-clip-"+o).append("rect"),J.select("#nv-edge-clip-"+o+" rect").attr("width",E).attr("height",F),N.attr("clip-path",t?"url(#nv-edge-clip-"+o+")":"");var O=J.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});O.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);var P=C.transition(O.exit().selectAll("rect.nv-bar"),"multibarExit",Math.min(100,z)).attr("y",function(a){var c=i(0)||0;return u&&b[a.series]&&!b[a.series].nonStackable&&(c=i(a.y0)),c}).attr("height",0).remove();P.delay&&P.delay(function(a,b){var c=b*(z/(D+1))-b;return c}),O.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return w(a,b)}).style("stroke",function(a,b){return w(a,b)}),O.style("stroke-opacity",1).style("fill-opacity",.75);var Q=O.selectAll("rect.nv-bar").data(function(a){return x&&!b.length?x.values:a.values});Q.exit().remove();Q.enter().append("rect").attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("x",function(a,c,d){return u&&!b[d].nonStackable?0:d*m.rangeBand()/b.length}).attr("y",function(a,c,d){return i(u&&!b[d].nonStackable?a.y0:0)||0}).attr("height",0).attr("width",function(a,c,d){return m.rangeBand()/(u&&!b[d].nonStackable?1:b.length)}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"});Q.style("fill",function(a,b,c){return w(a,c,b)}).style("stroke",function(a,b,c){return w(a,c,b)}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),B.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),B.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){B.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){B.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){B.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),Q.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"}),y&&(c||(c=b.map(function(){return!0})),Q.style("fill",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}));var R=Q.watchTransition(C,"multibar",Math.min(250,z)).delay(function(a,c){return c*z/b[0].values.length});u?R.attr("y",function(a,c,d){var e=0;return e=b[d].nonStackable?r(a,c)<0?n(0):n(0)-n(r(a,c))<-1?n(0)-1:n(r(a,c))||0:n(a.y1)}).attr("height",function(a,c,d){return b[d].nonStackable?Math.max(Math.abs(n(r(a,c))-n(0)),1)||0:Math.max(Math.abs(n(a.y+a.y0)-n(a.y0)),1)}).attr("x",function(a,c,d){var e=0;return b[d].nonStackable&&(e=a.series*m.rangeBand()/b.length,b.length!==G&&(e=b[d].nonStackableSeries*m.rangeBand()/(2*G))),e}).attr("width",function(a,c,d){if(b[d].nonStackable){var e=m.rangeBand()/G;return b.length!==G&&(e=m.rangeBand()/(2*G)),e}return m.rangeBand()}):R.attr("x",function(a){return a.series*m.rangeBand()/b.length}).attr("width",m.rangeBand()/b.length).attr("y",function(a,b){return r(a,b)<0?n(0):n(0)-n(r(a,b))<1?n(0)-1:n(r(a,b))||0}).attr("height",function(a,b){return Math.max(Math.abs(n(r(a,b))-n(0)),1)||0}),h=m.copy(),i=n.copy(),b[0]&&b[0].values&&(D=b[0].values.length)}),C.renderEnd("multibar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=d3.scale.ordinal(),n=d3.scale.linear(),o=Math.floor(1e4*Math.random()),p=null,q=function(a){return a.x},r=function(a){return a.y},s=[0],t=!0,u=!1,v="zero",w=a.utils.defaultColor(),x=!1,y=null,z=500,A=.1,B=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),C=a.utils.renderWatch(B,z),D=0;return b.dispatch=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return s},set:function(a){s=a}},stacked:{get:function(){return u},set:function(a){u=a}},stackOffset:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return t},set:function(a){t=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return o},set:function(a){o=a}},hideable:{get:function(){return x},set:function(a){x=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z)}},color:{get:function(){return w},set:function(b){w=a.utils.getColor(b)}},barColor:{get:function(){return y},set:function(b){y=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarChart=function(){"use strict";function b(j){return D.reset(),D.models(e),r&&D.models(f),s&&D.models(g),j.each(function(j){var z=d3.select(this);a.utils.initSVG(z);var D=a.utils.availableWidth(l,z,k),H=a.utils.availableHeight(m,z,k);if(b.update=function(){0===C?z.call(b):z.transition().duration(C).call(b)},b.container=this,x.setter(G(j),b.update).getter(F(j)).update(),x.disabled=j.map(function(a){return!!a.disabled}),!y){var I;y={};for(I in x)y[I]=x[I]instanceof Array?x[I].slice(0):x[I]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,z),b;z.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();
+var J=z.selectAll("g.nv-wrap.nv-multiBarWithLegend").data([j]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarWithLegend").append("g"),L=J.select("g");if(K.append("g").attr("class","nv-x nv-axis"),K.append("g").attr("class","nv-y nv-axis"),K.append("g").attr("class","nv-barsWrap"),K.append("g").attr("class","nv-legendWrap"),K.append("g").attr("class","nv-controlsWrap"),q&&(h.width(D-B()),L.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),H=a.utils.availableHeight(m,z,k)),L.select(".nv-legendWrap").attr("transform","translate("+B()+","+-k.top+")")),o){var M=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(B()).color(["#444","#444","#444"]),L.select(".nv-controlsWrap").datum(M).attr("transform","translate(0,"+-k.top+")").call(i)}J.attr("transform","translate("+k.left+","+k.top+")"),t&&L.select(".nv-y.nv-axis").attr("transform","translate("+D+",0)"),e.disabled(j.map(function(a){return a.disabled})).width(D).height(H).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var N=L.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(N.call(e),r){f.scale(c)._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-H,0),L.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),L.select(".nv-x.nv-axis").call(f);var O=L.select(".nv-x.nv-axis > g").selectAll("g");if(O.selectAll("line, text").style("opacity",1),v){var P=function(a,b){return"translate("+a+","+b+")"},Q=5,R=17;O.selectAll("text").attr("transform",function(a,b,c){return P(0,c%2==0?Q:R)});var S=d3.selectAll(".nv-x.nv-axis .nv-wrap g g text")[0].length;L.selectAll(".nv-x.nv-axis .nv-axisMaxMin text").attr("transform",function(a,b){return P(0,0===b||S%2!==0?R:Q)})}u&&O.filter(function(a,b){return b%Math.ceil(j[0].values.length/(D/100))!==0}).selectAll("text, line").style("opacity",0),w&&O.selectAll(".tick text").attr("transform","rotate("+w+" 0,0)").style("text-anchor",w>0?"start":"end"),L.select(".nv-x.nv-axis").selectAll("g.nv-axisMaxMin text").style("opacity",1)}s&&(g.scale(d)._ticks(a.utils.calcTicksY(H/36,j)).tickSize(-D,0),L.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)x[c]=a[c];A.stateChange(x),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(M=M.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":case p.grouped:e.stacked(!1);break;case"Stacked":case p.stacked:e.stacked(!0)}x.stacked=e.stacked(),A.stateChange(x),b.update()}}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),x.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),x.stacked=a.stacked,E=a.stacked),b.update()})}),D.renderEnd("multibarchart immediate"),b}var c,d,e=a.models.multiBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=0,x=a.utils.state(),y=null,z=null,A=d3.dispatch("stateChange","changeState","renderEnd"),B=function(){return o?180:0},C=250;x.stacked=!1,e.stacked(!1),f.orient("bottom").tickPadding(7).showMaxMin(!1).tickFormat(function(a){return a}),g.orient(t?"right":"left").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var D=a.utils.renderWatch(A),E=!1,F=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:E}}},G=function(a){return function(b){void 0!==b.stacked&&(E=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=A,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=x,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return y},set:function(a){y=a}},noData:{get:function(){return z},set:function(a){z=a}},reduceXTicks:{get:function(){return u},set:function(a){u=a}},rotateLabels:{get:function(){return w},set:function(a){w=a}},staggerLabels:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return C},set:function(a){C=a,e.duration(C),f.duration(C),g.duration(C),D.reset(C)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiBarHorizontal=function(){"use strict";function b(m){return E.reset(),m.each(function(b){var m=k-j.left-j.right,C=l-j.top-j.bottom;n=d3.select(this),a.utils.initSVG(n),w&&(b=d3.layout.stack().offset("zero").values(function(a){return a.values}).y(r)(b)),b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),w&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a){var b=a.values[c];b.size=Math.abs(b.y),b.y<0?(b.y1=e-b.size,e-=b.size):(b.y1=d,d+=b.size)})});var F=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:q(a,b),y:r(a,b),y0:a.y0,y1:a.y1}})});o.domain(d||d3.merge(F).map(function(a){return a.x})).rangeBands(f||[0,C],A),p.domain(e||d3.extent(d3.merge(F).map(function(a){return w?a.y>0?a.y1+a.y:a.y1:a.y}).concat(t))),p.range(x&&!w?g||[p.domain()[0]<0?z:0,m-(p.domain()[1]>0?z:0)]:g||[0,m]),h=h||o,i=i||d3.scale.linear().domain(p.domain()).range([p(0),p(0)]);{var G=d3.select(this).selectAll("g.nv-wrap.nv-multibarHorizontal").data([b]),H=G.enter().append("g").attr("class","nvd3 nv-wrap nv-multibarHorizontal"),I=(H.append("defs"),H.append("g"));G.select("g")}I.append("g").attr("class","nv-groups"),G.attr("transform","translate("+j.left+","+j.top+")");var J=G.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});J.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),J.exit().watchTransition(E,"multibarhorizontal: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),J.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return u(a,b)}).style("stroke",function(a,b){return u(a,b)}),J.watchTransition(E,"multibarhorizontal: groups").style("stroke-opacity",1).style("fill-opacity",.75);var K=J.selectAll("g.nv-bar").data(function(a){return a.values});K.exit().remove();var L=K.enter().append("g").attr("transform",function(a,c,d){return"translate("+i(w?a.y0:0)+","+(w?0:d*o.rangeBand()/b.length+o(q(a,c)))+")"});L.append("rect").attr("width",0).attr("height",o.rangeBand()/(w?1:b.length)),K.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),D.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){D.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){D.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){D.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),s(b[0],0)&&(L.append("polyline"),K.select("polyline").attr("fill","none").attr("points",function(a,c){var d=s(a,c),e=.8*o.rangeBand()/(2*(w?1:b.length));d=d.length?d:[-Math.abs(d),Math.abs(d)],d=d.map(function(a){return p(a)-p(0)});var f=[[d[0],-e],[d[0],e],[d[0],0],[d[1],0],[d[1],-e],[d[1],e]];return f.map(function(a){return a.join(",")}).join(" ")}).attr("transform",function(a,c){var d=o.rangeBand()/(2*(w?1:b.length));return"translate("+(r(a,c)<0?0:p(r(a,c))-p(0))+", "+d+")"})),L.append("text"),x&&!w?(K.select("text").attr("text-anchor",function(a,b){return r(a,b)<0?"end":"start"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){var c=B(r(a,b)),d=s(a,b);return void 0===d?c:d.length?c+"+"+B(Math.abs(d[1]))+"-"+B(Math.abs(d[0])):c+"±"+B(Math.abs(d))}),K.watchTransition(E,"multibarhorizontal: bars").select("text").attr("x",function(a,b){return r(a,b)<0?-4:p(r(a,b))-p(0)+4})):K.selectAll("text").text(""),y&&!w?(L.append("text").classed("nv-bar-label",!0),K.select("text.nv-bar-label").attr("text-anchor",function(a,b){return r(a,b)<0?"start":"end"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){return q(a,b)}),K.watchTransition(E,"multibarhorizontal: bars").select("text.nv-bar-label").attr("x",function(a,b){return r(a,b)<0?p(0)-p(r(a,b))+4:-4})):K.selectAll("text.nv-bar-label").text(""),K.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}),v&&(c||(c=b.map(function(){return!0})),K.style("fill",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()})),w?K.watchTransition(E,"multibarhorizontal: bars").attr("transform",function(a,b){return"translate("+p(a.y1)+","+o(q(a,b))+")"}).select("rect").attr("width",function(a,b){return Math.abs(p(r(a,b)+a.y0)-p(a.y0))}).attr("height",o.rangeBand()):K.watchTransition(E,"multibarhorizontal: bars").attr("transform",function(a,c){return"translate("+p(r(a,c)<0?r(a,c):0)+","+(a.series*o.rangeBand()/b.length+o(q(a,c)))+")"}).select("rect").attr("height",o.rangeBand()/b.length).attr("width",function(a,b){return Math.max(Math.abs(p(r(a,b))-p(0)),1)}),h=o.copy(),i=p.copy()}),E.renderEnd("multibarHorizontal immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=null,o=d3.scale.ordinal(),p=d3.scale.linear(),q=function(a){return a.x},r=function(a){return a.y},s=function(a){return a.yErr},t=[0],u=a.utils.defaultColor(),v=null,w=!1,x=!1,y=!1,z=60,A=.1,B=d3.format(",.2f"),C=250,D=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),E=a.utils.renderWatch(D,C);return b.dispatch=D,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},yErr:{get:function(){return s},set:function(a){s=a}},xScale:{get:function(){return o},set:function(a){o=a}},yScale:{get:function(){return p},set:function(a){p=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return t},set:function(a){t=a}},stacked:{get:function(){return w},set:function(a){w=a}},showValues:{get:function(){return x},set:function(a){x=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return m},set:function(a){m=a}},valueFormat:{get:function(){return B},set:function(a){B=a}},valuePadding:{get:function(){return z},set:function(a){z=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return C},set:function(a){C=a,E.reset(C)}},color:{get:function(){return u},set:function(b){u=a.utils.getColor(b)}},barColor:{get:function(){return v},set:function(b){v=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarHorizontalChart=function(){"use strict";function b(j){return C.reset(),C.models(e),r&&C.models(f),s&&C.models(g),j.each(function(j){var w=d3.select(this);a.utils.initSVG(w);var C=a.utils.availableWidth(l,w,k),D=a.utils.availableHeight(m,w,k);if(b.update=function(){w.transition().duration(z).call(b)},b.container=this,t=e.stacked(),u.setter(B(j),b.update).getter(A(j)).update(),u.disabled=j.map(function(a){return!!a.disabled}),!v){var E;v={};for(E in u)v[E]=u[E]instanceof Array?u[E].slice(0):u[E]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,w),b;w.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var F=w.selectAll("g.nv-wrap.nv-multiBarHorizontalChart").data([j]),G=F.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarHorizontalChart").append("g"),H=F.select("g");if(G.append("g").attr("class","nv-x nv-axis"),G.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),G.append("g").attr("class","nv-barsWrap"),G.append("g").attr("class","nv-legendWrap"),G.append("g").attr("class","nv-controlsWrap"),q&&(h.width(C-y()),H.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),D=a.utils.availableHeight(m,w,k)),H.select(".nv-legendWrap").attr("transform","translate("+y()+","+-k.top+")")),o){var I=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(y()).color(["#444","#444","#444"]),H.select(".nv-controlsWrap").datum(I).attr("transform","translate(0,"+-k.top+")").call(i)}F.attr("transform","translate("+k.left+","+k.top+")"),e.disabled(j.map(function(a){return a.disabled})).width(C).height(D).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var J=H.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(J.transition().call(e),r){f.scale(c)._ticks(a.utils.calcTicksY(D/24,j)).tickSize(-C,0),H.select(".nv-x.nv-axis").call(f);var K=H.select(".nv-x.nv-axis").selectAll("g");K.selectAll("line, text")}s&&(g.scale(d)._ticks(a.utils.calcTicksX(C/100,j)).tickSize(-D,0),H.select(".nv-y.nv-axis").attr("transform","translate(0,"+D+")"),H.select(".nv-y.nv-axis").call(g)),H.select(".nv-zeroLine line").attr("x1",d(0)).attr("x2",d(0)).attr("y1",0).attr("y2",-D),h.dispatch.on("stateChange",function(a){for(var c in a)u[c]=a[c];x.stateChange(u),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(I=I.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":e.stacked(!1);break;case"Stacked":e.stacked(!0)}u.stacked=e.stacked(),x.stateChange(u),t=e.stacked(),b.update()}}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),u.stacked=a.stacked,t=a.stacked),b.update()})}),C.renderEnd("multibar horizontal chart immediate"),b}var c,d,e=a.models.multiBarHorizontal(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend().height(30),i=a.models.legend().height(30),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=a.utils.state(),v=null,w=null,x=d3.dispatch("stateChange","changeState","renderEnd"),y=function(){return o?180:0},z=250;u.stacked=!1,e.stacked(t),f.orient("left").tickPadding(5).showMaxMin(!1).tickFormat(function(a){return a}),g.orient("bottom").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var A=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:t}}},B=function(a){return function(b){void 0!==b.stacked&&(t=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},C=a.utils.renderWatch(x,z);return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=x,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=u,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z),e.duration(z),f.duration(z),g.duration(z)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiChart=function(){"use strict";function b(j){return j.each(function(j){function k(a){var b=2===j[a.seriesIndex].yAxis?z:y;a.value=a.point.x,a.series={value:a.point.y,color:a.point.color},B.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function l(a){var b=2===j[a.seriesIndex].yAxis?z:y;a.point.x=v.x()(a.point),a.point.y=v.y()(a.point),B.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function n(a){var b=2===j[a.data.series].yAxis?z:y;a.value=t.x()(a.data),a.series={value:t.y()(a.data),color:a.color},B.duration(0).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).hidden(!1)}var C=d3.select(this);a.utils.initSVG(C),b.update=function(){C.transition().call(b)},b.container=this;var D=a.utils.availableWidth(g,C,e),E=a.utils.availableHeight(h,C,e),F=j.filter(function(a){return"line"==a.type&&1==a.yAxis}),G=j.filter(function(a){return"line"==a.type&&2==a.yAxis}),H=j.filter(function(a){return"bar"==a.type&&1==a.yAxis}),I=j.filter(function(a){return"bar"==a.type&&2==a.yAxis}),J=j.filter(function(a){return"area"==a.type&&1==a.yAxis}),K=j.filter(function(a){return"area"==a.type&&2==a.yAxis});if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,C),b;C.selectAll(".nv-noData").remove();var L=j.filter(function(a){return!a.disabled&&1==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})}),M=j.filter(function(a){return!a.disabled&&2==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})});o.domain(d3.extent(d3.merge(L.concat(M)),function(a){return a.x})).range([0,D]);var N=C.selectAll("g.wrap.multiChart").data([j]),O=N.enter().append("g").attr("class","wrap nvd3 multiChart").append("g");O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y1 nv-axis"),O.append("g").attr("class","nv-y2 nv-axis"),O.append("g").attr("class","lines1Wrap"),O.append("g").attr("class","lines2Wrap"),O.append("g").attr("class","bars1Wrap"),O.append("g").attr("class","bars2Wrap"),O.append("g").attr("class","stack1Wrap"),O.append("g").attr("class","stack2Wrap"),O.append("g").attr("class","legendWrap");var P=N.select("g"),Q=j.map(function(a,b){return j[b].color||f(a,b)});if(i){var R=A.align()?D/2:D,S=A.align()?R:0;A.width(R),A.color(Q),P.select(".legendWrap").datum(j.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(1==a.yAxis?"":" (right axis)"),a})).call(A),e.top!=A.height()&&(e.top=A.height(),E=a.utils.availableHeight(h,C,e)),P.select(".legendWrap").attr("transform","translate("+S+","+-e.top+")")}r.width(D).height(E).interpolate(m).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"line"==j[b].type})),s.width(D).height(E).interpolate(m).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"line"==j[b].type})),t.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"bar"==j[b].type})),u.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"bar"==j[b].type})),v.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"area"==j[b].type})),w.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"area"==j[b].type})),P.attr("transform","translate("+e.left+","+e.top+")");var T=P.select(".lines1Wrap").datum(F.filter(function(a){return!a.disabled})),U=P.select(".bars1Wrap").datum(H.filter(function(a){return!a.disabled})),V=P.select(".stack1Wrap").datum(J.filter(function(a){return!a.disabled})),W=P.select(".lines2Wrap").datum(G.filter(function(a){return!a.disabled})),X=P.select(".bars2Wrap").datum(I.filter(function(a){return!a.disabled})),Y=P.select(".stack2Wrap").datum(K.filter(function(a){return!a.disabled})),Z=J.length?J.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[],$=K.length?K.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[];p.domain(c||d3.extent(d3.merge(L).concat(Z),function(a){return a.y})).range([0,E]),q.domain(d||d3.extent(d3.merge(M).concat($),function(a){return a.y})).range([0,E]),r.yDomain(p.domain()),t.yDomain(p.domain()),v.yDomain(p.domain()),s.yDomain(q.domain()),u.yDomain(q.domain()),w.yDomain(q.domain()),J.length&&d3.transition(V).call(v),K.length&&d3.transition(Y).call(w),H.length&&d3.transition(U).call(t),I.length&&d3.transition(X).call(u),F.length&&d3.transition(T).call(r),G.length&&d3.transition(W).call(s),x._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-E,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+E+")"),d3.transition(P.select(".nv-x.nv-axis")).call(x),y._ticks(a.utils.calcTicksY(E/36,j)).tickSize(-D,0),d3.transition(P.select(".nv-y1.nv-axis")).call(y),z._ticks(a.utils.calcTicksY(E/36,j)).tickSize(-D,0),d3.transition(P.select(".nv-y2.nv-axis")).call(z),P.select(".nv-y1.nv-axis").classed("nv-disabled",L.length?!1:!0).attr("transform","translate("+o.range()[0]+",0)"),P.select(".nv-y2.nv-axis").classed("nv-disabled",M.length?!1:!0).attr("transform","translate("+o.range()[1]+",0)"),A.dispatch.on("stateChange",function(){b.update()}),r.dispatch.on("elementMouseover.tooltip",k),s.dispatch.on("elementMouseover.tooltip",k),r.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),s.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),v.dispatch.on("elementMouseover.tooltip",l),w.dispatch.on("elementMouseover.tooltip",l),v.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),w.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),t.dispatch.on("elementMouseover.tooltip",n),u.dispatch.on("elementMouseover.tooltip",n),t.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),u.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),t.dispatch.on("elementMousemove.tooltip",function(){B.position({top:d3.event.pageY,left:d3.event.pageX})()}),u.dispatch.on("elementMousemove.tooltip",function(){B.position({top:d3.event.pageY,left:d3.event.pageX})()})}),b}var c,d,e={top:30,right:20,bottom:50,left:60},f=a.utils.defaultColor(),g=null,h=null,i=!0,j=null,k=function(a){return a.x},l=function(a){return a.y},m="monotone",n=!0,o=d3.scale.linear(),p=d3.scale.linear(),q=d3.scale.linear(),r=a.models.line().yScale(p),s=a.models.line().yScale(q),t=a.models.multiBar().stacked(!1).yScale(p),u=a.models.multiBar().stacked(!1).yScale(q),v=a.models.stackedArea().yScale(p),w=a.models.stackedArea().yScale(q),x=a.models.axis().scale(o).orient("bottom").tickPadding(5),y=a.models.axis().scale(p).orient("left"),z=a.models.axis().scale(q).orient("right"),A=a.models.legend().height(30),B=a.models.tooltip(),C=d3.dispatch();return b.dispatch=C,b.lines1=r,b.lines2=s,b.bars1=t,b.bars2=u,b.stack1=v,b.stack2=w,b.xAxis=x,b.yAxis1=y,b.yAxis2=z,b.tooltip=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},showLegend:{get:function(){return i},set:function(a){i=a}},yDomain1:{get:function(){return c},set:function(a){c=a}},yDomain2:{get:function(){return d},set:function(a){d=a}},noData:{get:function(){return j},set:function(a){j=a}},interpolate:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return B.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),B.enabled(!!b)}},tooltipContent:{get:function(){return B.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),B.contentGenerator(b)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return f},set:function(b){f=a.utils.getColor(b)}},x:{get:function(){return k},set:function(a){k=a,r.x(a),s.x(a),t.x(a),u.x(a),v.x(a),w.x(a)}},y:{get:function(){return l},set:function(a){l=a,r.y(a),s.y(a),v.y(a),w.y(a),t.y(a),u.y(a)}},useVoronoi:{get:function(){return n},set:function(a){n=a,r.useVoronoi(a),s.useVoronoi(a),v.useVoronoi(a),w.useVoronoi(a)}}}),a.utils.initOptions(b),b},a.models.ohlcBar=function(){"use strict";function b(y){return y.each(function(b){k=d3.select(this);var y=a.utils.availableWidth(h,k,g),A=a.utils.availableHeight(i,k,g);a.utils.initSVG(k);var B=y/b[0].values.length*.9;l.domain(c||d3.extent(b[0].values.map(n).concat(t))),l.range(v?e||[.5*y/b[0].values.length,y*(b[0].values.length-.5)/b[0].values.length]:e||[5+B/2,y-B/2-5]),m.domain(d||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(f||[A,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var C=d3.select(this).selectAll("g.nv-wrap.nv-ohlcBar").data([b[0].values]),D=C.enter().append("g").attr("class","nvd3 nv-wrap nv-ohlcBar"),E=D.append("defs"),F=D.append("g"),G=C.select("g");F.append("g").attr("class","nv-ticks"),C.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:j})}),E.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),C.select("#nv-chart-clip-path-"+j+" rect").attr("width",y).attr("height",A),G.attr("clip-path",w?"url(#nv-chart-clip-path-"+j+")":"");var H=C.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});H.exit().remove(),H.enter().append("path").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}).attr("d",function(a,b){return"m0,0l0,"+(m(p(a,b))-m(r(a,b)))+"l"+-B/2+",0l"+B/2+",0l0,"+(m(s(a,b))-m(p(a,b)))+"l0,"+(m(q(a,b))-m(s(a,b)))+"l"+B/2+",0l"+-B/2+",0z"}).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("fill",function(){return x[0]}).attr("stroke",function(){return x[0]}).attr("x",0).attr("y",function(a,b){return m(Math.max(0,o(a,b)))}).attr("height",function(a,b){return Math.abs(m(o(a,b))-m(0))}),H.attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}),d3.transition(H).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("d",function(a,c){var d=y/b[0].values.length*.9;return"m0,0l0,"+(m(p(a,c))-m(r(a,c)))+"l"+-d/2+",0l"+d/2+",0l0,"+(m(s(a,c))-m(p(a,c)))+"l0,"+(m(q(a,c))-m(s(a,c)))+"l"+d/2+",0l"+-d/2+",0z"})}),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,c){b.clearHighlights(),k.select(".nv-ohlcBar .nv-tick-0-"+a).classed("hover",c)},b.clearHighlights=function(){k.select(".nv-ohlcBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!=a.top?a.top:g.top,g.right=void 0!=a.right?a.right:g.right,g.bottom=void 0!=a.bottom?a.bottom:g.bottom,g.left=void 0!=a.left?a.left:g.left
+}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.parallelCoordinates=function(){"use strict";function b(p){return p.each(function(b){function p(a){return F(h.map(function(b){if(isNaN(a[b])||isNaN(parseFloat(a[b]))){var c=g[b].domain(),d=g[b].range(),e=c[0]-(c[1]-c[0])/9;if(J.indexOf(b)<0){var h=d3.scale.linear().domain([e,c[1]]).range([x-12,d[1]]);g[b].brush.y(h),J.push(b)}return[f(b),g[b](e)]}return J.length>0?(D.style("display","inline"),E.style("display","inline")):(D.style("display","none"),E.style("display","none")),[f(b),g[b](a[b])]}))}function q(){var a=h.filter(function(a){return!g[a].brush.empty()}),b=a.map(function(a){return g[a].brush.extent()});k=[],a.forEach(function(a,c){k[c]={dimension:a,extent:b[c]}}),l=[],M.style("display",function(c){var d=a.every(function(a,d){return isNaN(c[a])&&b[d][0]==g[a].brush.y().domain()[0]?!0:b[d][0]<=c[a]&&c[a]<=b[d][1]});return d&&l.push(c),d?null:"none"}),o.brush({filters:k,active:l})}function r(a){m[a]=this.parentNode.__origin__=f(a),L.attr("visibility","hidden")}function s(a){m[a]=Math.min(w,Math.max(0,this.parentNode.__origin__+=d3.event.x)),M.attr("d",p),h.sort(function(a,b){return u(a)-u(b)}),f.domain(h),N.attr("transform",function(a){return"translate("+u(a)+")"})}function t(a){delete this.parentNode.__origin__,delete m[a],d3.select(this.parentNode).attr("transform","translate("+f(a)+")"),M.attr("d",p),L.attr("d",p).attr("visibility",null)}function u(a){var b=m[a];return null==b?f(a):b}var v=d3.select(this),w=a.utils.availableWidth(d,v,c),x=a.utils.availableHeight(e,v,c);a.utils.initSVG(v),l=b,f.rangePoints([0,w],1).domain(h);var y={};h.forEach(function(a){var c=d3.extent(b,function(b){return+b[a]});return y[a]=!1,void 0===c[0]&&(y[a]=!0,c[0]=0,c[1]=0),c[0]===c[1]&&(c[0]=c[0]-1,c[1]=c[1]+1),g[a]=d3.scale.linear().domain(c).range([.9*(x-12),0]),g[a].brush=d3.svg.brush().y(g[a]).on("brush",q),"name"!=a});var z=v.selectAll("g.nv-wrap.nv-parallelCoordinates").data([b]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-parallelCoordinates"),B=A.append("g"),C=z.select("g");B.append("g").attr("class","nv-parallelCoordinates background"),B.append("g").attr("class","nv-parallelCoordinates foreground"),B.append("g").attr("class","nv-parallelCoordinates missingValuesline"),z.attr("transform","translate("+c.left+","+c.top+")");var D,E,F=d3.svg.line().interpolate("cardinal").tension(n),G=d3.svg.axis().orient("left"),H=d3.behavior.drag().on("dragstart",r).on("drag",s).on("dragend",t),I=f.range()[1]-f.range()[0],J=[],K=[0+I/2,x-12,w-I/2,x-12];D=z.select(".missingValuesline").selectAll("line").data([K]),D.enter().append("line"),D.exit().remove(),D.attr("x1",function(a){return a[0]}).attr("y1",function(a){return a[1]}).attr("x2",function(a){return a[2]}).attr("y2",function(a){return a[3]}),E=z.select(".missingValuesline").selectAll("text").data(["undefined values"]),E.append("text").data(["undefined values"]),E.enter().append("text"),E.exit().remove(),E.attr("y",x).attr("x",w-92-I/2).text(function(a){return a});var L=z.select(".background").selectAll("path").data(b);L.enter().append("path"),L.exit().remove(),L.attr("d",p);var M=z.select(".foreground").selectAll("path").data(b);M.enter().append("path"),M.exit().remove(),M.attr("d",p).attr("stroke",j),M.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),o.elementMouseover({label:a.name,data:a.data,index:b,pos:[d3.mouse(this.parentNode)[0],d3.mouse(this.parentNode)[1]]})}),M.on("mouseout",function(a,b){d3.select(this).classed("hover",!1),o.elementMouseout({label:a.name,data:a.data,index:b})});var N=C.selectAll(".dimension").data(h),O=N.enter().append("g").attr("class","nv-parallelCoordinates dimension");O.append("g").attr("class","nv-parallelCoordinates nv-axis"),O.append("g").attr("class","nv-parallelCoordinates-brush"),O.append("text").attr("class","nv-parallelCoordinates nv-label"),N.attr("transform",function(a){return"translate("+f(a)+",0)"}),N.exit().remove(),N.select(".nv-label").style("cursor","move").attr("dy","-1em").attr("text-anchor","middle").text(String).on("mouseover",function(a){o.elementMouseover({dim:a,pos:[d3.mouse(this.parentNode.parentNode)[0],d3.mouse(this.parentNode.parentNode)[1]]})}).on("mouseout",function(a){o.elementMouseout({dim:a})}).call(H),N.select(".nv-axis").each(function(a,b){d3.select(this).call(G.scale(g[a]).tickFormat(d3.format(i[b])))}),N.select(".nv-parallelCoordinates-brush").each(function(a){d3.select(this).call(g[a].brush)}).selectAll("rect").attr("x",-8).attr("width",16)}),b}var c={top:30,right:0,bottom:10,left:0},d=null,e=null,f=d3.scale.ordinal(),g={},h=[],i=[],j=a.utils.defaultColor(),k=[],l=[],m=[],n=1,o=d3.dispatch("brush","elementMouseover","elementMouseout");return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},dimensionNames:{get:function(){return h},set:function(a){h=a}},dimensionFormats:{get:function(){return i},set:function(a){i=a}},lineTension:{get:function(){return n},set:function(a){n=a}},dimensions:{get:function(){return h},set:function(b){a.deprecated("dimensions","use dimensionNames instead"),h=b}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.pie=function(){"use strict";function b(E){return D.reset(),E.each(function(b){function E(a,b){a.endAngle=isNaN(a.endAngle)?0:a.endAngle,a.startAngle=isNaN(a.startAngle)?0:a.startAngle,p||(a.innerRadius=0);var c=d3.interpolate(this._current,a);return this._current=c(0),function(a){return B[b](c(a))}}var F=d-c.left-c.right,G=e-c.top-c.bottom,H=Math.min(F,G)/2,I=[],J=[];if(i=d3.select(this),0===z.length)for(var K=H-H/5,L=y*H,M=0;M<b[0].length;M++)I.push(K),J.push(L);else I=z.map(function(a){return(a.outer-a.outer/5)*H}),J=z.map(function(a){return(a.inner-a.inner/5)*H}),y=d3.min(z.map(function(a){return a.inner-a.inner/5}));a.utils.initSVG(i);var N=i.selectAll(".nv-wrap.nv-pie").data(b),O=N.enter().append("g").attr("class","nvd3 nv-wrap nv-pie nv-chart-"+h),P=O.append("g"),Q=N.select("g"),R=P.append("g").attr("class","nv-pie");P.append("g").attr("class","nv-pieLabels"),N.attr("transform","translate("+c.left+","+c.top+")"),Q.select(".nv-pie").attr("transform","translate("+F/2+","+G/2+")"),Q.select(".nv-pieLabels").attr("transform","translate("+F/2+","+G/2+")"),i.on("click",function(a,b){A.chartClick({data:a,index:b,pos:d3.event,id:h})}),B=[],C=[];for(var M=0;M<b[0].length;M++){var S=d3.svg.arc().outerRadius(I[M]),T=d3.svg.arc().outerRadius(I[M]+5);u!==!1&&(S.startAngle(u),T.startAngle(u)),w!==!1&&(S.endAngle(w),T.endAngle(w)),p&&(S.innerRadius(J[M]),T.innerRadius(J[M])),S.cornerRadius&&x&&(S.cornerRadius(x),T.cornerRadius(x)),B.push(S),C.push(T)}var U=d3.layout.pie().sort(null).value(function(a){return a.disabled?0:g(a)});U.padAngle&&v&&U.padAngle(v),p&&q&&(R.append("text").attr("class","nv-pie-title"),N.select(".nv-pie-title").style("text-anchor","middle").text(function(){return q}).style("font-size",Math.min(F,G)*y*2/(q.length+2)+"px").attr("dy","0.35em").attr("transform",function(){return"translate(0, "+s+")"}));var V=N.select(".nv-pie").selectAll(".nv-slice").data(U),W=N.select(".nv-pieLabels").selectAll(".nv-label").data(U);V.exit().remove(),W.exit().remove();var X=V.enter().append("g");X.attr("class","nv-slice"),X.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),r&&d3.select(this).select("path").transition().duration(70).attr("d",C[b]),A.elementMouseover({data:a.data,index:b,color:d3.select(this).style("fill")})}),X.on("mouseout",function(a,b){d3.select(this).classed("hover",!1),r&&d3.select(this).select("path").transition().duration(50).attr("d",B[b]),A.elementMouseout({data:a.data,index:b})}),X.on("mousemove",function(a,b){A.elementMousemove({data:a.data,index:b})}),X.on("click",function(a,b){A.elementClick({data:a.data,index:b,color:d3.select(this).style("fill")})}),X.on("dblclick",function(a,b){A.elementDblClick({data:a.data,index:b,color:d3.select(this).style("fill")})}),V.attr("fill",function(a,b){return j(a.data,b)}),V.attr("stroke",function(a,b){return j(a.data,b)});X.append("path").each(function(a){this._current=a});if(V.select("path").transition().attr("d",function(a,b){return B[b](a)}).attrTween("d",E),l){for(var Y=[],M=0;M<b[0].length;M++)Y.push(B[M]),m?p&&(Y[M]=d3.svg.arc().outerRadius(B[M].outerRadius()),u!==!1&&Y[M].startAngle(u),w!==!1&&Y[M].endAngle(w)):p||Y[M].innerRadius(0);W.enter().append("g").classed("nv-label",!0).each(function(a){var b=d3.select(this);b.attr("transform",function(a,b){if(t){a.outerRadius=I[b]+10,a.innerRadius=I[b]+15;var c=(a.startAngle+a.endAngle)/2*(180/Math.PI);return(a.startAngle+a.endAngle)/2<Math.PI?c-=90:c+=90,"translate("+Y[b].centroid(a)+") rotate("+c+")"}return a.outerRadius=H+10,a.innerRadius=H+15,"translate("+Y[b].centroid(a)+")"}),b.append("rect").style("stroke","#fff").style("fill","#fff").attr("rx",3).attr("ry",3),b.append("text").style("text-anchor",t?(a.startAngle+a.endAngle)/2<Math.PI?"start":"end":"middle").style("fill","#000")});var Z={},$=14,_=140,ab=function(a){return Math.floor(a[0]/_)*_+","+Math.floor(a[1]/$)*$};W.watchTransition(D,"pie labels").attr("transform",function(a,b){if(t){a.outerRadius=I[b]+10,a.innerRadius=I[b]+15;var c=(a.startAngle+a.endAngle)/2*(180/Math.PI);return(a.startAngle+a.endAngle)/2<Math.PI?c-=90:c+=90,"translate("+Y[b].centroid(a)+") rotate("+c+")"}a.outerRadius=H+10,a.innerRadius=H+15;var d=Y[b].centroid(a);if(a.value){var e=ab(d);Z[e]&&(d[1]-=$),Z[ab(d)]=!0}return"translate("+d+")"}),W.select(".nv-label text").style("text-anchor",function(a){return t?(a.startAngle+a.endAngle)/2<Math.PI?"start":"end":"middle"}).text(function(a,b){var c=(a.endAngle-a.startAngle)/(2*Math.PI),d="";if(!a.value||o>c)return"";if("function"==typeof n)d=n(a,b,{key:f(a.data),value:g(a.data),percent:k(c)});else switch(n){case"key":d=f(a.data);break;case"value":d=k(g(a.data));break;case"percent":d=d3.format("%")(c)}return d})}}),D.renderEnd("pie immediate"),b}var c={top:0,right:0,bottom:0,left:0},d=500,e=500,f=function(a){return a.x},g=function(a){return a.y},h=Math.floor(1e4*Math.random()),i=null,j=a.utils.defaultColor(),k=d3.format(",.2f"),l=!0,m=!1,n="key",o=.02,p=!1,q=!1,r=!0,s=0,t=!1,u=!1,v=!1,w=!1,x=0,y=.5,z=[],A=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),B=[],C=[],D=a.utils.renderWatch(A);return b.dispatch=A,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{arcsRadius:{get:function(){return z},set:function(a){z=a}},width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},showLabels:{get:function(){return l},set:function(a){l=a}},title:{get:function(){return q},set:function(a){q=a}},titleOffset:{get:function(){return s},set:function(a){s=a}},labelThreshold:{get:function(){return o},set:function(a){o=a}},valueFormat:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return h},set:function(a){h=a}},endAngle:{get:function(){return w},set:function(a){w=a}},startAngle:{get:function(){return u},set:function(a){u=a}},padAngle:{get:function(){return v},set:function(a){v=a}},cornerRadius:{get:function(){return x},set:function(a){x=a}},donutRatio:{get:function(){return y},set:function(a){y=a}},labelsOutside:{get:function(){return m},set:function(a){m=a}},labelSunbeamLayout:{get:function(){return t},set:function(a){t=a}},donut:{get:function(){return p},set:function(a){p=a}},growOnHover:{get:function(){return r},set:function(a){r=a}},pieLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("pieLabelsOutside","use labelsOutside instead")}},donutLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("donutLabelsOutside","use labelsOutside instead")}},labelFormat:{get:function(){return k},set:function(b){k=b,a.deprecated("labelFormat","use valueFormat instead")}},margin:{get:function(){return c},set:function(a){c.top="undefined"!=typeof a.top?a.top:c.top,c.right="undefined"!=typeof a.right?a.right:c.right,c.bottom="undefined"!=typeof a.bottom?a.bottom:c.bottom,c.left="undefined"!=typeof a.left?a.left:c.left}},y:{get:function(){return g},set:function(a){g=d3.functor(a)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},labelType:{get:function(){return n},set:function(a){n=a||"key"}}}),a.utils.initOptions(b),b},a.models.pieChart=function(){"use strict";function b(e){return q.reset(),q.models(c),e.each(function(e){var k=d3.select(this);a.utils.initSVG(k);var n=a.utils.availableWidth(g,k,f),o=a.utils.availableHeight(h,k,f);if(b.update=function(){k.transition().call(b)},b.container=this,l.setter(s(e),b.update).getter(r(e)).update(),l.disabled=e.map(function(a){return!!a.disabled}),!m){var q;m={};for(q in l)m[q]=l[q]instanceof Array?l[q].slice(0):l[q]}if(!e||!e.length)return a.utils.noData(b,k),b;k.selectAll(".nv-noData").remove();var t=k.selectAll("g.nv-wrap.nv-pieChart").data([e]),u=t.enter().append("g").attr("class","nvd3 nv-wrap nv-pieChart").append("g"),v=t.select("g");if(u.append("g").attr("class","nv-pieWrap"),u.append("g").attr("class","nv-legendWrap"),i)if("top"===j)d.width(n).key(c.x()),t.select(".nv-legendWrap").datum(e).call(d),f.top!=d.height()&&(f.top=d.height(),o=a.utils.availableHeight(h,k,f)),t.select(".nv-legendWrap").attr("transform","translate(0,"+-f.top+")");else if("right"===j){var w=a.models.legend().width();w>n/2&&(w=n/2),d.height(o).key(c.x()),d.width(w),n-=d.width(),t.select(".nv-legendWrap").datum(e).call(d).attr("transform","translate("+n+",0)")}t.attr("transform","translate("+f.left+","+f.top+")"),c.width(n).height(o);var x=v.select(".nv-pieWrap").datum([e]);d3.transition(x).call(c),d.dispatch.on("stateChange",function(a){for(var c in a)l[c]=a[c];p.stateChange(l),b.update()}),p.on("changeState",function(a){"undefined"!=typeof a.disabled&&(e.forEach(function(b,c){b.disabled=a.disabled[c]}),l.disabled=a.disabled),b.update()})}),q.renderEnd("pieChart immediate"),b}var c=a.models.pie(),d=a.models.legend(),e=a.models.tooltip(),f={top:30,right:20,bottom:20,left:20},g=null,h=null,i=!0,j="top",k=a.utils.defaultColor(),l=a.utils.state(),m=null,n=null,o=250,p=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd");e.headerEnabled(!1).duration(0).valueFormatter(function(a,b){return c.valueFormat()(a,b)});var q=a.utils.renderWatch(p),r=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},s=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},e.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){e.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){e.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.legend=d,b.dispatch=p,b.pie=c,b.tooltip=e,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return i},set:function(a){i=a}},legendPosition:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return e.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),e.enabled(!!b)}},tooltipContent:{get:function(){return e.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),e.contentGenerator(b)}},color:{get:function(){return k},set:function(a){k=a,d.color(k),c.color(k)}},duration:{get:function(){return o},set:function(a){o=a,q.reset(o)}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.scatter=function(){"use strict";function b(N){return P.reset(),N.each(function(b){function N(){if(O=!1,!w)return!1;if(M===!0){var a=d3.merge(b.map(function(a,b){return a.values.map(function(a,c){var d=p(a,c),e=q(a,c);return[m(d)+1e-4*Math.random(),n(e)+1e-4*Math.random(),b,c,a]}).filter(function(a,b){return x(a[4],b)})}));if(0==a.length)return!1;a.length<3&&(a.push([m.range()[0]-20,n.range()[0]-20,null,null]),a.push([m.range()[1]+20,n.range()[1]+20,null,null]),a.push([m.range()[0]-20,n.range()[0]+20,null,null]),a.push([m.range()[1]+20,n.range()[1]-20,null,null]));var c=d3.geom.polygon([[-10,-10],[-10,i+10],[h+10,i+10],[h+10,-10]]),d=d3.geom.voronoi(a).map(function(b,d){return{data:c.clip(b),series:a[d][2],point:a[d][3]}});U.select(".nv-point-paths").selectAll("path").remove();var e=U.select(".nv-point-paths").selectAll("path").data(d),f=e.enter().append("svg:path").attr("d",function(a){return a&&a.data&&0!==a.data.length?"M"+a.data.join(",")+"Z":"M 0 0"}).attr("id",function(a,b){return"nv-path-"+b}).attr("clip-path",function(a,b){return"url(#nv-clip-"+b+")"});C&&f.style("fill",d3.rgb(230,230,230)).style("fill-opacity",.4).style("stroke-opacity",1).style("stroke",d3.rgb(200,200,200)),B&&(U.select(".nv-point-clips").selectAll("clipPath").remove(),U.select(".nv-point-clips").selectAll("clipPath").data(a).enter().append("svg:clipPath").attr("id",function(a,b){return"nv-clip-"+b}).append("svg:circle").attr("cx",function(a){return a[0]}).attr("cy",function(a){return a[1]}).attr("r",D));var k=function(a,c){if(O)return 0;var d=b[a.series];if(void 0!==d){var e=d.values[a.point];e.color=j(d,a.series),e.x=p(e),e.y=q(e);var f=l.node().getBoundingClientRect(),h=window.pageYOffset||document.documentElement.scrollTop,i=window.pageXOffset||document.documentElement.scrollLeft,k={left:m(p(e,a.point))+f.left+i+g.left+10,top:n(q(e,a.point))+f.top+h+g.top+10};c({point:e,series:d,pos:k,seriesIndex:a.series,pointIndex:a.point})}};e.on("click",function(a){k(a,L.elementClick)}).on("dblclick",function(a){k(a,L.elementDblClick)}).on("mouseover",function(a){k(a,L.elementMouseover)}).on("mouseout",function(a){k(a,L.elementMouseout)})}else U.select(".nv-groups").selectAll(".nv-group").selectAll(".nv-point").on("click",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("dblclick",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementDblClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("mouseover",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseover({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c,color:j(a,c)})}).on("mouseout",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseout({point:e,series:d,seriesIndex:a.series,pointIndex:c,color:j(a,c)})})}l=d3.select(this);var R=a.utils.availableWidth(h,l,g),S=a.utils.availableHeight(i,l,g);a.utils.initSVG(l),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var T=E&&F&&I?[]:d3.merge(b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),size:r(a,b)}})}));m.domain(E||d3.extent(T.map(function(a){return a.x}).concat(t))),m.range(y&&b[0]?G||[(R*z+R)/(2*b[0].values.length),R-R*(1+z)/(2*b[0].values.length)]:G||[0,R]),n.domain(F||d3.extent(T.map(function(a){return a.y}).concat(u))).range(H||[S,0]),o.domain(I||d3.extent(T.map(function(a){return a.size}).concat(v))).range(J||Q),K=m.domain()[0]===m.domain()[1]||n.domain()[0]===n.domain()[1],m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]-.01*n.domain()[0],n.domain()[1]+.01*n.domain()[1]]:[-1,1]),isNaN(m.domain()[0])&&m.domain([-1,1]),isNaN(n.domain()[0])&&n.domain([-1,1]),c=c||m,d=d||n,e=e||o;var U=l.selectAll("g.nv-wrap.nv-scatter").data([b]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-scatter nv-chart-"+k),W=V.append("defs"),X=V.append("g"),Y=U.select("g");U.classed("nv-single-point",K),X.append("g").attr("class","nv-groups"),X.append("g").attr("class","nv-point-paths"),V.append("g").attr("class","nv-point-clips"),U.attr("transform","translate("+g.left+","+g.top+")"),W.append("clipPath").attr("id","nv-edge-clip-"+k).append("rect"),U.select("#nv-edge-clip-"+k+" rect").attr("width",R).attr("height",S>0?S:0),Y.attr("clip-path",A?"url(#nv-edge-clip-"+k+")":""),O=!0;var Z=U.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});Z.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),Z.exit().remove(),Z.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),Z.watchTransition(P,"scatter: groups").style("fill",function(a,b){return j(a,b)}).style("stroke",function(a,b){return j(a,b)}).style("stroke-opacity",1).style("fill-opacity",.5);var $=Z.selectAll("path.nv-point").data(function(a){return a.values.map(function(a,b){return[a,b]}).filter(function(a,b){return x(a[0],b)})});$.enter().append("path").style("fill",function(a){return a.color}).style("stroke",function(a){return a.color}).attr("transform",function(a){return"translate("+c(p(a[0],a[1]))+","+d(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),$.exit().remove(),Z.exit().selectAll("path.nv-point").watchTransition(P,"scatter exit").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).remove(),$.each(function(a){d3.select(this).classed("nv-point",!0).classed("nv-point-"+a[1],!0).classed("nv-noninteractive",!w).classed("hover",!1)}),$.watchTransition(P,"scatter points").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),clearTimeout(f),f=setTimeout(N,300),c=m.copy(),d=n.copy(),e=o.copy()}),P.renderEnd("scatter immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=a.utils.defaultColor(),k=Math.floor(1e5*Math.random()),l=null,m=d3.scale.linear(),n=d3.scale.linear(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=function(a){return a.size||1},s=function(a){return a.shape||"circle"},t=[],u=[],v=[],w=!0,x=function(a){return!a.notActive},y=!1,z=.1,A=!1,B=!0,C=!1,D=function(){return 25},E=null,F=null,G=null,H=null,I=null,J=null,K=!1,L=d3.dispatch("elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd"),M=!0,N=250,O=!1,P=a.utils.renderWatch(L,N),Q=[16,256];return b.dispatch=L,b.options=a.utils.optionsFunc.bind(b),b._calls=new function(){this.clearHighlights=function(){return a.dom.write(function(){l.selectAll(".nv-point.hover").classed("hover",!1)}),null},this.highlightPoint=function(b,c,d){a.dom.write(function(){l.select(" .nv-series-"+b+" .nv-point-"+c).classed("hover",d)})}},L.on("elementMouseover.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!0)}),L.on("elementMouseout.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!1)}),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},pointScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return E},set:function(a){E=a}},yDomain:{get:function(){return F},set:function(a){F=a}},pointDomain:{get:function(){return I},set:function(a){I=a}},xRange:{get:function(){return G},set:function(a){G=a}},yRange:{get:function(){return H},set:function(a){H=a}},pointRange:{get:function(){return J},set:function(a){J=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},forcePoint:{get:function(){return v},set:function(a){v=a}},interactive:{get:function(){return w},set:function(a){w=a}},pointActive:{get:function(){return x},set:function(a){x=a}},padDataOuter:{get:function(){return z},set:function(a){z=a}},padData:{get:function(){return y},set:function(a){y=a}},clipEdge:{get:function(){return A},set:function(a){A=a}},clipVoronoi:{get:function(){return B},set:function(a){B=a}},clipRadius:{get:function(){return D},set:function(a){D=a}},showVoronoi:{get:function(){return C},set:function(a){C=a}},id:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return p},set:function(a){p=d3.functor(a)}},y:{get:function(){return q},set:function(a){q=d3.functor(a)}},pointSize:{get:function(){return r},set:function(a){r=d3.functor(a)}},pointShape:{get:function(){return s},set:function(a){s=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},duration:{get:function(){return N},set:function(a){N=a,P.reset(N)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},useVoronoi:{get:function(){return M},set:function(a){M=a,M===!1&&(B=!1)}}}),a.utils.initOptions(b),b},a.models.scatterChart=function(){"use strict";function b(z){return D.reset(),D.models(c),t&&D.models(d),u&&D.models(e),q&&D.models(g),r&&D.models(h),z.each(function(z){m=d3.select(this),a.utils.initSVG(m);var G=a.utils.availableWidth(k,m,j),H=a.utils.availableHeight(l,m,j);if(b.update=function(){0===A?m.call(b):m.transition().duration(A).call(b)},b.container=this,w.setter(F(z),b.update).getter(E(z)).update(),w.disabled=z.map(function(a){return!!a.disabled}),!x){var I;x={};for(I in w)x[I]=w[I]instanceof Array?w[I].slice(0):w[I]}if(!(z&&z.length&&z.filter(function(a){return a.values.length}).length))return a.utils.noData(b,m),D.renderEnd("scatter immediate"),b;m.selectAll(".nv-noData").remove(),o=c.xScale(),p=c.yScale();var J=m.selectAll("g.nv-wrap.nv-scatterChart").data([z]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-scatterChart nv-chart-"+c.id()),L=K.append("g"),M=J.select("g");if(L.append("rect").attr("class","nvd3 nv-background").style("pointer-events","none"),L.append("g").attr("class","nv-x nv-axis"),L.append("g").attr("class","nv-y nv-axis"),L.append("g").attr("class","nv-scatterWrap"),L.append("g").attr("class","nv-regressionLinesWrap"),L.append("g").attr("class","nv-distWrap"),L.append("g").attr("class","nv-legendWrap"),v&&M.select(".nv-y.nv-axis").attr("transform","translate("+G+",0)"),s){var N=G;f.width(N),J.select(".nv-legendWrap").datum(z).call(f),j.top!=f.height()&&(j.top=f.height(),H=a.utils.availableHeight(l,m,j)),J.select(".nv-legendWrap").attr("transform","translate(0,"+-j.top+")")}J.attr("transform","translate("+j.left+","+j.top+")"),c.width(G).height(H).color(z.map(function(a,b){return a.color=a.color||n(a,b),a.color}).filter(function(a,b){return!z[b].disabled})),J.select(".nv-scatterWrap").datum(z.filter(function(a){return!a.disabled})).call(c),J.select(".nv-regressionLinesWrap").attr("clip-path","url(#nv-edge-clip-"+c.id()+")");var O=J.select(".nv-regressionLinesWrap").selectAll(".nv-regLines").data(function(a){return a});O.enter().append("g").attr("class","nv-regLines");var P=O.selectAll(".nv-regLine").data(function(a){return[a]});P.enter().append("line").attr("class","nv-regLine").style("stroke-opacity",0),P.filter(function(a){return a.intercept&&a.slope}).watchTransition(D,"scatterPlusLineChart: regline").attr("x1",o.range()[0]).attr("x2",o.range()[1]).attr("y1",function(a){return p(o.domain()[0]*a.slope+a.intercept)}).attr("y2",function(a){return p(o.domain()[1]*a.slope+a.intercept)}).style("stroke",function(a,b,c){return n(a,c)}).style("stroke-opacity",function(a){return a.disabled||"undefined"==typeof a.slope||"undefined"==typeof a.intercept?0:1}),t&&(d.scale(o)._ticks(a.utils.calcTicksX(G/100,z)).tickSize(-H,0),M.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range()[0]+")").call(d)),u&&(e.scale(p)._ticks(a.utils.calcTicksY(H/36,z)).tickSize(-G,0),M.select(".nv-y.nv-axis").call(e)),q&&(g.getData(c.x()).scale(o).width(G).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),M.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(z.filter(function(a){return!a.disabled})).call(g)),r&&(h.getData(c.y()).scale(p).width(H).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),M.select(".nv-distributionY").attr("transform","translate("+(v?G:-h.size())+",0)").datum(z.filter(function(a){return!a.disabled})).call(h)),f.dispatch.on("stateChange",function(a){for(var c in a)w[c]=a[c];y.stateChange(w),b.update()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&(z.forEach(function(b,c){b.disabled=a.disabled[c]}),w.disabled=a.disabled),b.update()}),c.dispatch.on("elementMouseout.tooltip",function(a){i.hidden(!0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",h.size())}),c.dispatch.on("elementMouseover.tooltip",function(a){m.select(".nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",a.pos.top-H-j.top),m.select(".nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",a.pos.left+g.size()-j.left),i.position(a.pos).data(a).hidden(!1)}),B=o.copy(),C=p.copy()}),D.renderEnd("scatter with line immediate"),b}var c=a.models.scatter(),d=a.models.axis(),e=a.models.axis(),f=a.models.legend(),g=a.models.distribution(),h=a.models.distribution(),i=a.models.tooltip(),j={top:30,right:20,bottom:50,left:75},k=null,l=null,m=null,n=a.utils.defaultColor(),o=c.xScale(),p=c.yScale(),q=!1,r=!1,s=!0,t=!0,u=!0,v=!1,w=a.utils.state(),x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=null,A=250;c.xScale(o).yScale(p),d.orient("bottom").tickPadding(10),e.orient(v?"right":"left").tickPadding(10),g.axis("x"),h.axis("y"),i.headerFormatter(function(a,b){return d.tickFormat()(a,b)}).valueFormatter(function(a,b){return e.tickFormat()(a,b)});var B,C,D=a.utils.renderWatch(y,A),E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return b.dispatch=y,b.scatter=c,b.legend=f,b.xAxis=d,b.yAxis=e,b.distX=g,b.distY=h,b.tooltip=i,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},container:{get:function(){return m},set:function(a){m=a}},showDistX:{get:function(){return q},set:function(a){q=a}},showDistY:{get:function(){return r},set:function(a){r=a}},showLegend:{get:function(){return s},set:function(a){s=a}},showXAxis:{get:function(){return t},set:function(a){t=a}},showYAxis:{get:function(){return u},set:function(a){u=a}},defaultState:{get:function(){return x},set:function(a){x=a}},noData:{get:function(){return z},set:function(a){z=a}},duration:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return i.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),i.enabled(!!b)
+}},tooltipContent:{get:function(){return i.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),i.contentGenerator(b)}},tooltipXContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},tooltipYContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},rightAlignYAxis:{get:function(){return v},set:function(a){v=a,e.orient(a?"right":"left")}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),f.color(n),g.color(n),h.color(n)}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.sparkline=function(){"use strict";function b(k){return k.each(function(b){var k=h-g.left-g.right,q=i-g.top-g.bottom;j=d3.select(this),a.utils.initSVG(j),l.domain(c||d3.extent(b,n)).range(e||[0,k]),m.domain(d||d3.extent(b,o)).range(f||[q,0]);{var r=j.selectAll("g.nv-wrap.nv-sparkline").data([b]),s=r.enter().append("g").attr("class","nvd3 nv-wrap nv-sparkline");s.append("g"),r.select("g")}r.attr("transform","translate("+g.left+","+g.top+")");var t=r.selectAll("path").data(function(a){return[a]});t.enter().append("path"),t.exit().remove(),t.style("stroke",function(a,b){return a.color||p(a,b)}).attr("d",d3.svg.line().x(function(a,b){return l(n(a,b))}).y(function(a,b){return m(o(a,b))}));var u=r.selectAll("circle.nv-point").data(function(a){function b(b){if(-1!=b){var c=a[b];return c.pointIndex=b,c}return null}var c=a.map(function(a,b){return o(a,b)}),d=b(c.lastIndexOf(m.domain()[1])),e=b(c.indexOf(m.domain()[0])),f=b(c.length-1);return[e,d,f].filter(function(a){return null!=a})});u.enter().append("circle"),u.exit().remove(),u.attr("cx",function(a){return l(n(a,a.pointIndex))}).attr("cy",function(a){return m(o(a,a.pointIndex))}).attr("r",2).attr("class",function(a){return n(a,a.pointIndex)==l.domain()[1]?"nv-point nv-currentValue":o(a,a.pointIndex)==m.domain()[0]?"nv-point nv-minValue":"nv-point nv-maxValue"})}),b}var c,d,e,f,g={top:2,right:0,bottom:2,left:0},h=400,i=32,j=null,k=!0,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=a.utils.getColor(["#000"]);return b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},animate:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return n},set:function(a){n=d3.functor(a)}},y:{get:function(){return o},set:function(a){o=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return p},set:function(b){p=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sparklinePlus=function(){"use strict";function b(p){return p.each(function(p){function q(){if(!j){var a=z.selectAll(".nv-hoverValue").data(i),b=a.enter().append("g").attr("class","nv-hoverValue").style("stroke-opacity",0).style("fill-opacity",0);a.exit().transition().duration(250).style("stroke-opacity",0).style("fill-opacity",0).remove(),a.attr("transform",function(a){return"translate("+c(e.x()(p[a],a))+",0)"}).transition().duration(250).style("stroke-opacity",1).style("fill-opacity",1),i.length&&(b.append("line").attr("x1",0).attr("y1",-f.top).attr("x2",0).attr("y2",u),b.append("text").attr("class","nv-xValue").attr("x",-6).attr("y",-f.top).attr("text-anchor","end").attr("dy",".9em"),z.select(".nv-hoverValue .nv-xValue").text(k(e.x()(p[i[0]],i[0]))),b.append("text").attr("class","nv-yValue").attr("x",6).attr("y",-f.top).attr("text-anchor","start").attr("dy",".9em"),z.select(".nv-hoverValue .nv-yValue").text(l(e.y()(p[i[0]],i[0]))))}}function r(){function a(a,b){for(var c=Math.abs(e.x()(a[0],0)-b),d=0,f=0;f<a.length;f++)Math.abs(e.x()(a[f],f)-b)<c&&(c=Math.abs(e.x()(a[f],f)-b),d=f);return d}if(!j){var b=d3.mouse(this)[0]-f.left;i=[a(p,Math.round(c.invert(b)))],q()}}var s=d3.select(this);a.utils.initSVG(s);var t=a.utils.availableWidth(g,s,f),u=a.utils.availableHeight(h,s,f);if(b.update=function(){s.call(b)},b.container=this,!p||!p.length)return a.utils.noData(b,s),b;s.selectAll(".nv-noData").remove();var v=e.y()(p[p.length-1],p.length-1);c=e.xScale(),d=e.yScale();var w=s.selectAll("g.nv-wrap.nv-sparklineplus").data([p]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-sparklineplus"),y=x.append("g"),z=w.select("g");y.append("g").attr("class","nv-sparklineWrap"),y.append("g").attr("class","nv-valueWrap"),y.append("g").attr("class","nv-hoverArea"),w.attr("transform","translate("+f.left+","+f.top+")");var A=z.select(".nv-sparklineWrap");if(e.width(t).height(u),A.call(e),m){var B=z.select(".nv-valueWrap"),C=B.selectAll(".nv-currentValue").data([v]);C.enter().append("text").attr("class","nv-currentValue").attr("dx",o?-8:8).attr("dy",".9em").style("text-anchor",o?"end":"start"),C.attr("x",t+(o?f.right:0)).attr("y",n?function(a){return d(a)}:0).style("fill",e.color()(p[p.length-1],p.length-1)).text(l(v))}y.select(".nv-hoverArea").append("rect").on("mousemove",r).on("click",function(){j=!j}).on("mouseout",function(){i=[],q()}),z.select(".nv-hoverArea rect").attr("transform",function(){return"translate("+-f.left+","+-f.top+")"}).attr("width",t+f.left+f.right).attr("height",u+f.top)}),b}var c,d,e=a.models.sparkline(),f={top:15,right:100,bottom:10,left:50},g=null,h=null,i=[],j=!1,k=d3.format(",r"),l=d3.format(",.2f"),m=!0,n=!0,o=!1,p=null;return b.sparkline=e,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},xTickFormat:{get:function(){return k},set:function(a){k=a}},yTickFormat:{get:function(){return l},set:function(a){l=a}},showLastValue:{get:function(){return m},set:function(a){m=a}},alignValue:{get:function(){return n},set:function(a){n=a}},rightAlignValue:{get:function(){return o},set:function(a){o=a}},noData:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.stackedArea=function(){"use strict";function b(m){return u.reset(),u.models(r),m.each(function(m){var s=f-e.left-e.right,v=g-e.top-e.bottom;j=d3.select(this),a.utils.initSVG(j),c=r.xScale(),d=r.yScale();var w=m;m.forEach(function(a,b){a.seriesIndex=b,a.values=a.values.map(function(a,c){return a.index=c,a.seriesIndex=b,a})});var x=m.filter(function(a){return!a.disabled});m=d3.layout.stack().order(o).offset(n).values(function(a){return a.values}).x(k).y(l).out(function(a,b,c){a.display={y:c,y0:b}})(x);var y=j.selectAll("g.nv-wrap.nv-stackedarea").data([m]),z=y.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedarea"),A=z.append("defs"),B=z.append("g"),C=y.select("g");B.append("g").attr("class","nv-areaWrap"),B.append("g").attr("class","nv-scatterWrap"),y.attr("transform","translate("+e.left+","+e.top+")"),0==r.forceY().length&&r.forceY().push(0),r.width(s).height(v).x(k).y(function(a){return a.display.y+a.display.y0}).forceY([0]).color(m.map(function(a){return a.color||h(a,a.seriesIndex)}));var D=C.select(".nv-scatterWrap").datum(m);D.call(r),A.append("clipPath").attr("id","nv-edge-clip-"+i).append("rect"),y.select("#nv-edge-clip-"+i+" rect").attr("width",s).attr("height",v),C.attr("clip-path",q?"url(#nv-edge-clip-"+i+")":"");var E=d3.svg.area().x(function(a,b){return c(k(a,b))}).y0(function(a){return d(a.display.y0)}).y1(function(a){return d(a.display.y+a.display.y0)}).interpolate(p),F=d3.svg.area().x(function(a,b){return c(k(a,b))}).y0(function(a){return d(a.display.y0)}).y1(function(a){return d(a.display.y0)}),G=C.select(".nv-areaWrap").selectAll("path.nv-area").data(function(a){return a});G.enter().append("path").attr("class",function(a,b){return"nv-area nv-area-"+b}).attr("d",function(a){return F(a.values,a.seriesIndex)}).on("mouseover",function(a){d3.select(this).classed("hover",!0),t.areaMouseover({point:a,series:a.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:a.seriesIndex})}).on("mouseout",function(a){d3.select(this).classed("hover",!1),t.areaMouseout({point:a,series:a.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:a.seriesIndex})}).on("click",function(a){d3.select(this).classed("hover",!1),t.areaClick({point:a,series:a.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:a.seriesIndex})}),G.exit().remove(),G.style("fill",function(a){return a.color||h(a,a.seriesIndex)}).style("stroke",function(a){return a.color||h(a,a.seriesIndex)}),G.watchTransition(u,"stackedArea path").attr("d",function(a,b){return E(a.values,b)}),r.dispatch.on("elementMouseover.area",function(a){C.select(".nv-chart-"+i+" .nv-area-"+a.seriesIndex).classed("hover",!0)}),r.dispatch.on("elementMouseout.area",function(a){C.select(".nv-chart-"+i+" .nv-area-"+a.seriesIndex).classed("hover",!1)}),b.d3_stackedOffset_stackPercent=function(a){var b,c,d,e=a.length,f=a[0].length,g=[];for(c=0;f>c;++c){for(b=0,d=0;b<w.length;b++)d+=l(w[b].values[c]);if(d)for(b=0;e>b;b++)a[b][c][1]/=d;else for(b=0;e>b;b++)a[b][c][1]=0}for(c=0;f>c;++c)g[c]=0;return g}}),u.renderEnd("stackedArea immediate"),b}var c,d,e={top:0,right:0,bottom:0,left:0},f=960,g=500,h=a.utils.defaultColor(),i=Math.floor(1e5*Math.random()),j=null,k=function(a){return a.x},l=function(a){return a.y},m="stack",n="zero",o="default",p="linear",q=!1,r=a.models.scatter(),s=250,t=d3.dispatch("areaClick","areaMouseover","areaMouseout","renderEnd","elementClick","elementMouseover","elementMouseout");r.pointSize(2.2).pointDomain([2.2,2.2]);var u=a.utils.renderWatch(t,s);return b.dispatch=t,b.scatter=r,r.dispatch.on("elementClick",function(){t.elementClick.apply(this,arguments)}),r.dispatch.on("elementMouseover",function(){t.elementMouseover.apply(this,arguments)}),r.dispatch.on("elementMouseout",function(){t.elementMouseout.apply(this,arguments)}),b.interpolate=function(a){return arguments.length?(p=a,b):p},b.duration=function(a){return arguments.length?(s=a,u.reset(s),r.duration(s),b):s},b.dispatch=t,b.scatter=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return f},set:function(a){f=a}},height:{get:function(){return g},set:function(a){g=a}},clipEdge:{get:function(){return q},set:function(a){q=a}},offset:{get:function(){return n},set:function(a){n=a}},order:{get:function(){return o},set:function(a){o=a}},interpolate:{get:function(){return p},set:function(a){p=a}},x:{get:function(){return k},set:function(a){k=d3.functor(a)}},y:{get:function(){return l},set:function(a){l=d3.functor(a)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return h},set:function(b){h=a.utils.getColor(b)}},style:{get:function(){return m},set:function(a){switch(m=a){case"stack":b.offset("zero"),b.order("default");break;case"stream":b.offset("wiggle"),b.order("inside-out");break;case"stream-center":b.offset("silhouette"),b.order("inside-out");break;case"expand":b.offset("expand"),b.order("default");break;case"stack_percent":b.offset(b.d3_stackedOffset_stackPercent),b.order("default")}}},duration:{get:function(){return s},set:function(a){s=a,u.reset(s),r.duration(s)}}}),a.utils.inheritOptions(b,r),a.utils.initOptions(b),b},a.models.stackedAreaChart=function(){"use strict";function b(k){return F.reset(),F.models(e),r&&F.models(f),s&&F.models(g),k.each(function(k){var x=d3.select(this),F=this;a.utils.initSVG(x);var K=a.utils.availableWidth(m,x,l),L=a.utils.availableHeight(n,x,l);if(b.update=function(){x.transition().duration(C).call(b)},b.container=this,v.setter(I(k),b.update).getter(H(k)).update(),v.disabled=k.map(function(a){return!!a.disabled}),!w){var M;w={};for(M in v)w[M]=v[M]instanceof Array?v[M].slice(0):v[M]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(b,x),b;x.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var N=x.selectAll("g.nv-wrap.nv-stackedAreaChart").data([k]),O=N.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedAreaChart").append("g"),P=N.select("g");if(O.append("rect").style("opacity",0),O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y nv-axis"),O.append("g").attr("class","nv-stackedWrap"),O.append("g").attr("class","nv-legendWrap"),O.append("g").attr("class","nv-controlsWrap"),O.append("g").attr("class","nv-interactive"),P.select("rect").attr("width",K).attr("height",L),q){var Q=p?K-z:K;h.width(Q),P.select(".nv-legendWrap").datum(k).call(h),l.top!=h.height()&&(l.top=h.height(),L=a.utils.availableHeight(n,x,l)),P.select(".nv-legendWrap").attr("transform","translate("+(K-Q)+","+-l.top+")")}if(p){var R=[{key:B.stacked||"Stacked",metaKey:"Stacked",disabled:"stack"!=e.style(),style:"stack"},{key:B.stream||"Stream",metaKey:"Stream",disabled:"stream"!=e.style(),style:"stream"},{key:B.expanded||"Expanded",metaKey:"Expanded",disabled:"expand"!=e.style(),style:"expand"},{key:B.stack_percent||"Stack %",metaKey:"Stack_Percent",disabled:"stack_percent"!=e.style(),style:"stack_percent"}];z=A.length/3*260,R=R.filter(function(a){return-1!==A.indexOf(a.metaKey)}),i.width(z).color(["#444","#444","#444"]),P.select(".nv-controlsWrap").datum(R).call(i),l.top!=Math.max(i.height(),h.height())&&(l.top=Math.max(i.height(),h.height()),L=a.utils.availableHeight(n,x,l)),P.select(".nv-controlsWrap").attr("transform","translate(0,"+-l.top+")")}N.attr("transform","translate("+l.left+","+l.top+")"),t&&P.select(".nv-y.nv-axis").attr("transform","translate("+K+",0)"),u&&(j.width(K).height(L).margin({left:l.left,top:l.top}).svgContainer(x).xScale(c),N.select(".nv-interactive").call(j)),e.width(K).height(L);var S=P.select(".nv-stackedWrap").datum(k);if(S.transition().call(e),r&&(f.scale(c)._ticks(a.utils.calcTicksX(K/100,k)).tickSize(-L,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+L+")"),P.select(".nv-x.nv-axis").transition().duration(0).call(f)),s){var T;if(T="wiggle"===e.offset()?0:a.utils.calcTicksY(L/36,k),g.scale(d)._ticks(T).tickSize(-K,0),"expand"===e.style()||"stack_percent"===e.style()){var U=g.tickFormat();D&&U===J||(D=U),g.tickFormat(J)}else D&&(g.tickFormat(D),D=null);P.select(".nv-y.nv-axis").transition().duration(0).call(g)}e.dispatch.on("areaClick.toggle",function(a){k.forEach(1===k.filter(function(a){return!a.disabled}).length?function(a){a.disabled=!1}:function(b,c){b.disabled=c!=a.seriesIndex}),v.disabled=k.map(function(a){return!!a.disabled}),y.stateChange(v),b.update()}),h.dispatch.on("stateChange",function(a){for(var c in a)v[c]=a[c];y.stateChange(v),b.update()}),i.dispatch.on("legendClick",function(a){a.disabled&&(R=R.map(function(a){return a.disabled=!0,a}),a.disabled=!1,e.style(a.style),v.style=e.style(),y.stateChange(v),b.update())}),j.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,g,h,i=[];if(k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,j){g=a.interactiveBisect(f.values,c.pointXValue,b.x());var k=f.values[g],l=b.y()(k,g);if(null!=l&&e.highlightPoint(j,g,!0),"undefined"!=typeof k){"undefined"==typeof d&&(d=k),"undefined"==typeof h&&(h=b.xScale()(b.x()(k,g)));var m="expand"==e.style()?k.display.y:b.y()(k,g);i.push({key:f.key,value:m,color:o(f,f.seriesIndex),stackedValue:k.display})}}),i.reverse(),i.length>2){var m=b.yScale().invert(c.mouseY),n=null;i.forEach(function(a,b){m=Math.abs(m);var c=Math.abs(a.stackedValue.y0),d=Math.abs(a.stackedValue.y);return m>=c&&d+c>=m?void(n=b):void 0}),null!=n&&(i[n].highlight=!0)}var p=f.tickFormat()(b.x()(d,g)),q=j.tooltip.valueFormatter();"expand"===e.style()||"stack_percent"===e.style()?(E||(E=q),q=d3.format(".1%")):E&&(q=E,E=null),j.tooltip.position({left:h+l.left,top:c.mouseY+l.top}).chartContainer(F.parentNode).valueFormatter(q).data({value:p,series:i})(),j.renderGuideLine(h)}),j.dispatch.on("elementMouseout",function(){e.clearHighlights()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&k.length===a.disabled.length&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),v.disabled=a.disabled),"undefined"!=typeof a.style&&(e.style(a.style),G=a.style),b.update()})}),F.renderEnd("stacked Area chart immediate"),b}var c,d,e=a.models.stackedArea(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:25,bottom:50,left:60},m=null,n=null,o=a.utils.defaultColor(),p=!0,q=!0,r=!0,s=!0,t=!1,u=!1,v=a.utils.state(),w=null,x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=250,A=["Stacked","Stream","Expanded"],B={},C=250;v.style=e.style(),f.orient("bottom").tickPadding(7),g.orient(t?"right":"left"),k.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)}),j.tooltip.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)});var D=null,E=null;i.updateState(!1);var F=a.utils.renderWatch(y),G=e.style(),H=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),style:e.style()}}},I=function(a){return function(b){void 0!==b.style&&(G=b.style),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},J=d3.format("%");return e.dispatch.on("elementMouseover.tooltip",function(a){a.point.x=e.x()(a.point),a.point.y=e.y()(a.point),k.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),b.dispatch=y,b.stacked=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.interactiveLayer=j,b.tooltip=k,b.dispatch=y,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return w},set:function(a){w=a}},noData:{get:function(){return x},set:function(a){x=a}},showControls:{get:function(){return p},set:function(a){p=a}},controlLabels:{get:function(){return B},set:function(a){B=a}},controlOptions:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},duration:{get:function(){return C},set:function(a){C=a,F.reset(C),e.duration(C),f.duration(C),g.duration(C)}},color:{get:function(){return o},set:function(b){o=a.utils.getColor(b),h.color(o),e.color(o)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},useInteractiveGuideline:{get:function(){return u},set:function(a){u=!!a,b.interactive(!a),b.useVoronoi(!a),e.scatter.interactive(!a)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.sunburst=function(){"use strict";function b(u){return t.reset(),u.each(function(b){function t(a){a.x0=a.x,a.dx0=a.dx}function u(a){var b=d3.interpolate(p.domain(),[a.x,a.x+a.dx]),c=d3.interpolate(q.domain(),[a.y,1]),d=d3.interpolate(q.range(),[a.y?20:0,y]);return function(a,e){return e?function(){return s(a)}:function(e){return p.domain(b(e)),q.domain(c(e)).range(d(e)),s(a)}}}l=d3.select(this);var v,w=a.utils.availableWidth(g,l,f),x=a.utils.availableHeight(h,l,f),y=Math.min(w,x)/2;a.utils.initSVG(l);var z=l.selectAll(".nv-wrap.nv-sunburst").data(b),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburst nv-chart-"+k),B=A.selectAll("nv-sunburst");z.attr("transform","translate("+w/2+","+x/2+")"),l.on("click",function(a,b){o.chartClick({data:a,index:b,pos:d3.event,id:k})}),q.range([0,y]),c=c||b,e=b[0],r.value(j[i]||j.count),v=B.data(r.nodes).enter().append("path").attr("d",s).style("fill",function(a){return m((a.children?a:a.parent).name)}).style("stroke","#FFF").on("click",function(a){d!==c&&c!==a&&(d=c),c=a,v.transition().duration(n).attrTween("d",u(a))}).each(t).on("dblclick",function(a){d.parent==a&&v.transition().duration(n).attrTween("d",u(e))}).each(t).on("mouseover",function(a){d3.select(this).classed("hover",!0).style("opacity",.8),o.elementMouseover({data:a,color:d3.select(this).style("fill")})}).on("mouseout",function(a){d3.select(this).classed("hover",!1).style("opacity",1),o.elementMouseout({data:a})}).on("mousemove",function(a){o.elementMousemove({data:a})})}),t.renderEnd("sunburst immediate"),b}var c,d,e,f={top:0,right:0,bottom:0,left:0},g=null,h=null,i="count",j={count:function(){return 1},size:function(a){return a.size}},k=Math.floor(1e4*Math.random()),l=null,m=a.utils.defaultColor(),n=500,o=d3.dispatch("chartClick","elementClick","elementDblClick","elementMousemove","elementMouseover","elementMouseout","renderEnd"),p=d3.scale.linear().range([0,2*Math.PI]),q=d3.scale.sqrt(),r=d3.layout.partition().sort(null).value(function(){return 1}),s=d3.svg.arc().startAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x)))}).endAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x+a.dx)))}).innerRadius(function(a){return Math.max(0,q(a.y))}).outerRadius(function(a){return Math.max(0,q(a.y+a.dy))}),t=a.utils.renderWatch(o);return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},mode:{get:function(){return i},set:function(a){i=a}},id:{get:function(){return k},set:function(a){k=a}},duration:{get:function(){return n},set:function(a){n=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!=a.top?a.top:f.top,f.right=void 0!=a.right?a.right:f.right,f.bottom=void 0!=a.bottom?a.bottom:f.bottom,f.left=void 0!=a.left?a.left:f.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sunburstChart=function(){"use strict";function b(d){return m.reset(),m.models(c),d.each(function(d){var h=d3.select(this);a.utils.initSVG(h);var i=a.utils.availableWidth(f,h,e),j=a.utils.availableHeight(g,h,e);if(b.update=function(){0===k?h.call(b):h.transition().duration(k).call(b)},b.container=this,!d||!d.length)return a.utils.noData(b,h),b;h.selectAll(".nv-noData").remove();var l=h.selectAll("g.nv-wrap.nv-sunburstChart").data(d),m=l.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburstChart").append("g"),n=l.select("g");m.append("g").attr("class","nv-sunburstWrap"),l.attr("transform","translate("+e.left+","+e.top+")"),c.width(i).height(j);var o=n.select(".nv-sunburstWrap").datum(d);d3.transition(o).call(c)}),m.renderEnd("sunburstChart immediate"),b}var c=a.models.sunburst(),d=a.models.tooltip(),e={top:30,right:20,bottom:20,left:20},f=null,g=null,h=a.utils.defaultColor(),i=(Math.round(1e5*Math.random()),null),j=null,k=250,l=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),m=a.utils.renderWatch(l);return d.headerEnabled(!1).duration(0).valueFormatter(function(a){return a}),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.data.name,value:a.data.size,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=l,b.sunburst=c,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return i},set:function(a){i=a}},color:{get:function(){return h},set:function(a){h=a,c.color(h)}},duration:{get:function(){return k},set:function(a){k=a,m.reset(k),c.duration(k)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.version="1.8.1"}(); \ No newline at end of file
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/respond.min.js b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/respond.min.js
new file mode 100644
index 0000000..80a7b69
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/respond.min.js
@@ -0,0 +1,5 @@
+/*! Respond.js v1.4.2: min/max-width media query polyfill * Copyright 2013 Scott Jehl
+ * Licensed under https://github.com/scottjehl/Respond/blob/master/LICENSE-MIT
+ * */
+
+!function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='&shy;<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b<s.length;b++){var c=s[b],e=c.href,f=c.media,g=c.rel&&"stylesheet"===c.rel.toLowerCase();e&&g&&!o[e]&&(c.styleSheet&&c.styleSheet.rawCssText?(v(c.styleSheet.rawCssText,e,f),o[e]=!0):(!/^([a-zA-Z:]*\/\/)/.test(e)&&!r||e.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&("//"===e.substring(0,2)&&(e=a.location.protocol+e),d.push({href:e,media:f})))}w()};x(),c.update=x,c.getEmValue=t,a.addEventListener?a.addEventListener("resize",b,!1):a.attachEvent&&a.attachEvent("onresize",b)}}(this); \ No newline at end of file
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/method_item.html.dist b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/method_item.html.dist
new file mode 100644
index 0000000..4bb0e42
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/method_item.html.dist
@@ -0,0 +1,11 @@
+ <tr>
+ <td class="{{methods_level}}" colspan="4">{{name}}</td>
+ <td class="{{methods_level}} big">{{methods_bar}}</td>
+ <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
+ <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
+ <td class="{{methods_level}} small">{{crap}}</td>
+ <td class="{{lines_level}} big">{{lines_bar}}</td>
+ <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
+ <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
+ </tr>
+
diff --git a/vendor/phpunit/php-code-coverage/src/Report/PHP.php b/vendor/phpunit/php-code-coverage/src/Report/PHP.php
new file mode 100644
index 0000000..0adb0a3
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/PHP.php
@@ -0,0 +1,51 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report;
+
+use SebastianBergmann\CodeCoverage\CodeCoverage;
+
+/**
+ * Uses var_export() to write a SebastianBergmann\CodeCoverage\CodeCoverage object to a file.
+ */
+class PHP
+{
+ /**
+ * @param CodeCoverage $coverage
+ * @param string $target
+ *
+ * @return string
+ */
+ public function process(CodeCoverage $coverage, $target = null)
+ {
+ $filter = $coverage->filter();
+
+ $output = sprintf(
+ '<?php
+$coverage = new SebastianBergmann\CodeCoverage\CodeCoverage;
+$coverage->setData(%s);
+$coverage->setTests(%s);
+
+$filter = $coverage->filter();
+$filter->setWhitelistedFiles(%s);
+
+return $coverage;',
+ var_export($coverage->getData(true), 1),
+ var_export($coverage->getTests(), 1),
+ var_export($filter->getWhitelistedFiles(), 1)
+ );
+
+ if ($target !== null) {
+ return file_put_contents($target, $output);
+ } else {
+ return $output;
+ }
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Text.php b/vendor/phpunit/php-code-coverage/src/Report/Text.php
new file mode 100644
index 0000000..1e66022
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Text.php
@@ -0,0 +1,257 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report;
+
+use SebastianBergmann\CodeCoverage\CodeCoverage;
+use SebastianBergmann\CodeCoverage\Node\File;
+use SebastianBergmann\CodeCoverage\Util;
+
+/**
+ * Generates human readable output from a code coverage object.
+ *
+ * The output gets put into a text file our written to the CLI.
+ */
+class Text
+{
+ private $lowUpperBound;
+ private $highLowerBound;
+ private $showUncoveredFiles;
+ private $showOnlySummary;
+
+ private $colors = [
+ 'green' => "\x1b[30;42m",
+ 'yellow' => "\x1b[30;43m",
+ 'red' => "\x1b[37;41m",
+ 'header' => "\x1b[1;37;40m",
+ 'reset' => "\x1b[0m",
+ 'eol' => "\x1b[2K",
+ ];
+
+ /**
+ * @param int $lowUpperBound
+ * @param int $highLowerBound
+ * @param bool $showUncoveredFiles
+ * @param bool $showOnlySummary
+ */
+ public function __construct($lowUpperBound = 50, $highLowerBound = 90, $showUncoveredFiles = false, $showOnlySummary = false)
+ {
+ $this->lowUpperBound = $lowUpperBound;
+ $this->highLowerBound = $highLowerBound;
+ $this->showUncoveredFiles = $showUncoveredFiles;
+ $this->showOnlySummary = $showOnlySummary;
+ }
+
+ /**
+ * @param CodeCoverage $coverage
+ * @param bool $showColors
+ *
+ * @return string
+ */
+ public function process(CodeCoverage $coverage, $showColors = false)
+ {
+ $output = PHP_EOL . PHP_EOL;
+ $report = $coverage->getReport();
+ unset($coverage);
+
+ $colors = [
+ 'header' => '',
+ 'classes' => '',
+ 'methods' => '',
+ 'lines' => '',
+ 'reset' => '',
+ 'eol' => ''
+ ];
+
+ if ($showColors) {
+ $colors['classes'] = $this->getCoverageColor(
+ $report->getNumTestedClassesAndTraits(),
+ $report->getNumClassesAndTraits()
+ );
+ $colors['methods'] = $this->getCoverageColor(
+ $report->getNumTestedMethods(),
+ $report->getNumMethods()
+ );
+ $colors['lines'] = $this->getCoverageColor(
+ $report->getNumExecutedLines(),
+ $report->getNumExecutableLines()
+ );
+ $colors['reset'] = $this->colors['reset'];
+ $colors['header'] = $this->colors['header'];
+ $colors['eol'] = $this->colors['eol'];
+ }
+
+ $classes = sprintf(
+ ' Classes: %6s (%d/%d)',
+ Util::percent(
+ $report->getNumTestedClassesAndTraits(),
+ $report->getNumClassesAndTraits(),
+ true
+ ),
+ $report->getNumTestedClassesAndTraits(),
+ $report->getNumClassesAndTraits()
+ );
+
+ $methods = sprintf(
+ ' Methods: %6s (%d/%d)',
+ Util::percent(
+ $report->getNumTestedMethods(),
+ $report->getNumMethods(),
+ true
+ ),
+ $report->getNumTestedMethods(),
+ $report->getNumMethods()
+ );
+
+ $lines = sprintf(
+ ' Lines: %6s (%d/%d)',
+ Util::percent(
+ $report->getNumExecutedLines(),
+ $report->getNumExecutableLines(),
+ true
+ ),
+ $report->getNumExecutedLines(),
+ $report->getNumExecutableLines()
+ );
+
+ $padding = max(array_map('strlen', [$classes, $methods, $lines]));
+
+ if ($this->showOnlySummary) {
+ $title = 'Code Coverage Report Summary:';
+ $padding = max($padding, strlen($title));
+
+ $output .= $this->format($colors['header'], $padding, $title);
+ } else {
+ $date = date(' Y-m-d H:i:s', $_SERVER['REQUEST_TIME']);
+ $title = 'Code Coverage Report:';
+
+ $output .= $this->format($colors['header'], $padding, $title);
+ $output .= $this->format($colors['header'], $padding, $date);
+ $output .= $this->format($colors['header'], $padding, '');
+ $output .= $this->format($colors['header'], $padding, ' Summary:');
+ }
+
+ $output .= $this->format($colors['classes'], $padding, $classes);
+ $output .= $this->format($colors['methods'], $padding, $methods);
+ $output .= $this->format($colors['lines'], $padding, $lines);
+
+ if ($this->showOnlySummary) {
+ return $output . PHP_EOL;
+ }
+
+ $classCoverage = [];
+
+ foreach ($report as $item) {
+ if (!$item instanceof File) {
+ continue;
+ }
+
+ $classes = $item->getClassesAndTraits();
+
+ foreach ($classes as $className => $class) {
+ $classStatements = 0;
+ $coveredClassStatements = 0;
+ $coveredMethods = 0;
+ $classMethods = 0;
+
+ foreach ($class['methods'] as $method) {
+ if ($method['executableLines'] == 0) {
+ continue;
+ }
+
+ $classMethods++;
+ $classStatements += $method['executableLines'];
+ $coveredClassStatements += $method['executedLines'];
+ if ($method['coverage'] == 100) {
+ $coveredMethods++;
+ }
+ }
+
+ if (!empty($class['package']['namespace'])) {
+ $namespace = '\\' . $class['package']['namespace'] . '::';
+ } elseif (!empty($class['package']['fullPackage'])) {
+ $namespace = '@' . $class['package']['fullPackage'] . '::';
+ } else {
+ $namespace = '';
+ }
+
+ $classCoverage[$namespace . $className] = [
+ 'namespace' => $namespace,
+ 'className ' => $className,
+ 'methodsCovered' => $coveredMethods,
+ 'methodCount' => $classMethods,
+ 'statementsCovered' => $coveredClassStatements,
+ 'statementCount' => $classStatements,
+ ];
+ }
+ }
+
+ ksort($classCoverage);
+
+ $methodColor = '';
+ $linesColor = '';
+ $resetColor = '';
+
+ foreach ($classCoverage as $fullQualifiedPath => $classInfo) {
+ if ($classInfo['statementsCovered'] != 0 ||
+ $this->showUncoveredFiles) {
+ if ($showColors) {
+ $methodColor = $this->getCoverageColor($classInfo['methodsCovered'], $classInfo['methodCount']);
+ $linesColor = $this->getCoverageColor($classInfo['statementsCovered'], $classInfo['statementCount']);
+ $resetColor = $colors['reset'];
+ }
+
+ $output .= PHP_EOL . $fullQualifiedPath . PHP_EOL
+ . ' ' . $methodColor . 'Methods: ' . $this->printCoverageCounts($classInfo['methodsCovered'], $classInfo['methodCount'], 2) . $resetColor . ' '
+ . ' ' . $linesColor . 'Lines: ' . $this->printCoverageCounts($classInfo['statementsCovered'], $classInfo['statementCount'], 3) . $resetColor
+ ;
+ }
+ }
+
+ return $output . PHP_EOL;
+ }
+
+ protected function getCoverageColor($numberOfCoveredElements, $totalNumberOfElements)
+ {
+ $coverage = Util::percent(
+ $numberOfCoveredElements,
+ $totalNumberOfElements
+ );
+
+ if ($coverage >= $this->highLowerBound) {
+ return $this->colors['green'];
+ } elseif ($coverage > $this->lowUpperBound) {
+ return $this->colors['yellow'];
+ }
+
+ return $this->colors['red'];
+ }
+
+ protected function printCoverageCounts($numberOfCoveredElements, $totalNumberOfElements, $precision)
+ {
+ $format = '%' . $precision . 's';
+
+ return Util::percent(
+ $numberOfCoveredElements,
+ $totalNumberOfElements,
+ true,
+ true
+ ) .
+ ' (' . sprintf($format, $numberOfCoveredElements) . '/' .
+ sprintf($format, $totalNumberOfElements) . ')';
+ }
+
+ private function format($color, $padding, $string)
+ {
+ $reset = $color ? $this->colors['reset'] : '';
+
+ return $color . str_pad($string, $padding) . $reset . PHP_EOL;
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Coverage.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Coverage.php
new file mode 100644
index 0000000..1a65fbe
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Coverage.php
@@ -0,0 +1,67 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Xml;
+
+use SebastianBergmann\CodeCoverage\RuntimeException;
+
+class Coverage
+{
+ /**
+ * @var \XMLWriter
+ */
+ private $writer;
+
+ /**
+ * @var \DOMElement
+ */
+ private $contextNode;
+
+ /**
+ * @var bool
+ */
+ private $finalized = false;
+
+ public function __construct(\DOMElement $context, $line)
+ {
+ $this->contextNode = $context;
+
+ $this->writer = new \XMLWriter;
+ $this->writer->openMemory();
+ $this->writer->startElementNs(null, $context->nodeName, 'http://schema.phpunit.de/coverage/1.0');
+ $this->writer->writeAttribute('nr', $line);
+ }
+
+ public function addTest($test)
+ {
+ if ($this->finalized) {
+ throw new RuntimeException('Coverage Report already finalized');
+ }
+
+ $this->writer->startElement('covered');
+ $this->writer->writeAttribute('by', $test);
+ $this->writer->endElement();
+ }
+
+ public function finalize()
+ {
+ $this->writer->endElement();
+
+ $fragment = $this->contextNode->ownerDocument->createDocumentFragment();
+ $fragment->appendXML($this->writer->outputMemory());
+
+ $this->contextNode->parentNode->replaceChild(
+ $fragment,
+ $this->contextNode
+ );
+
+ $this->finalized = true;
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Directory.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Directory.php
new file mode 100644
index 0000000..71d5a40
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Directory.php
@@ -0,0 +1,15 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Xml;
+
+class Directory extends Node
+{
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Facade.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Facade.php
new file mode 100644
index 0000000..c983da7
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Facade.php
@@ -0,0 +1,238 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Xml;
+
+use SebastianBergmann\CodeCoverage\CodeCoverage;
+use SebastianBergmann\CodeCoverage\Node\AbstractNode;
+use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode;
+use SebastianBergmann\CodeCoverage\Node\File as FileNode;
+use SebastianBergmann\CodeCoverage\RuntimeException;
+
+class Facade
+{
+ /**
+ * @var string
+ */
+ private $target;
+
+ /**
+ * @var Project
+ */
+ private $project;
+
+ /**
+ * @param CodeCoverage $coverage
+ * @param string $target
+ *
+ * @throws RuntimeException
+ */
+ public function process(CodeCoverage $coverage, $target)
+ {
+ if (substr($target, -1, 1) != DIRECTORY_SEPARATOR) {
+ $target .= DIRECTORY_SEPARATOR;
+ }
+
+ $this->target = $target;
+ $this->initTargetDirectory($target);
+
+ $report = $coverage->getReport();
+
+ $this->project = new Project(
+ $coverage->getReport()->getName()
+ );
+
+ $this->processTests($coverage->getTests());
+ $this->processDirectory($report, $this->project);
+
+ $index = $this->project->asDom();
+ $index->formatOutput = true;
+ $index->preserveWhiteSpace = false;
+ $index->save($target . '/index.xml');
+ }
+
+ /**
+ * @param string $directory
+ */
+ private function initTargetDirectory($directory)
+ {
+ if (file_exists($directory)) {
+ if (!is_dir($directory)) {
+ throw new RuntimeException(
+ "'$directory' exists but is not a directory."
+ );
+ }
+
+ if (!is_writable($directory)) {
+ throw new RuntimeException(
+ "'$directory' exists but is not writable."
+ );
+ }
+ } elseif (!@mkdir($directory, 0777, true)) {
+ throw new RuntimeException(
+ "'$directory' could not be created."
+ );
+ }
+ }
+
+ private function processDirectory(DirectoryNode $directory, Node $context)
+ {
+ $dirObject = $context->addDirectory($directory->getName());
+
+ $this->setTotals($directory, $dirObject->getTotals());
+
+ foreach ($directory->getDirectories() as $node) {
+ $this->processDirectory($node, $dirObject);
+ }
+
+ foreach ($directory->getFiles() as $node) {
+ $this->processFile($node, $dirObject);
+ }
+ }
+
+ private function processFile(FileNode $file, Directory $context)
+ {
+ $fileObject = $context->addFile(
+ $file->getName(),
+ $file->getId() . '.xml'
+ );
+
+ $this->setTotals($file, $fileObject->getTotals());
+
+ $fileReport = new Report($file->getName());
+
+ $this->setTotals($file, $fileReport->getTotals());
+
+ foreach ($file->getClassesAndTraits() as $unit) {
+ $this->processUnit($unit, $fileReport);
+ }
+
+ foreach ($file->getFunctions() as $function) {
+ $this->processFunction($function, $fileReport);
+ }
+
+ foreach ($file->getCoverageData() as $line => $tests) {
+ if (!is_array($tests) || count($tests) == 0) {
+ continue;
+ }
+
+ $coverage = $fileReport->getLineCoverage($line);
+
+ foreach ($tests as $test) {
+ $coverage->addTest($test);
+ }
+
+ $coverage->finalize();
+ }
+
+ $this->initTargetDirectory(
+ $this->target . dirname($file->getId()) . '/'
+ );
+
+ $fileDom = $fileReport->asDom();
+ $fileDom->formatOutput = true;
+ $fileDom->preserveWhiteSpace = false;
+ $fileDom->save($this->target . $file->getId() . '.xml');
+ }
+
+ private function processUnit($unit, Report $report)
+ {
+ if (isset($unit['className'])) {
+ $unitObject = $report->getClassObject($unit['className']);
+ } else {
+ $unitObject = $report->getTraitObject($unit['traitName']);
+ }
+
+ $unitObject->setLines(
+ $unit['startLine'],
+ $unit['executableLines'],
+ $unit['executedLines']
+ );
+
+ $unitObject->setCrap($unit['crap']);
+
+ $unitObject->setPackage(
+ $unit['package']['fullPackage'],
+ $unit['package']['package'],
+ $unit['package']['subpackage'],
+ $unit['package']['category']
+ );
+
+ $unitObject->setNamespace($unit['package']['namespace']);
+
+ foreach ($unit['methods'] as $method) {
+ $methodObject = $unitObject->addMethod($method['methodName']);
+ $methodObject->setSignature($method['signature']);
+ $methodObject->setLines($method['startLine'], $method['endLine']);
+ $methodObject->setCrap($method['crap']);
+ $methodObject->setTotals(
+ $method['executableLines'],
+ $method['executedLines'],
+ $method['coverage']
+ );
+ }
+ }
+
+ private function processFunction($function, Report $report)
+ {
+ $functionObject = $report->getFunctionObject($function['functionName']);
+
+ $functionObject->setSignature($function['signature']);
+ $functionObject->setLines($function['startLine']);
+ $functionObject->setCrap($function['crap']);
+ $functionObject->setTotals($function['executableLines'], $function['executedLines'], $function['coverage']);
+ }
+
+ private function processTests(array $tests)
+ {
+ $testsObject = $this->project->getTests();
+
+ foreach ($tests as $test => $result) {
+ if ($test == 'UNCOVERED_FILES_FROM_WHITELIST') {
+ continue;
+ }
+
+ $testsObject->addTest($test, $result);
+ }
+ }
+
+ private function setTotals(AbstractNode $node, Totals $totals)
+ {
+ $loc = $node->getLinesOfCode();
+
+ $totals->setNumLines(
+ $loc['loc'],
+ $loc['cloc'],
+ $loc['ncloc'],
+ $node->getNumExecutableLines(),
+ $node->getNumExecutedLines()
+ );
+
+ $totals->setNumClasses(
+ $node->getNumClasses(),
+ $node->getNumTestedClasses()
+ );
+
+ $totals->setNumTraits(
+ $node->getNumTraits(),
+ $node->getNumTestedTraits()
+ );
+
+ $totals->setNumMethods(
+ $node->getNumMethods(),
+ $node->getNumTestedMethods()
+ );
+
+ $totals->setNumFunctions(
+ $node->getNumFunctions(),
+ $node->getNumTestedFunctions()
+ );
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/File.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/File.php
new file mode 100644
index 0000000..5d6d71d
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/File.php
@@ -0,0 +1,72 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Xml;
+
+class File
+{
+ /**
+ * @var \DOMDocument
+ */
+ protected $dom;
+
+ /**
+ * @var \DOMElement
+ */
+ protected $contextNode;
+
+ public function __construct(\DOMElement $context)
+ {
+ $this->dom = $context->ownerDocument;
+ $this->contextNode = $context;
+ }
+
+ public function getTotals()
+ {
+ $totalsContainer = $this->contextNode->firstChild;
+
+ if (!$totalsContainer) {
+ $totalsContainer = $this->contextNode->appendChild(
+ $this->dom->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'totals'
+ )
+ );
+ }
+
+ return new Totals($totalsContainer);
+ }
+
+ public function getLineCoverage($line)
+ {
+ $coverage = $this->contextNode->getElementsByTagNameNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'coverage'
+ )->item(0);
+
+ if (!$coverage) {
+ $coverage = $this->contextNode->appendChild(
+ $this->dom->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'coverage'
+ )
+ );
+ }
+
+ $lineNode = $coverage->appendChild(
+ $this->dom->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'line'
+ )
+ );
+
+ return new Coverage($lineNode, $line);
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Method.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Method.php
new file mode 100644
index 0000000..10eb762
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Method.php
@@ -0,0 +1,57 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Xml;
+
+class Method
+{
+ /**
+ * @var \DOMElement
+ */
+ private $contextNode;
+
+ public function __construct(\DOMElement $context, $name)
+ {
+ $this->contextNode = $context;
+
+ $this->setName($name);
+ }
+
+ private function setName($name)
+ {
+ $this->contextNode->setAttribute('name', $name);
+ }
+
+ public function setSignature($signature)
+ {
+ $this->contextNode->setAttribute('signature', $signature);
+ }
+
+ public function setLines($start, $end = null)
+ {
+ $this->contextNode->setAttribute('start', $start);
+
+ if ($end !== null) {
+ $this->contextNode->setAttribute('end', $end);
+ }
+ }
+
+ public function setTotals($executable, $executed, $coverage)
+ {
+ $this->contextNode->setAttribute('executable', $executable);
+ $this->contextNode->setAttribute('executed', $executed);
+ $this->contextNode->setAttribute('coverage', $coverage);
+ }
+
+ public function setCrap($crap)
+ {
+ $this->contextNode->setAttribute('crap', $crap);
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Node.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Node.php
new file mode 100644
index 0000000..43776f1
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Node.php
@@ -0,0 +1,88 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Xml;
+
+class Node
+{
+ /**
+ * @var \DOMDocument
+ */
+ private $dom;
+
+ /**
+ * @var \DOMElement
+ */
+ private $contextNode;
+
+ public function __construct(\DOMElement $context)
+ {
+ $this->setContextNode($context);
+ }
+
+ protected function setContextNode(\DOMElement $context)
+ {
+ $this->dom = $context->ownerDocument;
+ $this->contextNode = $context;
+ }
+
+ public function getDom()
+ {
+ return $this->dom;
+ }
+
+ protected function getContextNode()
+ {
+ return $this->contextNode;
+ }
+
+ public function getTotals()
+ {
+ $totalsContainer = $this->getContextNode()->firstChild;
+
+ if (!$totalsContainer) {
+ $totalsContainer = $this->getContextNode()->appendChild(
+ $this->dom->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'totals'
+ )
+ );
+ }
+
+ return new Totals($totalsContainer);
+ }
+
+ public function addDirectory($name)
+ {
+ $dirNode = $this->getDom()->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'directory'
+ );
+
+ $dirNode->setAttribute('name', $name);
+ $this->getContextNode()->appendChild($dirNode);
+
+ return new Directory($dirNode);
+ }
+
+ public function addFile($name, $href)
+ {
+ $fileNode = $this->getDom()->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'file'
+ );
+
+ $fileNode->setAttribute('name', $name);
+ $fileNode->setAttribute('href', $href);
+ $this->getContextNode()->appendChild($fileNode);
+
+ return new File($fileNode);
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Project.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Project.php
new file mode 100644
index 0000000..17bf1e6
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Project.php
@@ -0,0 +1,62 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Xml;
+
+class Project extends Node
+{
+ public function __construct($name)
+ {
+ $this->init();
+ $this->setProjectName($name);
+ }
+
+ private function init()
+ {
+ $dom = new \DOMDocument;
+ $dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="http://schema.phpunit.de/coverage/1.0"><project/></phpunit>');
+
+ $this->setContextNode(
+ $dom->getElementsByTagNameNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'project'
+ )->item(0)
+ );
+ }
+
+ private function setProjectName($name)
+ {
+ $this->getContextNode()->setAttribute('name', $name);
+ }
+
+ public function getTests()
+ {
+ $testsNode = $this->getContextNode()->getElementsByTagNameNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'tests'
+ )->item(0);
+
+ if (!$testsNode) {
+ $testsNode = $this->getContextNode()->appendChild(
+ $this->getDom()->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'tests'
+ )
+ );
+ }
+
+ return new Tests($testsNode);
+ }
+
+ public function asDom()
+ {
+ return $this->getDom();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Report.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Report.php
new file mode 100644
index 0000000..4c3e3e5
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Report.php
@@ -0,0 +1,71 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Xml;
+
+class Report extends File
+{
+ public function __construct($name)
+ {
+ $this->dom = new \DOMDocument;
+ $this->dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="http://schema.phpunit.de/coverage/1.0"><file /></phpunit>');
+
+ $this->contextNode = $this->dom->getElementsByTagNameNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'file'
+ )->item(0);
+
+ $this->setName($name);
+ }
+
+ private function setName($name)
+ {
+ $this->contextNode->setAttribute('name', $name);
+ }
+
+ public function asDom()
+ {
+ return $this->dom;
+ }
+
+ public function getFunctionObject($name)
+ {
+ $node = $this->contextNode->appendChild(
+ $this->dom->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'function'
+ )
+ );
+
+ return new Method($node, $name);
+ }
+
+ public function getClassObject($name)
+ {
+ return $this->getUnitObject('class', $name);
+ }
+
+ public function getTraitObject($name)
+ {
+ return $this->getUnitObject('trait', $name);
+ }
+
+ private function getUnitObject($tagName, $name)
+ {
+ $node = $this->contextNode->appendChild(
+ $this->dom->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ $tagName
+ )
+ );
+
+ return new Unit($node, $name);
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Tests.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Tests.php
new file mode 100644
index 0000000..b569b03
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Tests.php
@@ -0,0 +1,46 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Xml;
+
+class Tests
+{
+ private $contextNode;
+
+ private $codeMap = [
+ 0 => 'PASSED', // PHPUnit_Runner_BaseTestRunner::STATUS_PASSED
+ 1 => 'SKIPPED', // PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED
+ 2 => 'INCOMPLETE', // PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE
+ 3 => 'FAILURE', // PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE
+ 4 => 'ERROR', // PHPUnit_Runner_BaseTestRunner::STATUS_ERROR
+ 5 => 'RISKY', // PHPUnit_Runner_BaseTestRunner::STATUS_RISKY
+ 6 => 'WARNING' // PHPUnit_Runner_BaseTestRunner::STATUS_WARNING
+ ];
+
+ public function __construct(\DOMElement $context)
+ {
+ $this->contextNode = $context;
+ }
+
+ public function addTest($test, array $result)
+ {
+ $node = $this->contextNode->appendChild(
+ $this->contextNode->ownerDocument->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'test'
+ )
+ );
+
+ $node->setAttribute('name', $test);
+ $node->setAttribute('size', $result['size']);
+ $node->setAttribute('result', (int) $result['status']);
+ $node->setAttribute('status', $this->codeMap[(int) $result['status']]);
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Totals.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Totals.php
new file mode 100644
index 0000000..a1eaa9e
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Totals.php
@@ -0,0 +1,141 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Xml;
+
+use SebastianBergmann\CodeCoverage\Util;
+
+class Totals
+{
+ /**
+ * @var \DOMNode
+ */
+ private $container;
+
+ /**
+ * @var \DOMElement
+ */
+ private $linesNode;
+
+ /**
+ * @var \DOMElement
+ */
+ private $methodsNode;
+
+ /**
+ * @var \DOMElement
+ */
+ private $functionsNode;
+
+ /**
+ * @var \DOMElement
+ */
+ private $classesNode;
+
+ /**
+ * @var \DOMElement
+ */
+ private $traitsNode;
+
+ public function __construct(\DOMElement $container)
+ {
+ $this->container = $container;
+ $dom = $container->ownerDocument;
+
+ $this->linesNode = $dom->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'lines'
+ );
+
+ $this->methodsNode = $dom->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'methods'
+ );
+
+ $this->functionsNode = $dom->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'functions'
+ );
+
+ $this->classesNode = $dom->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'classes'
+ );
+
+ $this->traitsNode = $dom->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'traits'
+ );
+
+ $container->appendChild($this->linesNode);
+ $container->appendChild($this->methodsNode);
+ $container->appendChild($this->functionsNode);
+ $container->appendChild($this->classesNode);
+ $container->appendChild($this->traitsNode);
+ }
+
+ public function getContainer()
+ {
+ return $this->container;
+ }
+
+ public function setNumLines($loc, $cloc, $ncloc, $executable, $executed)
+ {
+ $this->linesNode->setAttribute('total', $loc);
+ $this->linesNode->setAttribute('comments', $cloc);
+ $this->linesNode->setAttribute('code', $ncloc);
+ $this->linesNode->setAttribute('executable', $executable);
+ $this->linesNode->setAttribute('executed', $executed);
+ $this->linesNode->setAttribute(
+ 'percent',
+ Util::percent($executed, $executable, true)
+ );
+ }
+
+ public function setNumClasses($count, $tested)
+ {
+ $this->classesNode->setAttribute('count', $count);
+ $this->classesNode->setAttribute('tested', $tested);
+ $this->classesNode->setAttribute(
+ 'percent',
+ Util::percent($tested, $count, true)
+ );
+ }
+
+ public function setNumTraits($count, $tested)
+ {
+ $this->traitsNode->setAttribute('count', $count);
+ $this->traitsNode->setAttribute('tested', $tested);
+ $this->traitsNode->setAttribute(
+ 'percent',
+ Util::percent($tested, $count, true)
+ );
+ }
+
+ public function setNumMethods($count, $tested)
+ {
+ $this->methodsNode->setAttribute('count', $count);
+ $this->methodsNode->setAttribute('tested', $tested);
+ $this->methodsNode->setAttribute(
+ 'percent',
+ Util::percent($tested, $count, true)
+ );
+ }
+
+ public function setNumFunctions($count, $tested)
+ {
+ $this->functionsNode->setAttribute('count', $count);
+ $this->functionsNode->setAttribute('tested', $tested);
+ $this->functionsNode->setAttribute(
+ 'percent',
+ Util::percent($tested, $count, true)
+ );
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Unit.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Unit.php
new file mode 100644
index 0000000..854f844
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Unit.php
@@ -0,0 +1,96 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Xml;
+
+class Unit
+{
+ /**
+ * @var \DOMElement
+ */
+ private $contextNode;
+
+ public function __construct(\DOMElement $context, $name)
+ {
+ $this->contextNode = $context;
+
+ $this->setName($name);
+ }
+
+ private function setName($name)
+ {
+ $this->contextNode->setAttribute('name', $name);
+ }
+
+ public function setLines($start, $executable, $executed)
+ {
+ $this->contextNode->setAttribute('start', $start);
+ $this->contextNode->setAttribute('executable', $executable);
+ $this->contextNode->setAttribute('executed', $executed);
+ }
+
+ public function setCrap($crap)
+ {
+ $this->contextNode->setAttribute('crap', $crap);
+ }
+
+ public function setPackage($full, $package, $sub, $category)
+ {
+ $node = $this->contextNode->getElementsByTagNameNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'package'
+ )->item(0);
+
+ if (!$node) {
+ $node = $this->contextNode->appendChild(
+ $this->contextNode->ownerDocument->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'package'
+ )
+ );
+ }
+
+ $node->setAttribute('full', $full);
+ $node->setAttribute('name', $package);
+ $node->setAttribute('sub', $sub);
+ $node->setAttribute('category', $category);
+ }
+
+ public function setNamespace($namespace)
+ {
+ $node = $this->contextNode->getElementsByTagNameNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'namespace'
+ )->item(0);
+
+ if (!$node) {
+ $node = $this->contextNode->appendChild(
+ $this->contextNode->ownerDocument->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'namespace'
+ )
+ );
+ }
+
+ $node->setAttribute('name', $namespace);
+ }
+
+ public function addMethod($name)
+ {
+ $node = $this->contextNode->appendChild(
+ $this->contextNode->ownerDocument->createElementNS(
+ 'http://schema.phpunit.de/coverage/1.0',
+ 'method'
+ )
+ );
+
+ return new Method($node, $name);
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/src/Util.php b/vendor/phpunit/php-code-coverage/src/Util.php
new file mode 100644
index 0000000..89164f7
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/src/Util.php
@@ -0,0 +1,48 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage;
+
+/**
+ * Utility methods.
+ */
+class Util
+{
+ /**
+ * @param float $a
+ * @param float $b
+ * @param bool $asString
+ * @param bool $fixedWidth
+ *
+ * @return float|int|string
+ */
+ public static function percent($a, $b, $asString = false, $fixedWidth = false)
+ {
+ if ($asString && $b == 0) {
+ return '';
+ }
+
+ if ($b > 0) {
+ $percent = ($a / $b) * 100;
+ } else {
+ $percent = 100;
+ }
+
+ if ($asString) {
+ if ($fixedWidth) {
+ return sprintf('%6.2F%%', $percent);
+ }
+
+ return sprintf('%01.2F%%', $percent);
+ } else {
+ return $percent;
+ }
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/TestCase.php b/vendor/phpunit/php-code-coverage/tests/TestCase.php
new file mode 100644
index 0000000..cd18a82
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/TestCase.php
@@ -0,0 +1,343 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage;
+
+use SebastianBergmann\CodeCoverage\Driver\Xdebug;
+
+/**
+ * Abstract base class for test case classes.
+ *
+ * @since Class available since Release 1.0.0
+ */
+abstract class TestCase extends \PHPUnit_Framework_TestCase
+{
+ protected static $TEST_TMP_PATH;
+
+ public static function setUpBeforeClass()
+ {
+ self::$TEST_TMP_PATH = TEST_FILES_PATH . 'tmp';
+ }
+
+ protected function getXdebugDataForBankAccount()
+ {
+ return [
+ [
+ TEST_FILES_PATH . 'BankAccount.php' => [
+ 8 => 1,
+ 9 => -2,
+ 13 => -1,
+ 14 => -1,
+ 15 => -1,
+ 16 => -1,
+ 18 => -1,
+ 22 => -1,
+ 24 => -1,
+ 25 => -2,
+ 29 => -1,
+ 31 => -1,
+ 32 => -2
+ ]
+ ],
+ [
+ TEST_FILES_PATH . 'BankAccount.php' => [
+ 8 => 1,
+ 13 => 1,
+ 16 => 1,
+ 29 => 1,
+ ]
+ ],
+ [
+ TEST_FILES_PATH . 'BankAccount.php' => [
+ 8 => 1,
+ 13 => 1,
+ 16 => 1,
+ 22 => 1,
+ ]
+ ],
+ [
+ TEST_FILES_PATH . 'BankAccount.php' => [
+ 8 => 1,
+ 13 => 1,
+ 14 => 1,
+ 15 => 1,
+ 18 => 1,
+ 22 => 1,
+ 24 => 1,
+ 29 => 1,
+ 31 => 1,
+ ]
+ ]
+ ];
+ }
+
+ protected function getCoverageForBankAccount()
+ {
+ $data = $this->getXdebugDataForBankAccount();
+ require_once TEST_FILES_PATH . '/BankAccountTest.php';
+
+ $stub = $this->createMock(Xdebug::class);
+
+ $stub->expects($this->any())
+ ->method('stop')
+ ->will($this->onConsecutiveCalls(
+ $data[0],
+ $data[1],
+ $data[2],
+ $data[3]
+ ));
+
+ $filter = new Filter;
+ $filter->addFileToWhitelist(TEST_FILES_PATH . 'BankAccount.php');
+
+ $coverage = new CodeCoverage($stub, $filter);
+
+ $coverage->start(
+ new \BankAccountTest('testBalanceIsInitiallyZero'),
+ true
+ );
+
+ $coverage->stop(
+ true,
+ [TEST_FILES_PATH . 'BankAccount.php' => range(6, 9)]
+ );
+
+ $coverage->start(
+ new \BankAccountTest('testBalanceCannotBecomeNegative')
+ );
+
+ $coverage->stop(
+ true,
+ [TEST_FILES_PATH . 'BankAccount.php' => range(27, 32)]
+ );
+
+ $coverage->start(
+ new \BankAccountTest('testBalanceCannotBecomeNegative2')
+ );
+
+ $coverage->stop(
+ true,
+ [TEST_FILES_PATH . 'BankAccount.php' => range(20, 25)]
+ );
+
+ $coverage->start(
+ new \BankAccountTest('testDepositWithdrawMoney')
+ );
+
+ $coverage->stop(
+ true,
+ [
+ TEST_FILES_PATH . 'BankAccount.php' => array_merge(
+ range(6, 9),
+ range(20, 25),
+ range(27, 32)
+ )
+ ]
+ );
+
+ return $coverage;
+ }
+
+ protected function getCoverageForBankAccountForFirstTwoTests()
+ {
+ $data = $this->getXdebugDataForBankAccount();
+
+ $stub = $this->createMock(Xdebug::class);
+
+ $stub->expects($this->any())
+ ->method('stop')
+ ->will($this->onConsecutiveCalls(
+ $data[0],
+ $data[1]
+ ));
+
+ $filter = new Filter;
+ $filter->addFileToWhitelist(TEST_FILES_PATH . 'BankAccount.php');
+
+ $coverage = new CodeCoverage($stub, $filter);
+
+ $coverage->start(
+ new \BankAccountTest('testBalanceIsInitiallyZero'),
+ true
+ );
+
+ $coverage->stop(
+ true,
+ [TEST_FILES_PATH . 'BankAccount.php' => range(6, 9)]
+ );
+
+ $coverage->start(
+ new \BankAccountTest('testBalanceCannotBecomeNegative')
+ );
+
+ $coverage->stop(
+ true,
+ [TEST_FILES_PATH . 'BankAccount.php' => range(27, 32)]
+ );
+
+ return $coverage;
+ }
+
+ protected function getCoverageForBankAccountForLastTwoTests()
+ {
+ $data = $this->getXdebugDataForBankAccount();
+
+ $stub = $this->createMock(Xdebug::class);
+
+ $stub->expects($this->any())
+ ->method('stop')
+ ->will($this->onConsecutiveCalls(
+ $data[2],
+ $data[3]
+ ));
+
+ $filter = new Filter;
+ $filter->addFileToWhitelist(TEST_FILES_PATH . 'BankAccount.php');
+
+ $coverage = new CodeCoverage($stub, $filter);
+
+ $coverage->start(
+ new \BankAccountTest('testBalanceCannotBecomeNegative2')
+ );
+
+ $coverage->stop(
+ true,
+ [TEST_FILES_PATH . 'BankAccount.php' => range(20, 25)]
+ );
+
+ $coverage->start(
+ new \BankAccountTest('testDepositWithdrawMoney')
+ );
+
+ $coverage->stop(
+ true,
+ [
+ TEST_FILES_PATH . 'BankAccount.php' => array_merge(
+ range(6, 9),
+ range(20, 25),
+ range(27, 32)
+ )
+ ]
+ );
+
+ return $coverage;
+ }
+
+ protected function getExpectedDataArrayForBankAccount()
+ {
+ return [
+ TEST_FILES_PATH . 'BankAccount.php' => [
+ 8 => [
+ 0 => 'BankAccountTest::testBalanceIsInitiallyZero',
+ 1 => 'BankAccountTest::testDepositWithdrawMoney'
+ ],
+ 9 => null,
+ 13 => [],
+ 14 => [],
+ 15 => [],
+ 16 => [],
+ 18 => [],
+ 22 => [
+ 0 => 'BankAccountTest::testBalanceCannotBecomeNegative2',
+ 1 => 'BankAccountTest::testDepositWithdrawMoney'
+ ],
+ 24 => [
+ 0 => 'BankAccountTest::testDepositWithdrawMoney',
+ ],
+ 25 => null,
+ 29 => [
+ 0 => 'BankAccountTest::testBalanceCannotBecomeNegative',
+ 1 => 'BankAccountTest::testDepositWithdrawMoney'
+ ],
+ 31 => [
+ 0 => 'BankAccountTest::testDepositWithdrawMoney'
+ ],
+ 32 => null
+ ]
+ ];
+ }
+
+ protected function getCoverageForFileWithIgnoredLines()
+ {
+ $filter = new Filter;
+ $filter->addFileToWhitelist(TEST_FILES_PATH . 'source_with_ignore.php');
+
+ $coverage = new CodeCoverage(
+ $this->setUpXdebugStubForFileWithIgnoredLines(),
+ $filter
+ );
+
+ $coverage->start('FileWithIgnoredLines', true);
+ $coverage->stop();
+
+ return $coverage;
+ }
+
+ protected function setUpXdebugStubForFileWithIgnoredLines()
+ {
+ $stub = $this->createMock(Xdebug::class);
+
+ $stub->expects($this->any())
+ ->method('stop')
+ ->will($this->returnValue(
+ [
+ TEST_FILES_PATH . 'source_with_ignore.php' => [
+ 2 => 1,
+ 4 => -1,
+ 6 => -1,
+ 7 => 1
+ ]
+ ]
+ ));
+
+ return $stub;
+ }
+
+ protected function getCoverageForClassWithAnonymousFunction()
+ {
+ $filter = new Filter;
+ $filter->addFileToWhitelist(TEST_FILES_PATH . 'source_with_class_and_anonymous_function.php');
+
+ $coverage = new CodeCoverage(
+ $this->setUpXdebugStubForClassWithAnonymousFunction(),
+ $filter
+ );
+
+ $coverage->start('ClassWithAnonymousFunction', true);
+ $coverage->stop();
+
+ return $coverage;
+ }
+
+ protected function setUpXdebugStubForClassWithAnonymousFunction()
+ {
+ $stub = $this->createMock(Xdebug::class);
+
+ $stub->expects($this->any())
+ ->method('stop')
+ ->will($this->returnValue(
+ [
+ TEST_FILES_PATH . 'source_with_class_and_anonymous_function.php' => [
+ 7 => 1,
+ 9 => 1,
+ 10 => -1,
+ 11 => 1,
+ 12 => 1,
+ 13 => 1,
+ 14 => 1,
+ 17 => 1,
+ 18 => 1
+ ]
+ ]
+ ));
+
+ return $stub;
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-clover.xml b/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-clover.xml
new file mode 100644
index 0000000..0986fdf
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-clover.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<coverage generated="%i">
+ <project timestamp="%i" name="BankAccount">
+ <file name="%s/BankAccount.php">
+ <class name="BankAccount" namespace="global">
+ <metrics complexity="5" methods="4" coveredmethods="3" conditionals="0" coveredconditionals="0" statements="10" coveredstatements="5" elements="14" coveredelements="8"/>
+ </class>
+ <line num="6" type="method" name="getBalance" visibility="public" complexity="1" crap="1" count="2"/>
+ <line num="8" type="stmt" count="2"/>
+ <line num="11" type="method" name="setBalance" visibility="protected" complexity="2" crap="6" count="0"/>
+ <line num="13" type="stmt" count="0"/>
+ <line num="14" type="stmt" count="0"/>
+ <line num="15" type="stmt" count="0"/>
+ <line num="16" type="stmt" count="0"/>
+ <line num="18" type="stmt" count="0"/>
+ <line num="20" type="method" name="depositMoney" visibility="public" complexity="1" crap="1" count="2"/>
+ <line num="22" type="stmt" count="2"/>
+ <line num="24" type="stmt" count="1"/>
+ <line num="27" type="method" name="withdrawMoney" visibility="public" complexity="1" crap="1" count="2"/>
+ <line num="29" type="stmt" count="2"/>
+ <line num="31" type="stmt" count="1"/>
+ <metrics loc="33" ncloc="33" classes="1" methods="4" coveredmethods="3" conditionals="0" coveredconditionals="0" statements="10" coveredstatements="5" elements="14" coveredelements="8"/>
+ </file>
+ <metrics files="1" loc="33" ncloc="33" classes="1" methods="4" coveredmethods="3" conditionals="0" coveredconditionals="0" statements="10" coveredstatements="5" elements="14" coveredelements="8"/>
+ </project>
+</coverage>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-crap4j.xml b/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-crap4j.xml
new file mode 100644
index 0000000..f2f56ea
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-crap4j.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<crap_result>
+ <project>BankAccount</project>
+ <timestamp>%s</timestamp>
+ <stats>
+ <name>Method Crap Stats</name>
+ <methodCount>4</methodCount>
+ <crapMethodCount>0</crapMethodCount>
+ <crapLoad>0</crapLoad>
+ <totalCrap>9</totalCrap>
+ <crapMethodPercent>0</crapMethodPercent>
+ </stats>
+ <methods>
+ <method>
+ <package>global</package>
+ <className>BankAccount</className>
+ <methodName>getBalance</methodName>
+ <methodSignature>getBalance()</methodSignature>
+ <fullMethod>getBalance()</fullMethod>
+ <crap>1</crap>
+ <complexity>1</complexity>
+ <coverage>100</coverage>
+ <crapLoad>0</crapLoad>
+ </method>
+ <method>
+ <package>global</package>
+ <className>BankAccount</className>
+ <methodName>setBalance</methodName>
+ <methodSignature>setBalance($balance)</methodSignature>
+ <fullMethod>setBalance($balance)</fullMethod>
+ <crap>6</crap>
+ <complexity>2</complexity>
+ <coverage>0</coverage>
+ <crapLoad>0</crapLoad>
+ </method>
+ <method>
+ <package>global</package>
+ <className>BankAccount</className>
+ <methodName>depositMoney</methodName>
+ <methodSignature>depositMoney($balance)</methodSignature>
+ <fullMethod>depositMoney($balance)</fullMethod>
+ <crap>1</crap>
+ <complexity>1</complexity>
+ <coverage>100</coverage>
+ <crapLoad>0</crapLoad>
+ </method>
+ <method>
+ <package>global</package>
+ <className>BankAccount</className>
+ <methodName>withdrawMoney</methodName>
+ <methodSignature>withdrawMoney($balance)</methodSignature>
+ <fullMethod>withdrawMoney($balance)</fullMethod>
+ <crap>1</crap>
+ <complexity>1</complexity>
+ <coverage>100</coverage>
+ <crapLoad>0</crapLoad>
+ </method>
+ </methods>
+</crap_result>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-text.txt b/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-text.txt
new file mode 100644
index 0000000..892d834
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-text.txt
@@ -0,0 +1,12 @@
+
+
+Code Coverage Report:
+ %s
+
+ Summary:
+ Classes: 0.00% (0/1)
+ Methods: 75.00% (3/4)
+ Lines: 50.00% (5/10)
+
+BankAccount
+ Methods: 75.00% ( 3/ 4) Lines: 50.00% ( 5/ 10)
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/BankAccount.php b/vendor/phpunit/php-code-coverage/tests/_files/BankAccount.php
new file mode 100644
index 0000000..4238c15
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/BankAccount.php
@@ -0,0 +1,33 @@
+<?php
+class BankAccount
+{
+ protected $balance = 0;
+
+ public function getBalance()
+ {
+ return $this->balance;
+ }
+
+ protected function setBalance($balance)
+ {
+ if ($balance >= 0) {
+ $this->balance = $balance;
+ } else {
+ throw new RuntimeException;
+ }
+ }
+
+ public function depositMoney($balance)
+ {
+ $this->setBalance($this->getBalance() + $balance);
+
+ return $this->getBalance();
+ }
+
+ public function withdrawMoney($balance)
+ {
+ $this->setBalance($this->getBalance() - $balance);
+
+ return $this->getBalance();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/BankAccountTest.php b/vendor/phpunit/php-code-coverage/tests/_files/BankAccountTest.php
new file mode 100644
index 0000000..3a6277b
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/BankAccountTest.php
@@ -0,0 +1,66 @@
+<?php
+require_once 'BankAccount.php';
+
+class BankAccountTest extends PHPUnit_Framework_TestCase
+{
+ protected $ba;
+
+ protected function setUp()
+ {
+ $this->ba = new BankAccount;
+ }
+
+ /**
+ * @covers BankAccount::getBalance
+ */
+ public function testBalanceIsInitiallyZero()
+ {
+ $this->assertEquals(0, $this->ba->getBalance());
+ }
+
+ /**
+ * @covers BankAccount::withdrawMoney
+ */
+ public function testBalanceCannotBecomeNegative()
+ {
+ try {
+ $this->ba->withdrawMoney(1);
+ } catch (RuntimeException $e) {
+ $this->assertEquals(0, $this->ba->getBalance());
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @covers BankAccount::depositMoney
+ */
+ public function testBalanceCannotBecomeNegative2()
+ {
+ try {
+ $this->ba->depositMoney(-1);
+ } catch (RuntimeException $e) {
+ $this->assertEquals(0, $this->ba->getBalance());
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @covers BankAccount::getBalance
+ * @covers BankAccount::depositMoney
+ * @covers BankAccount::withdrawMoney
+ */
+ public function testDepositWithdrawMoney()
+ {
+ $this->assertEquals(0, $this->ba->getBalance());
+ $this->ba->depositMoney(1);
+ $this->assertEquals(1, $this->ba->getBalance());
+ $this->ba->withdrawMoney(1);
+ $this->assertEquals(0, $this->ba->getBalance());
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageClassExtendedTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageClassExtendedTest.php
new file mode 100644
index 0000000..df12d34
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageClassExtendedTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoverageClassExtendedTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass<extended>
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageClassTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageClassTest.php
new file mode 100644
index 0000000..7f569ae
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageClassTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoverageClassTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionParenthesesTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionParenthesesTest.php
new file mode 100644
index 0000000..33b5fe3
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionParenthesesTest.php
@@ -0,0 +1,11 @@
+<?php
+class CoverageFunctionParenthesesTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers ::globalFunction()
+ */
+ public function testSomething()
+ {
+ globalFunction();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionParenthesesWhitespaceTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionParenthesesWhitespaceTest.php
new file mode 100644
index 0000000..becc6c8
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionParenthesesWhitespaceTest.php
@@ -0,0 +1,11 @@
+<?php
+class CoverageFunctionParenthesesWhitespaceTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers ::globalFunction ( )
+ */
+ public function testSomething()
+ {
+ globalFunction();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionTest.php
new file mode 100644
index 0000000..c621fd2
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionTest.php
@@ -0,0 +1,11 @@
+<?php
+class CoverageFunctionTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers ::globalFunction
+ */
+ public function testSomething()
+ {
+ globalFunction();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodOneLineAnnotationTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodOneLineAnnotationTest.php
new file mode 100644
index 0000000..55d7f57
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodOneLineAnnotationTest.php
@@ -0,0 +1,11 @@
+<?php
+
+class CoverageMethodOneLineAnnotationTest extends PHPUnit_Framework_TestCase
+{
+ /** @covers CoveredClass::publicMethod */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesTest.php
new file mode 100644
index 0000000..4223004
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoverageMethodParenthesesTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::publicMethod()
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesWhitespaceTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesWhitespaceTest.php
new file mode 100644
index 0000000..d1be1c6
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesWhitespaceTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoverageMethodParenthesesWhitespaceTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::publicMethod ( )
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodTest.php
new file mode 100644
index 0000000..167b3db
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoverageMethodTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::publicMethod
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageNoneTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNoneTest.php
new file mode 100644
index 0000000..0b414c2
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNoneTest.php
@@ -0,0 +1,9 @@
+<?php
+class CoverageNoneTest extends PHPUnit_Framework_TestCase
+{
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPrivateTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPrivateTest.php
new file mode 100644
index 0000000..12b56e8
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPrivateTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoverageNotPrivateTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::<!private>
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotProtectedTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotProtectedTest.php
new file mode 100644
index 0000000..c69d261
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotProtectedTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoverageNotProtectedTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::<!protected>
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPublicTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPublicTest.php
new file mode 100644
index 0000000..aebfe4b
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPublicTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoverageNotPublicTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::<!public>
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageNothingTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNothingTest.php
new file mode 100644
index 0000000..5d5680d
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNothingTest.php
@@ -0,0 +1,13 @@
+<?php
+class CoverageNothingTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::publicMethod
+ * @coversNothing
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoveragePrivateTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoveragePrivateTest.php
new file mode 100644
index 0000000..f09560d
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoveragePrivateTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoveragePrivateTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::<private>
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageProtectedTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageProtectedTest.php
new file mode 100644
index 0000000..9b3acbf
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageProtectedTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoverageProtectedTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::<protected>
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoveragePublicTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoveragePublicTest.php
new file mode 100644
index 0000000..480a522
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoveragePublicTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoveragePublicTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::<public>
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageTwoDefaultClassAnnotations.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageTwoDefaultClassAnnotations.php
new file mode 100644
index 0000000..7ffc5c9
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageTwoDefaultClassAnnotations.php
@@ -0,0 +1,18 @@
+<?php
+
+/**
+ * @coversDefaultClass \NamespaceOne
+ * @coversDefaultClass \AnotherDefault\Name\Space\Does\Not\Work
+ */
+class CoverageTwoDefaultClassAnnotations
+{
+ /**
+ * @covers Foo\CoveredClass::<public>
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoveredClass.php b/vendor/phpunit/php-code-coverage/tests/_files/CoveredClass.php
new file mode 100644
index 0000000..f382ce9
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoveredClass.php
@@ -0,0 +1,36 @@
+<?php
+class CoveredParentClass
+{
+ private function privateMethod()
+ {
+ }
+
+ protected function protectedMethod()
+ {
+ $this->privateMethod();
+ }
+
+ public function publicMethod()
+ {
+ $this->protectedMethod();
+ }
+}
+
+class CoveredClass extends CoveredParentClass
+{
+ private function privateMethod()
+ {
+ }
+
+ protected function protectedMethod()
+ {
+ parent::protectedMethod();
+ $this->privateMethod();
+ }
+
+ public function publicMethod()
+ {
+ parent::publicMethod();
+ $this->protectedMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoveredFunction.php b/vendor/phpunit/php-code-coverage/tests/_files/CoveredFunction.php
new file mode 100644
index 0000000..9989eb0
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/CoveredFunction.php
@@ -0,0 +1,4 @@
+<?php
+function globalFunction()
+{
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageClassExtendedTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageClassExtendedTest.php
new file mode 100644
index 0000000..d0954cb
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageClassExtendedTest.php
@@ -0,0 +1,12 @@
+<?php
+class NamespaceCoverageClassExtendedTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Foo\CoveredClass<extended>
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageClassTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageClassTest.php
new file mode 100644
index 0000000..63912c0
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageClassTest.php
@@ -0,0 +1,12 @@
+<?php
+class NamespaceCoverageClassTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Foo\CoveredClass
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassPublicTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassPublicTest.php
new file mode 100644
index 0000000..45f583b
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassPublicTest.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * @coversDefaultClass \Foo\CoveredClass
+ */
+class NamespaceCoverageCoversClassPublicTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers ::publicMethod
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassTest.php
new file mode 100644
index 0000000..b336745
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassTest.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * @coversDefaultClass \Foo\CoveredClass
+ */
+class NamespaceCoverageCoversClassTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers ::privateMethod
+ * @covers ::protectedMethod
+ * @covers ::publicMethod
+ * @covers \Foo\CoveredParentClass::privateMethod
+ * @covers \Foo\CoveredParentClass::protectedMethod
+ * @covers \Foo\CoveredParentClass::publicMethod
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageMethodTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageMethodTest.php
new file mode 100644
index 0000000..35dfb8b
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageMethodTest.php
@@ -0,0 +1,12 @@
+<?php
+class NamespaceCoverageMethodTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Foo\CoveredClass::publicMethod
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPrivateTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPrivateTest.php
new file mode 100644
index 0000000..552c9ec
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPrivateTest.php
@@ -0,0 +1,12 @@
+<?php
+class NamespaceCoverageNotPrivateTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Foo\CoveredClass::<!private>
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotProtectedTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotProtectedTest.php
new file mode 100644
index 0000000..33fc8c7
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotProtectedTest.php
@@ -0,0 +1,12 @@
+<?php
+class NamespaceCoverageNotProtectedTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Foo\CoveredClass::<!protected>
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPublicTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPublicTest.php
new file mode 100644
index 0000000..ccbc500
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPublicTest.php
@@ -0,0 +1,12 @@
+<?php
+class NamespaceCoverageNotPublicTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Foo\CoveredClass::<!public>
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePrivateTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePrivateTest.php
new file mode 100644
index 0000000..cce7ba9
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePrivateTest.php
@@ -0,0 +1,12 @@
+<?php
+class NamespaceCoveragePrivateTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Foo\CoveredClass::<private>
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageProtectedTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageProtectedTest.php
new file mode 100644
index 0000000..dbbcc1c
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageProtectedTest.php
@@ -0,0 +1,12 @@
+<?php
+class NamespaceCoverageProtectedTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Foo\CoveredClass::<protected>
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePublicTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePublicTest.php
new file mode 100644
index 0000000..bf1bff8
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePublicTest.php
@@ -0,0 +1,12 @@
+<?php
+class NamespaceCoveragePublicTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Foo\CoveredClass::<public>
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveredClass.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveredClass.php
new file mode 100644
index 0000000..5bd0ddf
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveredClass.php
@@ -0,0 +1,38 @@
+<?php
+namespace Foo;
+
+class CoveredParentClass
+{
+ private function privateMethod()
+ {
+ }
+
+ protected function protectedMethod()
+ {
+ $this->privateMethod();
+ }
+
+ public function publicMethod()
+ {
+ $this->protectedMethod();
+ }
+}
+
+class CoveredClass extends CoveredParentClass
+{
+ private function privateMethod()
+ {
+ }
+
+ protected function protectedMethod()
+ {
+ parent::protectedMethod();
+ $this->privateMethod();
+ }
+
+ public function publicMethod()
+ {
+ parent::publicMethod();
+ $this->protectedMethod();
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NotExistingCoveredElementTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NotExistingCoveredElementTest.php
new file mode 100644
index 0000000..be07ef4
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/NotExistingCoveredElementTest.php
@@ -0,0 +1,24 @@
+<?php
+class NotExistingCoveredElementTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers NotExistingClass
+ */
+ public function testOne()
+ {
+ }
+
+ /**
+ * @covers NotExistingClass::notExistingMethod
+ */
+ public function testTwo()
+ {
+ }
+
+ /**
+ * @covers NotExistingClass::<public>
+ */
+ public function testThree()
+ {
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html
new file mode 100644
index 0000000..819a4a3
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html
@@ -0,0 +1,267 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <title>Code Coverage for %s/BankAccount.php</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link href="css/bootstrap.min.css" rel="stylesheet">
+ <link href="css/style.css" rel="stylesheet">
+ <!--[if lt IE 9]>
+ <script src="js/html5shiv.min.js"></script>
+ <script src="js/respond.min.js"></script>
+ <![endif]-->
+ </head>
+ <body>
+ <header>
+ <div class="container">
+ <div class="row">
+ <div class="col-md-12">
+ <ol class="breadcrumb">
+ <li><a href="index.html">%s</a></li>
+ <li class="active">BankAccount.php</li>
+
+ </ol>
+ </div>
+ </div>
+ </div>
+ </header>
+ <div class="container">
+ <table class="table table-bordered">
+ <thead>
+ <tr>
+ <td>&nbsp;</td>
+ <td colspan="10"><div align="center"><strong>Code Coverage</strong></div></td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
+ <td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
+ <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td class="danger">Total</td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="0.00" aria-valuemin="0" aria-valuemax="100" style="width: 0.00%">
+ <span class="sr-only">0.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">0.00%</div></td>
+ <td class="danger small"><div align="right">0&nbsp;/&nbsp;1</div></td>
+ <td class="warning big"> <div class="progress">
+ <div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="75.00" aria-valuemin="0" aria-valuemax="100" style="width: 75.00%">
+ <span class="sr-only">75.00% covered (warning)</span>
+ </div>
+ </div>
+</td>
+ <td class="warning small"><div align="right">75.00%</div></td>
+ <td class="warning small"><div align="right">3&nbsp;/&nbsp;4</div></td>
+ <td class="warning small"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="50.00" aria-valuemin="0" aria-valuemax="100" style="width: 50.00%">
+ <span class="sr-only">50.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">50.00%</div></td>
+ <td class="danger small"><div align="right">5&nbsp;/&nbsp;10</div></td>
+ </tr>
+
+ <tr>
+ <td class="danger">BankAccount</td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="0.00" aria-valuemin="0" aria-valuemax="100" style="width: 0.00%">
+ <span class="sr-only">0.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">0.00%</div></td>
+ <td class="danger small"><div align="right">0&nbsp;/&nbsp;1</div></td>
+ <td class="warning big"> <div class="progress">
+ <div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="75.00" aria-valuemin="0" aria-valuemax="100" style="width: 75.00%">
+ <span class="sr-only">75.00% covered (warning)</span>
+ </div>
+ </div>
+</td>
+ <td class="warning small"><div align="right">75.00%</div></td>
+ <td class="warning small"><div align="right">3&nbsp;/&nbsp;4</div></td>
+ <td class="warning small">8.12</td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="50.00" aria-valuemin="0" aria-valuemax="100" style="width: 50.00%">
+ <span class="sr-only">50.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">50.00%</div></td>
+ <td class="danger small"><div align="right">5&nbsp;/&nbsp;10</div></td>
+ </tr>
+
+ <tr>
+ <td class="success" colspan="4">&nbsp;<a href="#6"><abbr title="getBalance()">getBalance</abbr></a></td>
+ <td class="success big"> <div class="progress">
+ <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
+ <span class="sr-only">100.00% covered (success)</span>
+ </div>
+ </div>
+</td>
+ <td class="success small"><div align="right">100.00%</div></td>
+ <td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
+ <td class="success small">1</td>
+ <td class="success big"> <div class="progress">
+ <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
+ <span class="sr-only">100.00% covered (success)</span>
+ </div>
+ </div>
+</td>
+ <td class="success small"><div align="right">100.00%</div></td>
+ <td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
+ </tr>
+
+ <tr>
+ <td class="danger" colspan="4">&nbsp;<a href="#11"><abbr title="setBalance($balance)">setBalance</abbr></a></td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="0.00" aria-valuemin="0" aria-valuemax="100" style="width: 0.00%">
+ <span class="sr-only">0.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">0.00%</div></td>
+ <td class="danger small"><div align="right">0&nbsp;/&nbsp;1</div></td>
+ <td class="danger small">6</td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="0.00" aria-valuemin="0" aria-valuemax="100" style="width: 0.00%">
+ <span class="sr-only">0.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">0.00%</div></td>
+ <td class="danger small"><div align="right">0&nbsp;/&nbsp;5</div></td>
+ </tr>
+
+ <tr>
+ <td class="success" colspan="4">&nbsp;<a href="#20"><abbr title="depositMoney($balance)">depositMoney</abbr></a></td>
+ <td class="success big"> <div class="progress">
+ <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
+ <span class="sr-only">100.00% covered (success)</span>
+ </div>
+ </div>
+</td>
+ <td class="success small"><div align="right">100.00%</div></td>
+ <td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
+ <td class="success small">1</td>
+ <td class="success big"> <div class="progress">
+ <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
+ <span class="sr-only">100.00% covered (success)</span>
+ </div>
+ </div>
+</td>
+ <td class="success small"><div align="right">100.00%</div></td>
+ <td class="success small"><div align="right">2&nbsp;/&nbsp;2</div></td>
+ </tr>
+
+ <tr>
+ <td class="success" colspan="4">&nbsp;<a href="#27"><abbr title="withdrawMoney($balance)">withdrawMoney</abbr></a></td>
+ <td class="success big"> <div class="progress">
+ <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
+ <span class="sr-only">100.00% covered (success)</span>
+ </div>
+ </div>
+</td>
+ <td class="success small"><div align="right">100.00%</div></td>
+ <td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
+ <td class="success small">1</td>
+ <td class="success big"> <div class="progress">
+ <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
+ <span class="sr-only">100.00% covered (success)</span>
+ </div>
+ </div>
+</td>
+ <td class="success small"><div align="right">100.00%</div></td>
+ <td class="success small"><div align="right">2&nbsp;/&nbsp;2</div></td>
+ </tr>
+
+
+ </tbody>
+ </table>
+ <table id="code" class="table table-borderless table-condensed">
+ <tbody>
+ <tr><td><div align="right"><a name="1"></a><a href="#1">1</a></div></td><td class="codeLine"><span class="default">&lt;?php</span></td></tr>
+ <tr><td><div align="right"><a name="2"></a><a href="#2">2</a></div></td><td class="codeLine"><span class="keyword">class</span><span class="default">&nbsp;</span><span class="default">BankAccount</span></td></tr>
+ <tr><td><div align="right"><a name="3"></a><a href="#3">3</a></div></td><td class="codeLine"><span class="keyword">{</span></td></tr>
+ <tr><td><div align="right"><a name="4"></a><a href="#4">4</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">protected</span><span class="default">&nbsp;</span><span class="default">$balance</span><span class="default">&nbsp;</span><span class="keyword">=</span><span class="default">&nbsp;</span><span class="default">0</span><span class="keyword">;</span></td></tr>
+ <tr><td><div align="right"><a name="5"></a><a href="#5">5</a></div></td><td class="codeLine"></td></tr>
+ <tr><td><div align="right"><a name="6"></a><a href="#6">6</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span class="default">&nbsp;</span><span class="keyword">function</span><span class="default">&nbsp;</span><span class="default">getBalance</span><span class="keyword">(</span><span class="keyword">)</span></td></tr>
+ <tr><td><div align="right"><a name="7"></a><a href="#7">7</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">{</span></td></tr>
+ <tr class="covered-by-large-tests popin" data-title="2 tests cover line 8" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;BankAccountTest::testBalanceIsInitiallyZero&lt;/li&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;BankAccountTest::testDepositWithdrawMoney&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="8"></a><a href="#8">8</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">$this</span><span class="default">-&gt;</span><span class="default">balance</span><span class="keyword">;</span></td></tr>
+ <tr class="warning"><td><div align="right"><a name="9"></a><a href="#9">9</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
+ <tr><td><div align="right"><a name="10"></a><a href="#10">10</a></div></td><td class="codeLine"></td></tr>
+ <tr><td><div align="right"><a name="11"></a><a href="#11">11</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">protected</span><span class="default">&nbsp;</span><span class="keyword">function</span><span class="default">&nbsp;</span><span class="default">setBalance</span><span class="keyword">(</span><span class="default">$balance</span><span class="keyword">)</span></td></tr>
+ <tr><td><div align="right"><a name="12"></a><a href="#12">12</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">{</span></td></tr>
+ <tr class="danger"><td><div align="right"><a name="13"></a><a href="#13">13</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span class="default">&nbsp;</span><span class="keyword">(</span><span class="default">$balance</span><span class="default">&nbsp;</span><span class="default">&gt;=</span><span class="default">&nbsp;</span><span class="default">0</span><span class="keyword">)</span><span class="default">&nbsp;</span><span class="keyword">{</span></td></tr>
+ <tr class="danger"><td><div align="right"><a name="14"></a><a href="#14">14</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$this</span><span class="default">-&gt;</span><span class="default">balance</span><span class="default">&nbsp;</span><span class="keyword">=</span><span class="default">&nbsp;</span><span class="default">$balance</span><span class="keyword">;</span></td></tr>
+ <tr class="danger"><td><div align="right"><a name="15"></a><a href="#15">15</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">}</span><span class="default">&nbsp;</span><span class="keyword">else</span><span class="default">&nbsp;</span><span class="keyword">{</span></td></tr>
+ <tr class="danger"><td><div align="right"><a name="16"></a><a href="#16">16</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">throw</span><span class="default">&nbsp;</span><span class="keyword">new</span><span class="default">&nbsp;</span><span class="default">RuntimeException</span><span class="keyword">;</span></td></tr>
+ <tr><td><div align="right"><a name="17"></a><a href="#17">17</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
+ <tr class="danger"><td><div align="right"><a name="18"></a><a href="#18">18</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
+ <tr><td><div align="right"><a name="19"></a><a href="#19">19</a></div></td><td class="codeLine"></td></tr>
+ <tr><td><div align="right"><a name="20"></a><a href="#20">20</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span class="default">&nbsp;</span><span class="keyword">function</span><span class="default">&nbsp;</span><span class="default">depositMoney</span><span class="keyword">(</span><span class="default">$balance</span><span class="keyword">)</span></td></tr>
+ <tr><td><div align="right"><a name="21"></a><a href="#21">21</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">{</span></td></tr>
+ <tr class="covered-by-large-tests popin" data-title="2 tests cover line 22" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;BankAccountTest::testBalanceCannotBecomeNegative2&lt;/li&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;BankAccountTest::testDepositWithdrawMoney&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="22"></a><a href="#22">22</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$this</span><span class="default">-&gt;</span><span class="default">setBalance</span><span class="keyword">(</span><span class="default">$this</span><span class="default">-&gt;</span><span class="default">getBalance</span><span class="keyword">(</span><span class="keyword">)</span><span class="default">&nbsp;</span><span class="keyword">+</span><span class="default">&nbsp;</span><span class="default">$balance</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
+ <tr><td><div align="right"><a name="23"></a><a href="#23">23</a></div></td><td class="codeLine"></td></tr>
+ <tr class="covered-by-large-tests popin" data-title="1 test covers line 24" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;BankAccountTest::testDepositWithdrawMoney&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="24"></a><a href="#24">24</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">$this</span><span class="default">-&gt;</span><span class="default">getBalance</span><span class="keyword">(</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
+ <tr class="warning"><td><div align="right"><a name="25"></a><a href="#25">25</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
+ <tr><td><div align="right"><a name="26"></a><a href="#26">26</a></div></td><td class="codeLine"></td></tr>
+ <tr><td><div align="right"><a name="27"></a><a href="#27">27</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span class="default">&nbsp;</span><span class="keyword">function</span><span class="default">&nbsp;</span><span class="default">withdrawMoney</span><span class="keyword">(</span><span class="default">$balance</span><span class="keyword">)</span></td></tr>
+ <tr><td><div align="right"><a name="28"></a><a href="#28">28</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">{</span></td></tr>
+ <tr class="covered-by-large-tests popin" data-title="2 tests cover line 29" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;BankAccountTest::testBalanceCannotBecomeNegative&lt;/li&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;BankAccountTest::testDepositWithdrawMoney&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="29"></a><a href="#29">29</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$this</span><span class="default">-&gt;</span><span class="default">setBalance</span><span class="keyword">(</span><span class="default">$this</span><span class="default">-&gt;</span><span class="default">getBalance</span><span class="keyword">(</span><span class="keyword">)</span><span class="default">&nbsp;</span><span class="keyword">-</span><span class="default">&nbsp;</span><span class="default">$balance</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
+ <tr><td><div align="right"><a name="30"></a><a href="#30">30</a></div></td><td class="codeLine"></td></tr>
+ <tr class="covered-by-large-tests popin" data-title="1 test covers line 31" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;BankAccountTest::testDepositWithdrawMoney&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="31"></a><a href="#31">31</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span class="default">&nbsp;</span><span class="default">$this</span><span class="default">-&gt;</span><span class="default">getBalance</span><span class="keyword">(</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
+ <tr class="warning"><td><div align="right"><a name="32"></a><a href="#32">32</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
+ <tr><td><div align="right"><a name="33"></a><a href="#33">33</a></div></td><td class="codeLine"><span class="keyword">}</span></td></tr>
+
+ </tbody>
+ </table>
+ <footer>
+ <hr/>
+ <h4>Legend</h4>
+ <p>
+ <span class="success"><strong>Executed</strong></span>
+ <span class="danger"><strong>Not Executed</strong></span>
+ <span class="warning"><strong>Dead Code</strong></span>
+ </p>
+ <p>
+ <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="%s" target="_top">%s</a> at %s.</small>
+ </p>
+ <a title="Back to the top" id="toplink" href="#"><span class="glyphicon glyphicon-arrow-up"></span></a>
+ </footer>
+ </div>
+ <script src="js/jquery.min.js" type="text/javascript"></script>
+ <script src="js/bootstrap.min.js" type="text/javascript"></script>
+ <script src="js/holder.min.js" type="text/javascript"></script>
+ <script type="text/javascript">
+ $(function() {
+ var $window = $(window)
+ , $top_link = $('#toplink')
+ , $body = $('body, html')
+ , offset = $('#code').offset().top;
+
+ $top_link.hide().click(function(event) {
+ event.preventDefault();
+ $body.animate({scrollTop:0}, 800);
+ });
+
+ $window.scroll(function() {
+ if($window.scrollTop() > offset) {
+ $top_link.fadeIn();
+ } else {
+ $top_link.fadeOut();
+ }
+ }).scroll();
+
+ $('.popin').popover({trigger: 'hover'});
+ });
+ </script>
+ </body>
+</html>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/dashboard.html b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/dashboard.html
new file mode 100644
index 0000000..11f9a1e
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/dashboard.html
@@ -0,0 +1,290 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <title>Dashboard for %s</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link href="css/bootstrap.min.css" rel="stylesheet">
+ <link href="css/nv.d3.min.css" rel="stylesheet">
+ <link href="css/style.css" rel="stylesheet">
+ <!--[if lt IE 9]>
+ <script src="js/html5shiv.min.js"></script>
+ <script src="js/respond.min.js"></script>
+ <![endif]-->
+ </head>
+ <body>
+ <header>
+ <div class="container">
+ <div class="row">
+ <div class="col-md-12">
+ <ol class="breadcrumb">
+ <li><a href="index.html">%s</a></li>
+ <li class="active">(Dashboard)</li>
+
+ </ol>
+ </div>
+ </div>
+ </div>
+ </header>
+ <div class="container">
+ <div class="row">
+ <div class="col-md-12">
+ <h2>Classes</h2>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <h3>Coverage Distribution</h3>
+ <div id="classCoverageDistribution" style="height: 300px;">
+ <svg></svg>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <h3>Complexity</h3>
+ <div id="classComplexity" style="height: 300px;">
+ <svg></svg>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <h3>Insufficient Coverage</h3>
+ <div class="scrollbox">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Class</th>
+ <th class="text-right">Coverage</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr><td><a href="BankAccount.php.html#2">BankAccount</a></td><td class="text-right">50%</td></tr>
+
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <h3>Project Risks</h3>
+ <div class="scrollbox">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Class</th>
+ <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr><td><a href="BankAccount.php.html#2">BankAccount</a></td><td class="text-right">8</td></tr>
+
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-12">
+ <h2>Methods</h2>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <h3>Coverage Distribution</h3>
+ <div id="methodCoverageDistribution" style="height: 300px;">
+ <svg></svg>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <h3>Complexity</h3>
+ <div id="methodComplexity" style="height: 300px;">
+ <svg></svg>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <h3>Insufficient Coverage</h3>
+ <div class="scrollbox">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Method</th>
+ <th class="text-right">Coverage</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr><td><a href="BankAccount.php.html#11"><abbr title="BankAccount::setBalance">setBalance</abbr></a></td><td class="text-right">0%</td></tr>
+
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <h3>Project Risks</h3>
+ <div class="scrollbox">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Method</th>
+ <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr><td><a href="BankAccount.php.html#11"><abbr title="BankAccount::setBalance">setBalance</abbr></a></td><td class="text-right">6</td></tr>
+
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ <footer>
+ <hr/>
+ <p>
+ <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="%s" target="_top">%s</a> at %s.</small>
+ </p>
+ </footer>
+ </div>
+ <script src="js/jquery.min.js" type="text/javascript"></script>
+ <script src="js/bootstrap.min.js" type="text/javascript"></script>
+ <script src="js/holder.min.js" type="text/javascript"></script>
+ <script src="js/d3.min.js" type="text/javascript"></script>
+ <script src="js/nv.d3.min.js" type="text/javascript"></script>
+ <script type="text/javascript">
+$(document).ready(function() {
+ nv.addGraph(function() {
+ var chart = nv.models.multiBarChart();
+ chart.tooltips(false)
+ .showControls(false)
+ .showLegend(false)
+ .reduceXTicks(false)
+ .staggerLabels(true)
+ .yAxis.tickFormat(d3.format('d'));
+
+ d3.select('#classCoverageDistribution svg')
+ .datum(getCoverageDistributionData([0,0,0,0,0,0,1,0,0,0,0,0], "Class Coverage"))
+ .transition().duration(500).call(chart);
+
+ nv.utils.windowResize(chart.update);
+
+ return chart;
+ });
+
+ nv.addGraph(function() {
+ var chart = nv.models.multiBarChart();
+ chart.tooltips(false)
+ .showControls(false)
+ .showLegend(false)
+ .reduceXTicks(false)
+ .staggerLabels(true)
+ .yAxis.tickFormat(d3.format('d'));
+
+ d3.select('#methodCoverageDistribution svg')
+ .datum(getCoverageDistributionData([1,0,0,0,0,0,0,0,0,0,0,3], "Method Coverage"))
+ .transition().duration(500).call(chart);
+
+ nv.utils.windowResize(chart.update);
+
+ return chart;
+ });
+
+ function getCoverageDistributionData(data, label) {
+ var labels = [
+ '0%',
+ '0-10%',
+ '10-20%',
+ '20-30%',
+ '30-40%',
+ '40-50%',
+ '50-60%',
+ '60-70%',
+ '70-80%',
+ '80-90%',
+ '90-100%',
+ '100%'
+ ];
+ var values = [];
+ $.each(labels, function(key) {
+ values.push({x: labels[key], y: data[key]});
+ });
+
+ return [
+ {
+ key: label,
+ values: values,
+ color: "#4572A7"
+ }
+ ];
+ }
+ nv.addGraph(function() {
+ var chart = nv.models.scatterChart()
+ .showDistX(true)
+ .showDistY(true)
+ .showLegend(false)
+ .forceX([0, 100]);
+ chart.tooltipContent(function(graph) {
+ return '<p>' + graph.point.class + '</p>';
+ });
+
+ chart.xAxis.axisLabel('Code Coverage (in percent)');
+ chart.yAxis.axisLabel('Cyclomatic Complexity');
+
+ d3.select('#classComplexity svg')
+ .datum(getComplexityData([[50,5,"<a href=\"BankAccount.php.html#2\">BankAccount<\/a>"]], 'Class Complexity'))
+ .transition()
+ .duration(500)
+ .call(chart);
+
+ nv.utils.windowResize(chart.update);
+
+ return chart;
+ });
+
+ nv.addGraph(function() {
+ var chart = nv.models.scatterChart()
+ .showDistX(true)
+ .showDistY(true)
+ .showLegend(false)
+ .forceX([0, 100]);
+ chart.tooltipContent(function(graph) {
+ return '<p>' + graph.point.class + '</p>';
+ });
+
+ chart.xAxis.axisLabel('Code Coverage (in percent)');
+ chart.yAxis.axisLabel('Method Complexity');
+
+ d3.select('#methodComplexity svg')
+ .datum(getComplexityData([[100,1,"<a href=\"BankAccount.php.html#6\">BankAccount::getBalance<\/a>"],[0,2,"<a href=\"BankAccount.php.html#11\">BankAccount::setBalance<\/a>"],[100,1,"<a href=\"BankAccount.php.html#20\">BankAccount::depositMoney<\/a>"],[100,1,"<a href=\"BankAccount.php.html#27\">BankAccount::withdrawMoney<\/a>"]], 'Method Complexity'))
+ .transition()
+ .duration(500)
+ .call(chart);
+
+ nv.utils.windowResize(chart.update);
+
+ return chart;
+ });
+
+ function getComplexityData(data, label) {
+ var values = [];
+ $.each(data, function(key) {
+ var value = Math.round(data[key][0]*100) / 100;
+ values.push({
+ x: value,
+ y: data[key][1],
+ class: data[key][2],
+ size: 0.05,
+ shape: 'diamond'
+ });
+ });
+
+ return [
+ {
+ key: label,
+ values: values,
+ color: "#4572A7"
+ }
+ ];
+ }
+});
+ </script>
+ </body>
+</html>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/index.html b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/index.html
new file mode 100644
index 0000000..ba6ce68
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/index.html
@@ -0,0 +1,119 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <title>Code Coverage for %s</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link href="css/bootstrap.min.css" rel="stylesheet">
+ <link href="css/style.css" rel="stylesheet">
+ <!--[if lt IE 9]>
+ <script src="js/html5shiv.min.js"></script>
+ <script src="js/respond.min.js"></script>
+ <![endif]-->
+ </head>
+ <body>
+ <header>
+ <div class="container">
+ <div class="row">
+ <div class="col-md-12">
+ <ol class="breadcrumb">
+ <li class="active">%s</li>
+ <li>(<a href="dashboard.html">Dashboard</a>)</li>
+
+ </ol>
+ </div>
+ </div>
+ </div>
+ </header>
+ <div class="container">
+ <table class="table table-bordered">
+ <thead>
+ <tr>
+ <td>&nbsp;</td>
+ <td colspan="9"><div align="center"><strong>Code Coverage</strong></div></td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
+ <td colspan="3"><div align="center"><strong>Functions and Methods</strong></div></td>
+ <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td class="danger">Total</td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="50.00" aria-valuemin="0" aria-valuemax="100" style="width: 50.00%">
+ <span class="sr-only">50.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">50.00%</div></td>
+ <td class="danger small"><div align="right">5&nbsp;/&nbsp;10</div></td>
+ <td class="warning big"> <div class="progress">
+ <div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="75.00" aria-valuemin="0" aria-valuemax="100" style="width: 75.00%">
+ <span class="sr-only">75.00% covered (warning)</span>
+ </div>
+ </div>
+</td>
+ <td class="warning small"><div align="right">75.00%</div></td>
+ <td class="warning small"><div align="right">3&nbsp;/&nbsp;4</div></td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="0.00" aria-valuemin="0" aria-valuemax="100" style="width: 0.00%">
+ <span class="sr-only">0.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">0.00%</div></td>
+ <td class="danger small"><div align="right">0&nbsp;/&nbsp;1</div></td>
+ </tr>
+
+ <tr>
+ <td class="danger"><span class="glyphicon glyphicon-file"></span> <a href="BankAccount.php.html">BankAccount.php</a></td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="50.00" aria-valuemin="0" aria-valuemax="100" style="width: 50.00%">
+ <span class="sr-only">50.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">50.00%</div></td>
+ <td class="danger small"><div align="right">5&nbsp;/&nbsp;10</div></td>
+ <td class="warning big"> <div class="progress">
+ <div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="75.00" aria-valuemin="0" aria-valuemax="100" style="width: 75.00%">
+ <span class="sr-only">75.00% covered (warning)</span>
+ </div>
+ </div>
+</td>
+ <td class="warning small"><div align="right">75.00%</div></td>
+ <td class="warning small"><div align="right">3&nbsp;/&nbsp;4</div></td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="0.00" aria-valuemin="0" aria-valuemax="100" style="width: 0.00%">
+ <span class="sr-only">0.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">0.00%</div></td>
+ <td class="danger small"><div align="right">0&nbsp;/&nbsp;1</div></td>
+ </tr>
+
+
+ </tbody>
+ </table>
+ <footer>
+ <hr/>
+ <h4>Legend</h4>
+ <p>
+ <span class="danger"><strong>Low</strong>: 0% to 50%</span>
+ <span class="warning"><strong>Medium</strong>: 50% to 90%</span>
+ <span class="success"><strong>High</strong>: 90% to 100%</span>
+ </p>
+ <p>
+ <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="%s" target="_top">%s</a> at %s.</small>
+ </p>
+ </footer>
+ </div>
+ <script src="js/jquery.min.js" type="text/javascript"></script>
+ <script src="js/bootstrap.min.js" type="text/javascript"></script>
+ <script src="js/holder.min.js" type="text/javascript"></script>
+ </body>
+</html>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/dashboard.html b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/dashboard.html
new file mode 100644
index 0000000..4b2adac
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/dashboard.html
@@ -0,0 +1,288 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <title>Dashboard for %s</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link href="css/bootstrap.min.css" rel="stylesheet">
+ <link href="css/nv.d3.min.css" rel="stylesheet">
+ <link href="css/style.css" rel="stylesheet">
+ <!--[if lt IE 9]>
+ <script src="js/html5shiv.min.js"></script>
+ <script src="js/respond.min.js"></script>
+ <![endif]-->
+ </head>
+ <body>
+ <header>
+ <div class="container">
+ <div class="row">
+ <div class="col-md-12">
+ <ol class="breadcrumb">
+ <li><a href="index.html">%s</a></li>
+ <li class="active">(Dashboard)</li>
+
+ </ol>
+ </div>
+ </div>
+ </div>
+ </header>
+ <div class="container">
+ <div class="row">
+ <div class="col-md-12">
+ <h2>Classes</h2>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <h3>Coverage Distribution</h3>
+ <div id="classCoverageDistribution" style="height: 300px;">
+ <svg></svg>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <h3>Complexity</h3>
+ <div id="classComplexity" style="height: 300px;">
+ <svg></svg>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <h3>Insufficient Coverage</h3>
+ <div class="scrollbox">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Class</th>
+ <th class="text-right">Coverage</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr><td><a href="source_with_class_and_anonymous_function.php.html#3">CoveredClassWithAnonymousFunctionInStaticMethod</a></td><td class="text-right">87%</td></tr>
+
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <h3>Project Risks</h3>
+ <div class="scrollbox">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Class</th>
+ <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
+ </tr>
+ </thead>
+ <tbody>
+
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-12">
+ <h2>Methods</h2>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <h3>Coverage Distribution</h3>
+ <div id="methodCoverageDistribution" style="height: 300px;">
+ <svg></svg>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <h3>Complexity</h3>
+ <div id="methodComplexity" style="height: 300px;">
+ <svg></svg>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <h3>Insufficient Coverage</h3>
+ <div class="scrollbox">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Method</th>
+ <th class="text-right">Coverage</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr><td><a href="source_with_class_and_anonymous_function.php.html#5"><abbr title="CoveredClassWithAnonymousFunctionInStaticMethod::runAnonymous">runAnonymous</abbr></a></td><td class="text-right">66%</td></tr>
+
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <h3>Project Risks</h3>
+ <div class="scrollbox">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Method</th>
+ <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
+ </tr>
+ </thead>
+ <tbody>
+
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ <footer>
+ <hr/>
+ <p>
+ <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="%s" target="_top">%s</a> at %s.</small>
+ </p>
+ </footer>
+ </div>
+ <script src="js/jquery.min.js" type="text/javascript"></script>
+ <script src="js/bootstrap.min.js" type="text/javascript"></script>
+ <script src="js/holder.min.js" type="text/javascript"></script>
+ <script src="js/d3.min.js" type="text/javascript"></script>
+ <script src="js/nv.d3.min.js" type="text/javascript"></script>
+ <script type="text/javascript">
+$(document).ready(function() {
+ nv.addGraph(function() {
+ var chart = nv.models.multiBarChart();
+ chart.tooltips(false)
+ .showControls(false)
+ .showLegend(false)
+ .reduceXTicks(false)
+ .staggerLabels(true)
+ .yAxis.tickFormat(d3.format('d'));
+
+ d3.select('#classCoverageDistribution svg')
+ .datum(getCoverageDistributionData([0,0,0,0,0,0,0,0,0,1,0,0], "Class Coverage"))
+ .transition().duration(500).call(chart);
+
+ nv.utils.windowResize(chart.update);
+
+ return chart;
+ });
+
+ nv.addGraph(function() {
+ var chart = nv.models.multiBarChart();
+ chart.tooltips(false)
+ .showControls(false)
+ .showLegend(false)
+ .reduceXTicks(false)
+ .staggerLabels(true)
+ .yAxis.tickFormat(d3.format('d'));
+
+ d3.select('#methodCoverageDistribution svg')
+ .datum(getCoverageDistributionData([0,0,0,0,0,0,0,1,0,0,0,1], "Method Coverage"))
+ .transition().duration(500).call(chart);
+
+ nv.utils.windowResize(chart.update);
+
+ return chart;
+ });
+
+ function getCoverageDistributionData(data, label) {
+ var labels = [
+ '0%',
+ '0-10%',
+ '10-20%',
+ '20-30%',
+ '30-40%',
+ '40-50%',
+ '50-60%',
+ '60-70%',
+ '70-80%',
+ '80-90%',
+ '90-100%',
+ '100%'
+ ];
+ var values = [];
+ $.each(labels, function(key) {
+ values.push({x: labels[key], y: data[key]});
+ });
+
+ return [
+ {
+ key: label,
+ values: values,
+ color: "#4572A7"
+ }
+ ];
+ }
+ nv.addGraph(function() {
+ var chart = nv.models.scatterChart()
+ .showDistX(true)
+ .showDistY(true)
+ .showLegend(false)
+ .forceX([0, 100]);
+ chart.tooltipContent(function(graph) {
+ return '<p>' + graph.point.class + '</p>';
+ });
+
+ chart.xAxis.axisLabel('Code Coverage (in percent)');
+ chart.yAxis.axisLabel('Cyclomatic Complexity');
+
+ d3.select('#classComplexity svg')
+ .datum(getComplexityData([[87.5,2,"<a href=\"source_with_class_and_anonymous_function.php.html#3\">CoveredClassWithAnonymousFunctionInStaticMethod<\/a>"]], 'Class Complexity'))
+ .transition()
+ .duration(500)
+ .call(chart);
+
+ nv.utils.windowResize(chart.update);
+
+ return chart;
+ });
+
+ nv.addGraph(function() {
+ var chart = nv.models.scatterChart()
+ .showDistX(true)
+ .showDistY(true)
+ .showLegend(false)
+ .forceX([0, 100]);
+ chart.tooltipContent(function(graph) {
+ return '<p>' + graph.point.class + '</p>';
+ });
+
+ chart.xAxis.axisLabel('Code Coverage (in percent)');
+ chart.yAxis.axisLabel('Method Complexity');
+
+ d3.select('#methodComplexity svg')
+ .datum(getComplexityData([[66.666666666667,1,"<a href=\"source_with_class_and_anonymous_function.php.html#5\">CoveredClassWithAnonymousFunctionInStaticMethod::runAnonymous<\/a>"],[100,1,"<a href=\"source_with_class_and_anonymous_function.php.html#11\">CoveredClassWithAnonymousFunctionInStaticMethod::anonymous function<\/a>"]], 'Method Complexity'))
+ .transition()
+ .duration(500)
+ .call(chart);
+
+ nv.utils.windowResize(chart.update);
+
+ return chart;
+ });
+
+ function getComplexityData(data, label) {
+ var values = [];
+ $.each(data, function(key) {
+ var value = Math.round(data[key][0]*100) / 100;
+ values.push({
+ x: value,
+ y: data[key][1],
+ class: data[key][2],
+ size: 0.05,
+ shape: 'diamond'
+ });
+ });
+
+ return [
+ {
+ key: label,
+ values: values,
+ color: "#4572A7"
+ }
+ ];
+ }
+});
+ </script>
+ </body>
+</html>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html
new file mode 100644
index 0000000..ae3368b
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html
@@ -0,0 +1,119 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <title>Code Coverage for %s</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link href="css/bootstrap.min.css" rel="stylesheet">
+ <link href="css/style.css" rel="stylesheet">
+ <!--[if lt IE 9]>
+ <script src="js/html5shiv.min.js"></script>
+ <script src="js/respond.min.js"></script>
+ <![endif]-->
+ </head>
+ <body>
+ <header>
+ <div class="container">
+ <div class="row">
+ <div class="col-md-12">
+ <ol class="breadcrumb">
+ <li class="active">%s</li>
+ <li>(<a href="dashboard.html">Dashboard</a>)</li>
+
+ </ol>
+ </div>
+ </div>
+ </div>
+ </header>
+ <div class="container">
+ <table class="table table-bordered">
+ <thead>
+ <tr>
+ <td>&nbsp;</td>
+ <td colspan="9"><div align="center"><strong>Code Coverage</strong></div></td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
+ <td colspan="3"><div align="center"><strong>Functions and Methods</strong></div></td>
+ <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td class="warning">Total</td>
+ <td class="warning big"> <div class="progress">
+ <div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="87.50" aria-valuemin="0" aria-valuemax="100" style="width: 87.50%">
+ <span class="sr-only">87.50% covered (warning)</span>
+ </div>
+ </div>
+</td>
+ <td class="warning small"><div align="right">87.50%</div></td>
+ <td class="warning small"><div align="right">7&nbsp;/&nbsp;8</div></td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="50.00" aria-valuemin="0" aria-valuemax="100" style="width: 50.00%">
+ <span class="sr-only">50.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">50.00%</div></td>
+ <td class="danger small"><div align="right">1&nbsp;/&nbsp;2</div></td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="0.00" aria-valuemin="0" aria-valuemax="100" style="width: 0.00%">
+ <span class="sr-only">0.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">0.00%</div></td>
+ <td class="danger small"><div align="right">0&nbsp;/&nbsp;1</div></td>
+ </tr>
+
+ <tr>
+ <td class="warning"><span class="glyphicon glyphicon-file"></span> <a href="source_with_class_and_anonymous_function.php.html">source_with_class_and_anonymous_function.php</a></td>
+ <td class="warning big"> <div class="progress">
+ <div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="87.50" aria-valuemin="0" aria-valuemax="100" style="width: 87.50%">
+ <span class="sr-only">87.50% covered (warning)</span>
+ </div>
+ </div>
+</td>
+ <td class="warning small"><div align="right">87.50%</div></td>
+ <td class="warning small"><div align="right">7&nbsp;/&nbsp;8</div></td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="50.00" aria-valuemin="0" aria-valuemax="100" style="width: 50.00%">
+ <span class="sr-only">50.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">50.00%</div></td>
+ <td class="danger small"><div align="right">1&nbsp;/&nbsp;2</div></td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="0.00" aria-valuemin="0" aria-valuemax="100" style="width: 0.00%">
+ <span class="sr-only">0.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">0.00%</div></td>
+ <td class="danger small"><div align="right">0&nbsp;/&nbsp;1</div></td>
+ </tr>
+
+
+ </tbody>
+ </table>
+ <footer>
+ <hr/>
+ <h4>Legend</h4>
+ <p>
+ <span class="danger"><strong>Low</strong>: 0% to 50%</span>
+ <span class="warning"><strong>Medium</strong>: 50% to 90%</span>
+ <span class="success"><strong>High</strong>: 90% to 100%</span>
+ </p>
+ <p>
+ <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="%s" target="_top">%s</a> at %s.</small>
+ </p>
+ </footer>
+ </div>
+ <script src="js/jquery.min.js" type="text/javascript"></script>
+ <script src="js/bootstrap.min.js" type="text/javascript"></script>
+ <script src="js/holder.min.js" type="text/javascript"></script>
+ </body>
+</html>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html
new file mode 100644
index 0000000..6165fc1
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <title>Code Coverage for %s/source_with_class_and_anonymous_function.php</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link href="css/bootstrap.min.css" rel="stylesheet">
+ <link href="css/style.css" rel="stylesheet">
+ <!--[if lt IE 9]>
+ <script src="js/html5shiv.min.js"></script>
+ <script src="js/respond.min.js"></script>
+ <![endif]-->
+ </head>
+ <body>
+ <header>
+ <div class="container">
+ <div class="row">
+ <div class="col-md-12">
+ <ol class="breadcrumb">
+ <li><a href="index.html">%s</a></li>
+ <li class="active">source_with_class_and_anonymous_function.php</li>
+
+ </ol>
+ </div>
+ </div>
+ </div>
+ </header>
+ <div class="container">
+ <table class="table table-bordered">
+ <thead>
+ <tr>
+ <td>&nbsp;</td>
+ <td colspan="10"><div align="center"><strong>Code Coverage</strong></div></td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
+ <td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
+ <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td class="danger">Total</td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="0.00" aria-valuemin="0" aria-valuemax="100" style="width: 0.00%">
+ <span class="sr-only">0.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">0.00%</div></td>
+ <td class="danger small"><div align="right">0&nbsp;/&nbsp;1</div></td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="50.00" aria-valuemin="0" aria-valuemax="100" style="width: 50.00%">
+ <span class="sr-only">50.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">50.00%</div></td>
+ <td class="danger small"><div align="right">1&nbsp;/&nbsp;2</div></td>
+ <td class="danger small"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></td>
+ <td class="warning big"> <div class="progress">
+ <div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="87.50" aria-valuemin="0" aria-valuemax="100" style="width: 87.50%">
+ <span class="sr-only">87.50% covered (warning)</span>
+ </div>
+ </div>
+</td>
+ <td class="warning small"><div align="right">87.50%</div></td>
+ <td class="warning small"><div align="right">7&nbsp;/&nbsp;8</div></td>
+ </tr>
+
+ <tr>
+ <td class="danger">CoveredClassWithAnonymousFunctionInStaticMethod</td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="0.00" aria-valuemin="0" aria-valuemax="100" style="width: 0.00%">
+ <span class="sr-only">0.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">0.00%</div></td>
+ <td class="danger small"><div align="right">0&nbsp;/&nbsp;1</div></td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="50.00" aria-valuemin="0" aria-valuemax="100" style="width: 50.00%">
+ <span class="sr-only">50.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">50.00%</div></td>
+ <td class="danger small"><div align="right">1&nbsp;/&nbsp;2</div></td>
+ <td class="danger small">2.01</td>
+ <td class="warning big"> <div class="progress">
+ <div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="87.50" aria-valuemin="0" aria-valuemax="100" style="width: 87.50%">
+ <span class="sr-only">87.50% covered (warning)</span>
+ </div>
+ </div>
+</td>
+ <td class="warning small"><div align="right">87.50%</div></td>
+ <td class="warning small"><div align="right">7&nbsp;/&nbsp;8</div></td>
+ </tr>
+
+ <tr>
+ <td class="danger" colspan="4">&nbsp;<a href="#5"><abbr title="runAnonymous()">runAnonymous</abbr></a></td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="0.00" aria-valuemin="0" aria-valuemax="100" style="width: 0.00%">
+ <span class="sr-only">0.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">0.00%</div></td>
+ <td class="danger small"><div align="right">0&nbsp;/&nbsp;1</div></td>
+ <td class="danger small">1.04</td>
+ <td class="warning big"> <div class="progress">
+ <div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="66.67" aria-valuemin="0" aria-valuemax="100" style="width: 66.67%">
+ <span class="sr-only">66.67% covered (warning)</span>
+ </div>
+ </div>
+</td>
+ <td class="warning small"><div align="right">66.67%</div></td>
+ <td class="warning small"><div align="right">2&nbsp;/&nbsp;3</div></td>
+ </tr>
+
+ <tr>
+ <td class="success" colspan="4">&nbsp;<a href="#11"><abbr title="anonymous function (&amp;$val, $key)">anonymous function</abbr></a></td>
+ <td class="success big"> <div class="progress">
+ <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
+ <span class="sr-only">100.00% covered (success)</span>
+ </div>
+ </div>
+</td>
+ <td class="success small"><div align="right">100.00%</div></td>
+ <td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
+ <td class="success small">1</td>
+ <td class="success big"> <div class="progress">
+ <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
+ <span class="sr-only">100.00% covered (success)</span>
+ </div>
+ </div>
+</td>
+ <td class="success small"><div align="right">100.00%</div></td>
+ <td class="success small"><div align="right">2&nbsp;/&nbsp;2</div></td>
+ </tr>
+
+
+ </tbody>
+ </table>
+ <table id="code" class="table table-borderless table-condensed">
+ <tbody>
+ <tr><td><div align="right"><a name="1"></a><a href="#1">1</a></div></td><td class="codeLine"><span class="default">&lt;?php</span></td></tr>
+ <tr><td><div align="right"><a name="2"></a><a href="#2">2</a></div></td><td class="codeLine"></td></tr>
+ <tr><td><div align="right"><a name="3"></a><a href="#3">3</a></div></td><td class="codeLine"><span class="keyword">class</span><span class="default">&nbsp;</span><span class="default">CoveredClassWithAnonymousFunctionInStaticMethod</span></td></tr>
+ <tr><td><div align="right"><a name="4"></a><a href="#4">4</a></div></td><td class="codeLine"><span class="keyword">{</span></td></tr>
+ <tr><td><div align="right"><a name="5"></a><a href="#5">5</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span class="default">&nbsp;</span><span class="keyword">static</span><span class="default">&nbsp;</span><span class="keyword">function</span><span class="default">&nbsp;</span><span class="default">runAnonymous</span><span class="keyword">(</span><span class="keyword">)</span></td></tr>
+ <tr><td><div align="right"><a name="6"></a><a href="#6">6</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">{</span></td></tr>
+ <tr class="covered-by-large-tests popin" data-title="1 test covers line 7" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;ClassWithAnonymousFunction&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="7"></a><a href="#7">7</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$filter</span><span class="default">&nbsp;</span><span class="keyword">=</span><span class="default">&nbsp;</span><span class="keyword">[</span><span class="default">'abc124'</span><span class="keyword">,</span><span class="default">&nbsp;</span><span class="default">'abc123'</span><span class="keyword">,</span><span class="default">&nbsp;</span><span class="default">'123'</span><span class="keyword">]</span><span class="keyword">;</span></td></tr>
+ <tr><td><div align="right"><a name="8"></a><a href="#8">8</a></div></td><td class="codeLine"></td></tr>
+ <tr class="covered-by-large-tests popin" data-title="1 test covers line 9" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;ClassWithAnonymousFunction&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="9"></a><a href="#9">9</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">array_walk</span><span class="keyword">(</span></td></tr>
+ <tr class="danger"><td><div align="right"><a name="10"></a><a href="#10">10</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$filter</span><span class="keyword">,</span></td></tr>
+ <tr><td><div align="right"><a name="11"></a><a href="#11">11</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">function</span><span class="default">&nbsp;</span><span class="keyword">(</span><span class="keyword">&amp;</span><span class="default">$val</span><span class="keyword">,</span><span class="default">&nbsp;</span><span class="default">$key</span><span class="keyword">)</span><span class="default">&nbsp;</span><span class="keyword">{</span></td></tr>
+ <tr class="covered-by-large-tests popin" data-title="1 test covers line 12" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;ClassWithAnonymousFunction&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="12"></a><a href="#12">12</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$val</span><span class="default">&nbsp;</span><span class="keyword">=</span><span class="default">&nbsp;</span><span class="default">preg_replace</span><span class="keyword">(</span><span class="default">'|[^0-9]|'</span><span class="keyword">,</span><span class="default">&nbsp;</span><span class="default">''</span><span class="keyword">,</span><span class="default">&nbsp;</span><span class="default">$val</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
+ <tr class="covered-by-large-tests popin" data-title="1 test covers line 13" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;ClassWithAnonymousFunction&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="13"></a><a href="#13">13</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
+ <tr class="covered-by-large-tests popin" data-title="1 test covers line 14" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;ClassWithAnonymousFunction&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="14"></a><a href="#14">14</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
+ <tr><td><div align="right"><a name="15"></a><a href="#15">15</a></div></td><td class="codeLine"></td></tr>
+ <tr><td><div align="right"><a name="16"></a><a href="#16">16</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;Should&nbsp;be&nbsp;covered</span></td></tr>
+ <tr class="covered-by-large-tests popin" data-title="1 test covers line 17" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;ClassWithAnonymousFunction&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="17"></a><a href="#17">17</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">$extravar</span><span class="default">&nbsp;</span><span class="keyword">=</span><span class="default">&nbsp;</span><span class="default">true</span><span class="keyword">;</span></td></tr>
+ <tr class="covered-by-large-tests popin" data-title="1 test covers line 18" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;ClassWithAnonymousFunction&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="18"></a><a href="#18">18</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
+ <tr><td><div align="right"><a name="19"></a><a href="#19">19</a></div></td><td class="codeLine"><span class="keyword">}</span></td></tr>
+
+ </tbody>
+ </table>
+ <footer>
+ <hr/>
+ <h4>Legend</h4>
+ <p>
+ <span class="success"><strong>Executed</strong></span>
+ <span class="danger"><strong>Not Executed</strong></span>
+ <span class="warning"><strong>Dead Code</strong></span>
+ </p>
+ <p>
+ <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="%s" target="_top">%s</a> at %s.</small>
+ </p>
+ <a title="Back to the top" id="toplink" href="#"><span class="glyphicon glyphicon-arrow-up"></span></a>
+ </footer>
+ </div>
+ <script src="js/jquery.min.js" type="text/javascript"></script>
+ <script src="js/bootstrap.min.js" type="text/javascript"></script>
+ <script src="js/holder.min.js" type="text/javascript"></script>
+ <script type="text/javascript">
+ $(function() {
+ var $window = $(window)
+ , $top_link = $('#toplink')
+ , $body = $('body, html')
+ , offset = $('#code').offset().top;
+
+ $top_link.hide().click(function(event) {
+ event.preventDefault();
+ $body.animate({scrollTop:0}, 800);
+ });
+
+ $window.scroll(function() {
+ if($window.scrollTop() > offset) {
+ $top_link.fadeIn();
+ } else {
+ $top_link.fadeOut();
+ }
+ }).scroll();
+
+ $('.popin').popover({trigger: 'hover'});
+ });
+ </script>
+ </body>
+</html>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/dashboard.html b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/dashboard.html
new file mode 100644
index 0000000..f905a9c
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/dashboard.html
@@ -0,0 +1,286 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <title>Dashboard for %s</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link href="css/bootstrap.min.css" rel="stylesheet">
+ <link href="css/nv.d3.min.css" rel="stylesheet">
+ <link href="css/style.css" rel="stylesheet">
+ <!--[if lt IE 9]>
+ <script src="js/html5shiv.min.js"></script>
+ <script src="js/respond.min.js"></script>
+ <![endif]-->
+ </head>
+ <body>
+ <header>
+ <div class="container">
+ <div class="row">
+ <div class="col-md-12">
+ <ol class="breadcrumb">
+ <li><a href="index.html">%s</a></li>
+ <li class="active">(Dashboard)</li>
+
+ </ol>
+ </div>
+ </div>
+ </div>
+ </header>
+ <div class="container">
+ <div class="row">
+ <div class="col-md-12">
+ <h2>Classes</h2>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <h3>Coverage Distribution</h3>
+ <div id="classCoverageDistribution" style="height: 300px;">
+ <svg></svg>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <h3>Complexity</h3>
+ <div id="classComplexity" style="height: 300px;">
+ <svg></svg>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <h3>Insufficient Coverage</h3>
+ <div class="scrollbox">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Class</th>
+ <th class="text-right">Coverage</th>
+ </tr>
+ </thead>
+ <tbody>
+
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <h3>Project Risks</h3>
+ <div class="scrollbox">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Class</th>
+ <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
+ </tr>
+ </thead>
+ <tbody>
+
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-12">
+ <h2>Methods</h2>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <h3>Coverage Distribution</h3>
+ <div id="methodCoverageDistribution" style="height: 300px;">
+ <svg></svg>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <h3>Complexity</h3>
+ <div id="methodComplexity" style="height: 300px;">
+ <svg></svg>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-md-6">
+ <h3>Insufficient Coverage</h3>
+ <div class="scrollbox">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Method</th>
+ <th class="text-right">Coverage</th>
+ </tr>
+ </thead>
+ <tbody>
+
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <h3>Project Risks</h3>
+ <div class="scrollbox">
+ <table class="table">
+ <thead>
+ <tr>
+ <th>Method</th>
+ <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
+ </tr>
+ </thead>
+ <tbody>
+
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ <footer>
+ <hr/>
+ <p>
+ <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="%s" target="_top">%s</a> at %s.</small>
+ </p>
+ </footer>
+ </div>
+ <script src="js/jquery.min.js" type="text/javascript"></script>
+ <script src="js/bootstrap.min.js" type="text/javascript"></script>
+ <script src="js/holder.min.js" type="text/javascript"></script>
+ <script src="js/d3.min.js" type="text/javascript"></script>
+ <script src="js/nv.d3.min.js" type="text/javascript"></script>
+ <script type="text/javascript">
+$(document).ready(function() {
+ nv.addGraph(function() {
+ var chart = nv.models.multiBarChart();
+ chart.tooltips(false)
+ .showControls(false)
+ .showLegend(false)
+ .reduceXTicks(false)
+ .staggerLabels(true)
+ .yAxis.tickFormat(d3.format('d'));
+
+ d3.select('#classCoverageDistribution svg')
+ .datum(getCoverageDistributionData([0,0,0,0,0,0,0,0,0,0,0,2], "Class Coverage"))
+ .transition().duration(500).call(chart);
+
+ nv.utils.windowResize(chart.update);
+
+ return chart;
+ });
+
+ nv.addGraph(function() {
+ var chart = nv.models.multiBarChart();
+ chart.tooltips(false)
+ .showControls(false)
+ .showLegend(false)
+ .reduceXTicks(false)
+ .staggerLabels(true)
+ .yAxis.tickFormat(d3.format('d'));
+
+ d3.select('#methodCoverageDistribution svg')
+ .datum(getCoverageDistributionData([0,0,0,0,0,0,0,0,0,0,0,2], "Method Coverage"))
+ .transition().duration(500).call(chart);
+
+ nv.utils.windowResize(chart.update);
+
+ return chart;
+ });
+
+ function getCoverageDistributionData(data, label) {
+ var labels = [
+ '0%',
+ '0-10%',
+ '10-20%',
+ '20-30%',
+ '30-40%',
+ '40-50%',
+ '50-60%',
+ '60-70%',
+ '70-80%',
+ '80-90%',
+ '90-100%',
+ '100%'
+ ];
+ var values = [];
+ $.each(labels, function(key) {
+ values.push({x: labels[key], y: data[key]});
+ });
+
+ return [
+ {
+ key: label,
+ values: values,
+ color: "#4572A7"
+ }
+ ];
+ }
+ nv.addGraph(function() {
+ var chart = nv.models.scatterChart()
+ .showDistX(true)
+ .showDistY(true)
+ .showLegend(false)
+ .forceX([0, 100]);
+ chart.tooltipContent(function(graph) {
+ return '<p>' + graph.point.class + '</p>';
+ });
+
+ chart.xAxis.axisLabel('Code Coverage (in percent)');
+ chart.yAxis.axisLabel('Cyclomatic Complexity');
+
+ d3.select('#classComplexity svg')
+ .datum(getComplexityData([[100,1,"<a href=\"source_with_ignore.php.html#11\">Foo<\/a>"],[100,1,"<a href=\"source_with_ignore.php.html#18\">Bar<\/a>"]], 'Class Complexity'))
+ .transition()
+ .duration(500)
+ .call(chart);
+
+ nv.utils.windowResize(chart.update);
+
+ return chart;
+ });
+
+ nv.addGraph(function() {
+ var chart = nv.models.scatterChart()
+ .showDistX(true)
+ .showDistY(true)
+ .showLegend(false)
+ .forceX([0, 100]);
+ chart.tooltipContent(function(graph) {
+ return '<p>' + graph.point.class + '</p>';
+ });
+
+ chart.xAxis.axisLabel('Code Coverage (in percent)');
+ chart.yAxis.axisLabel('Method Complexity');
+
+ d3.select('#methodComplexity svg')
+ .datum(getComplexityData([[100,1,"<a href=\"source_with_ignore.php.html#13\">Foo::bar<\/a>"],[100,1,"<a href=\"source_with_ignore.php.html#23\">Bar::foo<\/a>"]], 'Method Complexity'))
+ .transition()
+ .duration(500)
+ .call(chart);
+
+ nv.utils.windowResize(chart.update);
+
+ return chart;
+ });
+
+ function getComplexityData(data, label) {
+ var values = [];
+ $.each(data, function(key) {
+ var value = Math.round(data[key][0]*100) / 100;
+ values.push({
+ x: value,
+ y: data[key][1],
+ class: data[key][2],
+ size: 0.05,
+ shape: 'diamond'
+ });
+ });
+
+ return [
+ {
+ key: label,
+ values: values,
+ color: "#4572A7"
+ }
+ ];
+ }
+});
+ </script>
+ </body>
+</html>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html
new file mode 100644
index 0000000..78b8ef3
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <title>Code Coverage for %s</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link href="css/bootstrap.min.css" rel="stylesheet">
+ <link href="css/style.css" rel="stylesheet">
+ <!--[if lt IE 9]>
+ <script src="js/html5shiv.min.js"></script>
+ <script src="js/respond.min.js"></script>
+ <![endif]-->
+ </head>
+ <body>
+ <header>
+ <div class="container">
+ <div class="row">
+ <div class="col-md-12">
+ <ol class="breadcrumb">
+ <li class="active">%s</li>
+ <li>(<a href="dashboard.html">Dashboard</a>)</li>
+
+ </ol>
+ </div>
+ </div>
+ </div>
+ </header>
+ <div class="container">
+ <table class="table table-bordered">
+ <thead>
+ <tr>
+ <td>&nbsp;</td>
+ <td colspan="9"><div align="center"><strong>Code Coverage</strong></div></td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
+ <td colspan="3"><div align="center"><strong>Functions and Methods</strong></div></td>
+ <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td class="danger">Total</td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="50.00" aria-valuemin="0" aria-valuemax="100" style="width: 50.00%">
+ <span class="sr-only">50.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">50.00%</div></td>
+ <td class="danger small"><div align="right">1&nbsp;/&nbsp;2</div></td>
+ <td class=" big"></td>
+ <td class=" small"><div align="right">n/a</div></td>
+ <td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
+ <td class=" big"></td>
+ <td class=" small"><div align="right">n/a</div></td>
+ <td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
+ </tr>
+
+ <tr>
+ <td class="danger"><span class="glyphicon glyphicon-file"></span> <a href="source_with_ignore.php.html">source_with_ignore.php</a></td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="50.00" aria-valuemin="0" aria-valuemax="100" style="width: 50.00%">
+ <span class="sr-only">50.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">50.00%</div></td>
+ <td class="danger small"><div align="right">1&nbsp;/&nbsp;2</div></td>
+ <td class=" big"></td>
+ <td class=" small"><div align="right">n/a</div></td>
+ <td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
+ <td class=" big"></td>
+ <td class=" small"><div align="right">n/a</div></td>
+ <td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
+ </tr>
+
+
+ </tbody>
+ </table>
+ <footer>
+ <hr/>
+ <h4>Legend</h4>
+ <p>
+ <span class="danger"><strong>Low</strong>: 0% to 50%</span>
+ <span class="warning"><strong>Medium</strong>: 50% to 90%</span>
+ <span class="success"><strong>High</strong>: 90% to 100%</span>
+ </p>
+ <p>
+ <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="%s" target="_top">%s</a> at %s.</small>
+ </p>
+ </footer>
+ </div>
+ <script src="js/jquery.min.js" type="text/javascript"></script>
+ <script src="js/bootstrap.min.js" type="text/javascript"></script>
+ <script src="js/holder.min.js" type="text/javascript"></script>
+ </body>
+</html>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html
new file mode 100644
index 0000000..12effe1
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html
@@ -0,0 +1,234 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <title>Code Coverage for %s</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link href="css/bootstrap.min.css" rel="stylesheet">
+ <link href="css/style.css" rel="stylesheet">
+ <!--[if lt IE 9]>
+ <script src="js/html5shiv.min.js"></script>
+ <script src="js/respond.min.js"></script>
+ <![endif]-->
+ </head>
+ <body>
+ <header>
+ <div class="container">
+ <div class="row">
+ <div class="col-md-12">
+ <ol class="breadcrumb">
+ <li><a href="index.html">%s</a></li>
+ <li class="active">source_with_ignore.php</li>
+
+ </ol>
+ </div>
+ </div>
+ </div>
+ </header>
+ <div class="container">
+ <table class="table table-bordered">
+ <thead>
+ <tr>
+ <td>&nbsp;</td>
+ <td colspan="10"><div align="center"><strong>Code Coverage</strong></div></td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
+ <td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
+ <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td class="">Total</td>
+ <td class=" big"></td>
+ <td class=" small"><div align="right">n/a</div></td>
+ <td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
+ <td class=" big"></td>
+ <td class=" small"><div align="right">n/a</div></td>
+ <td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
+ <td class=" small"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></td>
+ <td class="danger big"> <div class="progress">
+ <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="50.00" aria-valuemin="0" aria-valuemax="100" style="width: 50.00%">
+ <span class="sr-only">50.00% covered (danger)</span>
+ </div>
+ </div>
+</td>
+ <td class="danger small"><div align="right">50.00%</div></td>
+ <td class="danger small"><div align="right">1&nbsp;/&nbsp;2</div></td>
+ </tr>
+
+ <tr>
+ <td class="success" colspan="4"><a href="#28"><abbr title="baz()">baz</abbr></a></td>
+ <td class="success big"> <div class="progress">
+ <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
+ <span class="sr-only">100.00% covered (success)</span>
+ </div>
+ </div>
+</td>
+ <td class="success small"><div align="right">100.00%</div></td>
+ <td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
+ <td class="success small">0</td>
+ <td class=" big"></td>
+ <td class=" small"><div align="right">n/a</div></td>
+ <td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
+ </tr>
+
+ <tr>
+ <td class="">Foo</td>
+ <td class=" big"></td>
+ <td class=" small"><div align="right">n/a</div></td>
+ <td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
+ <td class="success big"> <div class="progress">
+ <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
+ <span class="sr-only">100.00% covered (success)</span>
+ </div>
+ </div>
+</td>
+ <td class="success small"><div align="right">100.00%</div></td>
+ <td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
+ <td class="success small">1</td>
+ <td class=" big"></td>
+ <td class=" small"><div align="right">n/a</div></td>
+ <td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
+ </tr>
+
+ <tr>
+ <td class="success" colspan="4">&nbsp;<a href="#13"><abbr title="bar()">bar</abbr></a></td>
+ <td class="success big"> <div class="progress">
+ <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
+ <span class="sr-only">100.00% covered (success)</span>
+ </div>
+ </div>
+</td>
+ <td class="success small"><div align="right">100.00%</div></td>
+ <td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
+ <td class="success small">1</td>
+ <td class=" big"></td>
+ <td class=" small"><div align="right">n/a</div></td>
+ <td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
+ </tr>
+
+ <tr>
+ <td class="">Bar</td>
+ <td class=" big"></td>
+ <td class=" small"><div align="right">n/a</div></td>
+ <td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
+ <td class="success big"> <div class="progress">
+ <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
+ <span class="sr-only">100.00% covered (success)</span>
+ </div>
+ </div>
+</td>
+ <td class="success small"><div align="right">100.00%</div></td>
+ <td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
+ <td class="success small">1</td>
+ <td class=" big"></td>
+ <td class=" small"><div align="right">n/a</div></td>
+ <td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
+ </tr>
+
+ <tr>
+ <td class="success" colspan="4">&nbsp;<a href="#23"><abbr title="foo()">foo</abbr></a></td>
+ <td class="success big"> <div class="progress">
+ <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100.00" aria-valuemin="0" aria-valuemax="100" style="width: 100.00%">
+ <span class="sr-only">100.00% covered (success)</span>
+ </div>
+ </div>
+</td>
+ <td class="success small"><div align="right">100.00%</div></td>
+ <td class="success small"><div align="right">1&nbsp;/&nbsp;1</div></td>
+ <td class="success small">1</td>
+ <td class=" big"></td>
+ <td class=" small"><div align="right">n/a</div></td>
+ <td class=" small"><div align="right">0&nbsp;/&nbsp;0</div></td>
+ </tr>
+
+
+ </tbody>
+ </table>
+ <table id="code" class="table table-borderless table-condensed">
+ <tbody>
+ <tr><td><div align="right"><a name="1"></a><a href="#1">1</a></div></td><td class="codeLine"><span class="default">&lt;?php</span></td></tr>
+ <tr class="covered-by-large-tests popin" data-title="1 test covers line 2" data-content="&lt;ul&gt;&lt;li class=&quot;covered-by-large-tests&quot;&gt;FileWithIgnoredLines&lt;/li&gt;&lt;/ul&gt;" data-placement="bottom" data-html="true"><td><div align="right"><a name="2"></a><a href="#2">2</a></div></td><td class="codeLine"><span class="keyword">if</span><span class="default">&nbsp;</span><span class="keyword">(</span><span class="default">$neverHappens</span><span class="keyword">)</span><span class="default">&nbsp;</span><span class="keyword">{</span></td></tr>
+ <tr><td><div align="right"><a name="3"></a><a href="#3">3</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;@codeCoverageIgnoreStart</span></td></tr>
+ <tr><td><div align="right"><a name="4"></a><a href="#4">4</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">print</span><span class="default">&nbsp;</span><span class="default">'*'</span><span class="keyword">;</span></td></tr>
+ <tr><td><div align="right"><a name="5"></a><a href="#5">5</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;@codeCoverageIgnoreEnd</span></td></tr>
+ <tr class="danger"><td><div align="right"><a name="6"></a><a href="#6">6</a></div></td><td class="codeLine"><span class="keyword">}</span></td></tr>
+ <tr><td><div align="right"><a name="7"></a><a href="#7">7</a></div></td><td class="codeLine"></td></tr>
+ <tr><td><div align="right"><a name="8"></a><a href="#8">8</a></div></td><td class="codeLine"><span class="comment">/**</span></td></tr>
+ <tr><td><div align="right"><a name="9"></a><a href="#9">9</a></div></td><td class="codeLine"><span class="comment">&nbsp;*&nbsp;@codeCoverageIgnore</span></td></tr>
+ <tr><td><div align="right"><a name="10"></a><a href="#10">10</a></div></td><td class="codeLine"><span class="comment">&nbsp;*/</span></td></tr>
+ <tr><td><div align="right"><a name="11"></a><a href="#11">11</a></div></td><td class="codeLine"><span class="keyword">class</span><span class="default">&nbsp;</span><span class="default">Foo</span></td></tr>
+ <tr><td><div align="right"><a name="12"></a><a href="#12">12</a></div></td><td class="codeLine"><span class="keyword">{</span></td></tr>
+ <tr><td><div align="right"><a name="13"></a><a href="#13">13</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span class="default">&nbsp;</span><span class="keyword">function</span><span class="default">&nbsp;</span><span class="default">bar</span><span class="keyword">(</span><span class="keyword">)</span></td></tr>
+ <tr><td><div align="right"><a name="14"></a><a href="#14">14</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">{</span></td></tr>
+ <tr><td><div align="right"><a name="15"></a><a href="#15">15</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
+ <tr><td><div align="right"><a name="16"></a><a href="#16">16</a></div></td><td class="codeLine"><span class="keyword">}</span></td></tr>
+ <tr><td><div align="right"><a name="17"></a><a href="#17">17</a></div></td><td class="codeLine"></td></tr>
+ <tr><td><div align="right"><a name="18"></a><a href="#18">18</a></div></td><td class="codeLine"><span class="keyword">class</span><span class="default">&nbsp;</span><span class="default">Bar</span></td></tr>
+ <tr><td><div align="right"><a name="19"></a><a href="#19">19</a></div></td><td class="codeLine"><span class="keyword">{</span></td></tr>
+ <tr><td><div align="right"><a name="20"></a><a href="#20">20</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">/**</span></td></tr>
+ <tr><td><div align="right"><a name="21"></a><a href="#21">21</a></div></td><td class="codeLine"><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@codeCoverageIgnore</span></td></tr>
+ <tr><td><div align="right"><a name="22"></a><a href="#22">22</a></div></td><td class="codeLine"><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></td></tr>
+ <tr><td><div align="right"><a name="23"></a><a href="#23">23</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span class="default">&nbsp;</span><span class="keyword">function</span><span class="default">&nbsp;</span><span class="default">foo</span><span class="keyword">(</span><span class="keyword">)</span></td></tr>
+ <tr><td><div align="right"><a name="24"></a><a href="#24">24</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">{</span></td></tr>
+ <tr><td><div align="right"><a name="25"></a><a href="#25">25</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">}</span></td></tr>
+ <tr><td><div align="right"><a name="26"></a><a href="#26">26</a></div></td><td class="codeLine"><span class="keyword">}</span></td></tr>
+ <tr><td><div align="right"><a name="27"></a><a href="#27">27</a></div></td><td class="codeLine"></td></tr>
+ <tr><td><div align="right"><a name="28"></a><a href="#28">28</a></div></td><td class="codeLine"><span class="keyword">function</span><span class="default">&nbsp;</span><span class="default">baz</span><span class="keyword">(</span><span class="keyword">)</span></td></tr>
+ <tr><td><div align="right"><a name="29"></a><a href="#29">29</a></div></td><td class="codeLine"><span class="keyword">{</span></td></tr>
+ <tr><td><div align="right"><a name="30"></a><a href="#30">30</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="default">print</span><span class="default">&nbsp;</span><span class="default">'*'</span><span class="keyword">;</span><span class="default">&nbsp;</span><span class="comment">//&nbsp;@codeCoverageIgnore</span></td></tr>
+ <tr><td><div align="right"><a name="31"></a><a href="#31">31</a></div></td><td class="codeLine"><span class="keyword">}</span></td></tr>
+ <tr><td><div align="right"><a name="32"></a><a href="#32">32</a></div></td><td class="codeLine"></td></tr>
+ <tr><td><div align="right"><a name="33"></a><a href="#33">33</a></div></td><td class="codeLine"><span class="keyword">interface</span><span class="default">&nbsp;</span><span class="default">Bor</span></td></tr>
+ <tr><td><div align="right"><a name="34"></a><a href="#34">34</a></div></td><td class="codeLine"><span class="keyword">{</span></td></tr>
+ <tr><td><div align="right"><a name="35"></a><a href="#35">35</a></div></td><td class="codeLine"><span class="default">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span class="default">&nbsp;</span><span class="keyword">function</span><span class="default">&nbsp;</span><span class="default">foo</span><span class="keyword">(</span><span class="keyword">)</span><span class="keyword">;</span></td></tr>
+ <tr><td><div align="right"><a name="36"></a><a href="#36">36</a></div></td><td class="codeLine"></td></tr>
+ <tr><td><div align="right"><a name="37"></a><a href="#37">37</a></div></td><td class="codeLine"><span class="keyword">}</span></td></tr>
+
+ </tbody>
+ </table>
+ <footer>
+ <hr/>
+ <h4>Legend</h4>
+ <p>
+ <span class="success"><strong>Executed</strong></span>
+ <span class="danger"><strong>Not Executed</strong></span>
+ <span class="warning"><strong>Dead Code</strong></span>
+ </p>
+ <p>
+ <small>Generated by <a href="https://github.com/sebastianbergmann/php-code-coverage" target="_top">php-code-coverage %s</a> using <a href="%s" target="_top">%s</a> at %s.</small>
+ </p>
+ <a title="Back to the top" id="toplink" href="#"><span class="glyphicon glyphicon-arrow-up"></span></a>
+ </footer>
+ </div>
+ <script src="js/jquery.min.js" type="text/javascript"></script>
+ <script src="js/bootstrap.min.js" type="text/javascript"></script>
+ <script src="js/holder.min.js" type="text/javascript"></script>
+ <script type="text/javascript">
+ $(function() {
+ var $window = $(window)
+ , $top_link = $('#toplink')
+ , $body = $('body, html')
+ , offset = $('#code').offset().top;
+
+ $top_link.hide().click(function(event) {
+ event.preventDefault();
+ $body.animate({scrollTop:0}, 800);
+ });
+
+ $window.scroll(function() {
+ if($window.scrollTop() > offset) {
+ $top_link.fadeIn();
+ } else {
+ $top_link.fadeOut();
+ }
+ }).scroll();
+
+ $('.popin').popover({trigger: 'hover'});
+ });
+ </script>
+ </body>
+</html>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForBankAccount/BankAccount.php.xml b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForBankAccount/BankAccount.php.xml
new file mode 100644
index 0000000..d5c5d2e
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForBankAccount/BankAccount.php.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<phpunit xmlns="http://schema.phpunit.de/coverage/1.0">
+ <file name="BankAccount.php">
+ <totals>
+ <lines total="33" comments="0" code="33" executable="10" executed="5" percent="50.00%"/>
+ <methods count="4" tested="3" percent="75.00%"/>
+ <functions count="0" tested="0" percent=""/>
+ <classes count="1" tested="0" percent="0.00%"/>
+ <traits count="0" tested="0" percent=""/>
+ </totals>
+ <class name="BankAccount" start="2" executable="10" executed="5" crap="8.12">
+ <package full="" name="" sub="" category=""/>
+ <namespace name=""/>
+ <method name="getBalance" signature="getBalance()" start="6" end="9" crap="1" executable="1" executed="1" coverage="100"/>
+ <method name="setBalance" signature="setBalance($balance)" start="11" end="18" crap="6" executable="5" executed="0" coverage="0"/>
+ <method name="depositMoney" signature="depositMoney($balance)" start="20" end="25" crap="1" executable="2" executed="2" coverage="100"/>
+ <method name="withdrawMoney" signature="withdrawMoney($balance)" start="27" end="32" crap="1" executable="2" executed="2" coverage="100"/>
+ </class>
+ <coverage>
+ <line nr="8">
+ <covered by="BankAccountTest::testBalanceIsInitiallyZero"/>
+ <covered by="BankAccountTest::testDepositWithdrawMoney"/>
+ </line>
+ <line nr="22">
+ <covered by="BankAccountTest::testBalanceCannotBecomeNegative2"/>
+ <covered by="BankAccountTest::testDepositWithdrawMoney"/>
+ </line>
+ <line nr="24">
+ <covered by="BankAccountTest::testDepositWithdrawMoney"/>
+ </line>
+ <line nr="29">
+ <covered by="BankAccountTest::testBalanceCannotBecomeNegative"/>
+ <covered by="BankAccountTest::testDepositWithdrawMoney"/>
+ </line>
+ <line nr="31">
+ <covered by="BankAccountTest::testDepositWithdrawMoney"/>
+ </line>
+ </coverage>
+ </file>
+</phpunit>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForBankAccount/index.xml b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForBankAccount/index.xml
new file mode 100644
index 0000000..27fc5b4
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForBankAccount/index.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<phpunit xmlns="http://schema.phpunit.de/coverage/1.0">
+ <project name="%s">
+ <tests>
+ <test name="BankAccountTest::testBalanceIsInitiallyZero" size="unknown" result="0" status="PASSED"/>
+ <test name="BankAccountTest::testBalanceCannotBecomeNegative" size="unknown" result="0" status="PASSED"/>
+ <test name="BankAccountTest::testBalanceCannotBecomeNegative2" size="unknown" result="0" status="PASSED"/>
+ <test name="BankAccountTest::testDepositWithdrawMoney" size="unknown" result="0" status="PASSED"/>
+ </tests>
+ <directory name="%s">
+ <totals>
+ <lines total="33" comments="0" code="33" executable="10" executed="5" percent="50.00%"/>
+ <methods count="4" tested="3" percent="75.00%"/>
+ <functions count="0" tested="0" percent=""/>
+ <classes count="1" tested="0" percent="0.00%"/>
+ <traits count="0" tested="0" percent=""/>
+ </totals>
+ <file name="BankAccount.php" href="BankAccount.php.xml">
+ <totals>
+ <lines total="33" comments="0" code="33" executable="10" executed="5" percent="50.00%"/>
+ <methods count="4" tested="3" percent="75.00%"/>
+ <functions count="0" tested="0" percent=""/>
+ <classes count="1" tested="0" percent="0.00%"/>
+ <traits count="0" tested="0" percent=""/>
+ </totals>
+ </file>
+ </directory>
+ </project>
+</phpunit>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/index.xml b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/index.xml
new file mode 100644
index 0000000..6f9cd19
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/index.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<phpunit xmlns="http://schema.phpunit.de/coverage/1.0">
+ <project name="%s">
+ <tests>
+ <test name="ClassWithAnonymousFunction" size="unknown" result="0" status="PASSED"/>
+ </tests>
+ <directory name="%s">
+ <totals>
+ <lines total="19" comments="2" code="17" executable="8" executed="7" percent="87.50%"/>
+ <methods count="2" tested="1" percent="50.00%"/>
+ <functions count="0" tested="0" percent=""/>
+ <classes count="1" tested="0" percent="0.00%"/>
+ <traits count="0" tested="0" percent=""/>
+ </totals>
+ <file name="source_with_class_and_anonymous_function.php" href="source_with_class_and_anonymous_function.php.xml">
+ <totals>
+ <lines total="19" comments="2" code="17" executable="8" executed="7" percent="87.50%"/>
+ <methods count="2" tested="1" percent="50.00%"/>
+ <functions count="0" tested="0" percent=""/>
+ <classes count="1" tested="0" percent="0.00%"/>
+ <traits count="0" tested="0" percent=""/>
+ </totals>
+ </file>
+ </directory>
+ </project>
+</phpunit>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.xml b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.xml
new file mode 100644
index 0000000..d424524
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<phpunit xmlns="http://schema.phpunit.de/coverage/1.0">
+ <file name="source_with_class_and_anonymous_function.php">
+ <totals>
+ <lines total="19" comments="2" code="17" executable="8" executed="7" percent="87.50%"/>
+ <methods count="2" tested="1" percent="50.00%"/>
+ <functions count="0" tested="0" percent=""/>
+ <classes count="1" tested="0" percent="0.00%"/>
+ <traits count="0" tested="0" percent=""/>
+ </totals>
+ <class name="CoveredClassWithAnonymousFunctionInStaticMethod" start="3" executable="8" executed="7" crap="2.01">
+ <package full="" name="" sub="" category=""/>
+ <namespace name=""/>
+ <method name="runAnonymous" signature="runAnonymous()" start="5" end="18" crap="1.04" executable="3" executed="2" coverage="66.666666666667"/>
+ <method name="anonymous function" signature="anonymous function (&amp;$val, $key)" start="11" end="13" crap="1" executable="2" executed="2" coverage="100"/>
+ </class>
+ <coverage>
+ <line nr="7">
+ <covered by="ClassWithAnonymousFunction"/>
+ </line>
+ <line nr="9">
+ <covered by="ClassWithAnonymousFunction"/>
+ </line>
+ <line nr="12">
+ <covered by="ClassWithAnonymousFunction"/>
+ </line>
+ <line nr="13">
+ <covered by="ClassWithAnonymousFunction"/>
+ </line>
+ <line nr="14">
+ <covered by="ClassWithAnonymousFunction"/>
+ </line>
+ <line nr="17">
+ <covered by="ClassWithAnonymousFunction"/>
+ </line>
+ <line nr="18">
+ <covered by="ClassWithAnonymousFunction"/>
+ </line>
+ </coverage>
+ </file>
+</phpunit>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/index.xml b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/index.xml
new file mode 100644
index 0000000..436081a
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/index.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<phpunit xmlns="http://schema.phpunit.de/coverage/1.0">
+ <project name="%s">
+ <tests>
+ <test name="FileWithIgnoredLines" size="unknown" result="0" status="PASSED"/>
+ </tests>
+ <directory name="%s">
+ <totals>
+ <lines total="37" comments="12" code="25" executable="2" executed="1" percent="50.00%"/>
+ <methods count="0" tested="0" percent=""/>
+ <functions count="1" tested="0" percent="0.00%"/>
+ <classes count="0" tested="0" percent=""/>
+ <traits count="0" tested="0" percent=""/>
+ </totals>
+ <file name="source_with_ignore.php" href="source_with_ignore.php.xml">
+ <totals>
+ <lines total="37" comments="12" code="25" executable="2" executed="1" percent="50.00%"/>
+ <methods count="0" tested="0" percent=""/>
+ <functions count="1" tested="0" percent="0.00%"/>
+ <classes count="0" tested="0" percent=""/>
+ <traits count="0" tested="0" percent=""/>
+ </totals>
+ </file>
+ </directory>
+ </project>
+</phpunit>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/source_with_ignore.php.xml b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/source_with_ignore.php.xml
new file mode 100644
index 0000000..f5eec7d
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/source_with_ignore.php.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<phpunit xmlns="http://schema.phpunit.de/coverage/1.0">
+ <file name="source_with_ignore.php">
+ <totals>
+ <lines total="37" comments="12" code="25" executable="2" executed="1" percent="50.00%"/>
+ <methods count="0" tested="0" percent=""/>
+ <functions count="1" tested="0" percent="0.00%"/>
+ <classes count="0" tested="0" percent=""/>
+ <traits count="0" tested="0" percent=""/>
+ </totals>
+ <class name="Foo" start="11" executable="0" executed="0" crap="1">
+ <package full="" name="" sub="" category=""/>
+ <namespace name=""/>
+ <method name="bar" signature="bar()" start="13" end="15" crap="1" executable="0" executed="0" coverage="100"/>
+ </class>
+ <class name="Bar" start="18" executable="0" executed="0" crap="1">
+ <package full="" name="" sub="" category=""/>
+ <namespace name=""/>
+ <method name="foo" signature="foo()" start="23" end="25" crap="1" executable="0" executed="0" coverage="100"/>
+ </class>
+ <function name="baz" signature="baz()" start="28" crap="0" executable="0" executed="0" coverage="0"/>
+ <coverage>
+ <line nr="2">
+ <covered by="FileWithIgnoredLines"/>
+ </line>
+ </coverage>
+ </file>
+</phpunit>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-clover.xml b/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-clover.xml
new file mode 100644
index 0000000..d6a8b40
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-clover.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<coverage generated="%i">
+ <project timestamp="%i">
+ <file name="%s/source_with_class_and_anonymous_function.php">
+ <class name="CoveredClassWithAnonymousFunctionInStaticMethod" namespace="global">
+ <metrics complexity="2" methods="2" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="5" coveredstatements="4" elements="7" coveredelements="5"/>
+ </class>
+ <line num="5" type="method" name="runAnonymous" visibility="public" complexity="1" crap="1.04" count="1"/>
+ <line num="7" type="stmt" count="1"/>
+ <line num="9" type="stmt" count="1"/>
+ <line num="10" type="stmt" count="0"/>
+ <line num="11" type="method" name="anonymous function" complexity="1" crap="1" count="1"/>
+ <line num="12" type="stmt" count="1"/>
+ <line num="13" type="stmt" count="1"/>
+ <line num="14" type="stmt" count="1"/>
+ <line num="17" type="stmt" count="1"/>
+ <line num="18" type="stmt" count="1"/>
+ <metrics loc="19" ncloc="17" classes="1" methods="2" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="8" coveredstatements="7" elements="10" coveredelements="8"/>
+ </file>
+ <metrics files="1" loc="19" ncloc="17" classes="1" methods="2" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="8" coveredstatements="7" elements="10" coveredelements="8"/>
+ </project>
+</coverage>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-crap4j.xml b/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-crap4j.xml
new file mode 100644
index 0000000..696496d
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-crap4j.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<crap_result>
+ <project>CoverageForClassWithAnonymousFunction</project>
+ <timestamp>%s</timestamp>
+ <stats>
+ <name>Method Crap Stats</name>
+ <methodCount>2</methodCount>
+ <crapMethodCount>0</crapMethodCount>
+ <crapLoad>0</crapLoad>
+ <totalCrap>2.04</totalCrap>
+ <crapMethodPercent>0</crapMethodPercent>
+ </stats>
+ <methods>
+ <method>
+ <package>global</package>
+ <className>CoveredClassWithAnonymousFunctionInStaticMethod</className>
+ <methodName>runAnonymous</methodName>
+ <methodSignature>runAnonymous()</methodSignature>
+ <fullMethod>runAnonymous()</fullMethod>
+ <crap>1.04</crap>
+ <complexity>1</complexity>
+ <coverage>66.67</coverage>
+ <crapLoad>0</crapLoad>
+ </method>
+ <method>
+ <package>global</package>
+ <className>CoveredClassWithAnonymousFunctionInStaticMethod</className>
+ <methodName>anonymous function</methodName>
+ <methodSignature>anonymous function (&amp;$val, $key)</methodSignature>
+ <fullMethod>anonymous function (&amp;$val, $key)</fullMethod>
+ <crap>1</crap>
+ <complexity>1</complexity>
+ <coverage>100</coverage>
+ <crapLoad>0</crapLoad>
+ </method>
+ </methods>
+</crap_result>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-text.txt b/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-text.txt
new file mode 100644
index 0000000..0eb257e
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-text.txt
@@ -0,0 +1,12 @@
+
+
+Code Coverage Report:
+ %s
+
+ Summary:
+ Classes: 0.00% (0/1)
+ Methods: 50.00% (1/2)
+ Lines: 87.50% (7/8)
+
+CoveredClassWithAnonymousFunctionInStaticMethod
+ Methods: 50.00% ( 1/ 2) Lines: 80.00% ( 4/ 5)
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-clover.xml b/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-clover.xml
new file mode 100644
index 0000000..a35cc4b
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-clover.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<coverage generated="%i">
+ <project timestamp="%i">
+ <file name="%s/source_with_ignore.php">
+ <class name="Foo" namespace="global">
+ <metrics complexity="1" methods="0" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="0" coveredstatements="0" elements="0" coveredelements="0"/>
+ </class>
+ <class name="Bar" namespace="global">
+ <metrics complexity="1" methods="0" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="0" coveredstatements="0" elements="0" coveredelements="0"/>
+ </class>
+ <line num="2" type="stmt" count="1"/>
+ <line num="6" type="stmt" count="0"/>
+ <metrics loc="37" ncloc="25" classes="0" methods="0" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="2" coveredstatements="1" elements="2" coveredelements="1"/>
+ </file>
+ <metrics files="1" loc="37" ncloc="25" classes="0" methods="0" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="2" coveredstatements="1" elements="2" coveredelements="1"/>
+ </project>
+</coverage>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-crap4j.xml b/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-crap4j.xml
new file mode 100644
index 0000000..2607b59
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-crap4j.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<crap_result>
+ <project>CoverageForFileWithIgnoredLines</project>
+ <timestamp>%s</timestamp>
+ <stats>
+ <name>Method Crap Stats</name>
+ <methodCount>2</methodCount>
+ <crapMethodCount>0</crapMethodCount>
+ <crapLoad>0</crapLoad>
+ <totalCrap>2</totalCrap>
+ <crapMethodPercent>0</crapMethodPercent>
+ </stats>
+ <methods>
+ <method>
+ <package>global</package>
+ <className>Foo</className>
+ <methodName>bar</methodName>
+ <methodSignature>bar()</methodSignature>
+ <fullMethod>bar()</fullMethod>
+ <crap>1</crap>
+ <complexity>1</complexity>
+ <coverage>100</coverage>
+ <crapLoad>0</crapLoad>
+ </method>
+ <method>
+ <package>global</package>
+ <className>Bar</className>
+ <methodName>foo</methodName>
+ <methodSignature>foo()</methodSignature>
+ <fullMethod>foo()</fullMethod>
+ <crap>1</crap>
+ <complexity>1</complexity>
+ <coverage>100</coverage>
+ <crapLoad>0</crapLoad>
+ </method>
+ </methods>
+</crap_result>
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-text.txt b/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-text.txt
new file mode 100644
index 0000000..6e8e149
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-text.txt
@@ -0,0 +1,10 @@
+
+
+Code Coverage Report:%w
+ %s
+%w
+ Summary:%w
+ Classes: (0/0)
+ Methods: (0/0)
+ Lines: 50.00% (1/2)
+
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/source_with_class_and_anonymous_function.php b/vendor/phpunit/php-code-coverage/tests/_files/source_with_class_and_anonymous_function.php
new file mode 100644
index 0000000..72aa938
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/source_with_class_and_anonymous_function.php
@@ -0,0 +1,19 @@
+<?php
+
+class CoveredClassWithAnonymousFunctionInStaticMethod
+{
+ public static function runAnonymous()
+ {
+ $filter = ['abc124', 'abc123', '123'];
+
+ array_walk(
+ $filter,
+ function (&$val, $key) {
+ $val = preg_replace('|[^0-9]|', '', $val);
+ }
+ );
+
+ // Should be covered
+ $extravar = true;
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/source_with_ignore.php b/vendor/phpunit/php-code-coverage/tests/_files/source_with_ignore.php
new file mode 100644
index 0000000..dd9aa12
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/source_with_ignore.php
@@ -0,0 +1,37 @@
+<?php
+if ($neverHappens) {
+ // @codeCoverageIgnoreStart
+ print '*';
+ // @codeCoverageIgnoreEnd
+}
+
+/**
+ * @codeCoverageIgnore
+ */
+class Foo
+{
+ public function bar()
+ {
+ }
+}
+
+class Bar
+{
+ /**
+ * @codeCoverageIgnore
+ */
+ public function foo()
+ {
+ }
+}
+
+function baz()
+{
+ print '*'; // @codeCoverageIgnore
+}
+
+interface Bor
+{
+ public function foo();
+
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/source_with_namespace.php b/vendor/phpunit/php-code-coverage/tests/_files/source_with_namespace.php
new file mode 100644
index 0000000..fb9dfa3
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/source_with_namespace.php
@@ -0,0 +1,20 @@
+<?php
+namespace bar\baz;
+
+/**
+ * Represents foo.
+ */
+class source_with_namespace
+{
+}
+
+/**
+ * @param mixed $bar
+ */
+function &foo($bar)
+{
+ $baz = function () {};
+ $a = true ? true : false;
+ $b = "{$a}";
+ $c = "${b}";
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/source_with_oneline_annotations.php b/vendor/phpunit/php-code-coverage/tests/_files/source_with_oneline_annotations.php
new file mode 100644
index 0000000..19dd4cd
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/source_with_oneline_annotations.php
@@ -0,0 +1,36 @@
+<?php
+
+/** Docblock */
+interface Foo
+{
+ public function bar();
+}
+
+class Foo
+{
+ public function bar()
+ {
+ }
+}
+
+function baz()
+{
+ // a one-line comment
+ print '*'; // a one-line comment
+
+ /* a one-line comment */
+ print '*'; /* a one-line comment */
+
+ /* a one-line comment
+ */
+ print '*'; /* a one-line comment
+ */
+
+ print '*'; // @codeCoverageIgnore
+
+ print '*'; // @codeCoverageIgnoreStart
+ print '*';
+ print '*'; // @codeCoverageIgnoreEnd
+
+ print '*';
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/source_without_ignore.php b/vendor/phpunit/php-code-coverage/tests/_files/source_without_ignore.php
new file mode 100644
index 0000000..be4e836
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/source_without_ignore.php
@@ -0,0 +1,4 @@
+<?php
+if ($neverHappens) {
+ print '*';
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/_files/source_without_namespace.php b/vendor/phpunit/php-code-coverage/tests/_files/source_without_namespace.php
new file mode 100644
index 0000000..a291e74
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/_files/source_without_namespace.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Represents foo.
+ */
+class Foo
+{
+}
+
+/**
+ * @param mixed $bar
+ */
+function &foo($bar)
+{
+ $baz = function () {};
+ $a = true ? true : false;
+ $b = "{$a}";
+ $c = "${b}";
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/bootstrap.php b/vendor/phpunit/php-code-coverage/tests/bootstrap.php
new file mode 100644
index 0000000..8e6d413
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/bootstrap.php
@@ -0,0 +1,5 @@
+<?php
+require __DIR__ . '/../vendor/autoload.php';
+require __DIR__ . '/TestCase.php';
+
+define('TEST_FILES_PATH', __DIR__ . '/_files/');
diff --git a/vendor/phpunit/php-code-coverage/tests/tests/BuilderTest.php b/vendor/phpunit/php-code-coverage/tests/tests/BuilderTest.php
new file mode 100644
index 0000000..1a4b6f3
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/tests/BuilderTest.php
@@ -0,0 +1,212 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report;
+
+use SebastianBergmann\CodeCoverage\TestCase;
+use SebastianBergmann\CodeCoverage\Node\Builder;
+
+class BuilderTest extends TestCase
+{
+ protected $factory;
+
+ protected function setUp()
+ {
+ $this->factory = new Builder;
+ }
+
+ public function testSomething()
+ {
+ $root = $this->getCoverageForBankAccount()->getReport();
+
+ $expectedPath = rtrim(TEST_FILES_PATH, DIRECTORY_SEPARATOR);
+ $this->assertEquals($expectedPath, $root->getName());
+ $this->assertEquals($expectedPath, $root->getPath());
+ $this->assertEquals(10, $root->getNumExecutableLines());
+ $this->assertEquals(5, $root->getNumExecutedLines());
+ $this->assertEquals(1, $root->getNumClasses());
+ $this->assertEquals(0, $root->getNumTestedClasses());
+ $this->assertEquals(4, $root->getNumMethods());
+ $this->assertEquals(3, $root->getNumTestedMethods());
+ $this->assertEquals('0.00%', $root->getTestedClassesPercent());
+ $this->assertEquals('75.00%', $root->getTestedMethodsPercent());
+ $this->assertEquals('50.00%', $root->getLineExecutedPercent());
+ $this->assertEquals(0, $root->getNumFunctions());
+ $this->assertEquals(0, $root->getNumTestedFunctions());
+ $this->assertNull($root->getParent());
+ $this->assertEquals([], $root->getDirectories());
+ #$this->assertEquals(array(), $root->getFiles());
+ #$this->assertEquals(array(), $root->getChildNodes());
+
+ $this->assertEquals(
+ [
+ 'BankAccount' => [
+ 'methods' => [
+ 'getBalance' => [
+ 'signature' => 'getBalance()',
+ 'startLine' => 6,
+ 'endLine' => 9,
+ 'executableLines' => 1,
+ 'executedLines' => 1,
+ 'ccn' => 1,
+ 'coverage' => 100,
+ 'crap' => '1',
+ 'link' => 'BankAccount.php.html#6',
+ 'methodName' => 'getBalance',
+ 'visibility' => 'public',
+ ],
+ 'setBalance' => [
+ 'signature' => 'setBalance($balance)',
+ 'startLine' => 11,
+ 'endLine' => 18,
+ 'executableLines' => 5,
+ 'executedLines' => 0,
+ 'ccn' => 2,
+ 'coverage' => 0,
+ 'crap' => 6,
+ 'link' => 'BankAccount.php.html#11',
+ 'methodName' => 'setBalance',
+ 'visibility' => 'protected',
+ ],
+ 'depositMoney' => [
+ 'signature' => 'depositMoney($balance)',
+ 'startLine' => 20,
+ 'endLine' => 25,
+ 'executableLines' => 2,
+ 'executedLines' => 2,
+ 'ccn' => 1,
+ 'coverage' => 100,
+ 'crap' => '1',
+ 'link' => 'BankAccount.php.html#20',
+ 'methodName' => 'depositMoney',
+ 'visibility' => 'public',
+ ],
+ 'withdrawMoney' => [
+ 'signature' => 'withdrawMoney($balance)',
+ 'startLine' => 27,
+ 'endLine' => 32,
+ 'executableLines' => 2,
+ 'executedLines' => 2,
+ 'ccn' => 1,
+ 'coverage' => 100,
+ 'crap' => '1',
+ 'link' => 'BankAccount.php.html#27',
+ 'methodName' => 'withdrawMoney',
+ 'visibility' => 'public',
+ ],
+ ],
+ 'startLine' => 2,
+ 'executableLines' => 10,
+ 'executedLines' => 5,
+ 'ccn' => 5,
+ 'coverage' => 50,
+ 'crap' => '8.12',
+ 'package' => [
+ 'namespace' => '',
+ 'fullPackage' => '',
+ 'category' => '',
+ 'package' => '',
+ 'subpackage' => ''
+ ],
+ 'link' => 'BankAccount.php.html#2',
+ 'className' => 'BankAccount'
+ ]
+ ],
+ $root->getClasses()
+ );
+
+ $this->assertEquals([], $root->getFunctions());
+ }
+
+ public function testBuildDirectoryStructure()
+ {
+ $method = new \ReflectionMethod(
+ Builder::class,
+ 'buildDirectoryStructure'
+ );
+
+ $method->setAccessible(true);
+
+ $this->assertEquals(
+ [
+ 'src' => [
+ 'Money.php/f' => [],
+ 'MoneyBag.php/f' => []
+ ]
+ ],
+ $method->invoke(
+ $this->factory,
+ ['src/Money.php' => [], 'src/MoneyBag.php' => []]
+ )
+ );
+ }
+
+ /**
+ * @dataProvider reducePathsProvider
+ */
+ public function testReducePaths($reducedPaths, $commonPath, $paths)
+ {
+ $method = new \ReflectionMethod(
+ Builder::class,
+ 'reducePaths'
+ );
+
+ $method->setAccessible(true);
+
+ $_commonPath = $method->invokeArgs($this->factory, [&$paths]);
+
+ $this->assertEquals($reducedPaths, $paths);
+ $this->assertEquals($commonPath, $_commonPath);
+ }
+
+ public function reducePathsProvider()
+ {
+ return [
+ [
+ [
+ 'Money.php' => [],
+ 'MoneyBag.php' => []
+ ],
+ '/home/sb/Money',
+ [
+ '/home/sb/Money/Money.php' => [],
+ '/home/sb/Money/MoneyBag.php' => []
+ ]
+ ],
+ [
+ [
+ 'Money.php' => []
+ ],
+ '/home/sb/Money/',
+ [
+ '/home/sb/Money/Money.php' => []
+ ]
+ ],
+ [
+ [],
+ '.',
+ []
+ ],
+ [
+ [
+ 'Money.php' => [],
+ 'MoneyBag.php' => [],
+ 'Cash.phar/Cash.php' => [],
+ ],
+ '/home/sb/Money',
+ [
+ '/home/sb/Money/Money.php' => [],
+ '/home/sb/Money/MoneyBag.php' => [],
+ 'phar:///home/sb/Money/Cash.phar/Cash.php' => [],
+ ],
+ ],
+ ];
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/tests/CloverTest.php b/vendor/phpunit/php-code-coverage/tests/tests/CloverTest.php
new file mode 100644
index 0000000..85743ab
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/tests/CloverTest.php
@@ -0,0 +1,49 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report;
+
+use SebastianBergmann\CodeCoverage\TestCase;
+
+/**
+ * @covers SebastianBergmann\CodeCoverage\Report\Clover
+ */
+class CloverTest extends TestCase
+{
+ public function testCloverForBankAccountTest()
+ {
+ $clover = new Clover;
+
+ $this->assertStringMatchesFormatFile(
+ TEST_FILES_PATH . 'BankAccount-clover.xml',
+ $clover->process($this->getCoverageForBankAccount(), null, 'BankAccount')
+ );
+ }
+
+ public function testCloverForFileWithIgnoredLines()
+ {
+ $clover = new Clover;
+
+ $this->assertStringMatchesFormatFile(
+ TEST_FILES_PATH . 'ignored-lines-clover.xml',
+ $clover->process($this->getCoverageForFileWithIgnoredLines())
+ );
+ }
+
+ public function testCloverForClassWithAnonymousFunction()
+ {
+ $clover = new Clover;
+
+ $this->assertStringMatchesFormatFile(
+ TEST_FILES_PATH . 'class-with-anonymous-function-clover.xml',
+ $clover->process($this->getCoverageForClassWithAnonymousFunction())
+ );
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/tests/CodeCoverageTest.php b/vendor/phpunit/php-code-coverage/tests/tests/CodeCoverageTest.php
new file mode 100644
index 0000000..26438fe
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/tests/CodeCoverageTest.php
@@ -0,0 +1,547 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage;
+
+use SebastianBergmann\CodeCoverage\Driver\PHPDBG;
+use SebastianBergmann\CodeCoverage\Driver\Xdebug;
+
+/**
+ * @covers SebastianBergmann\CodeCoverage\CodeCoverage
+ */
+class CodeCoverageTest extends TestCase
+{
+ /**
+ * @var CodeCoverage
+ */
+ private $coverage;
+
+ protected function setUp()
+ {
+ $this->coverage = new CodeCoverage;
+ }
+
+ public function testCanBeConstructedForXdebugWithoutGivenFilterObject()
+ {
+ if (PHP_SAPI == 'phpdbg') {
+ $this->markTestSkipped('Requires PHP CLI and Xdebug');
+ }
+
+ $this->assertAttributeInstanceOf(
+ Xdebug::class,
+ 'driver',
+ $this->coverage
+ );
+
+ $this->assertAttributeInstanceOf(
+ Filter::class,
+ 'filter',
+ $this->coverage
+ );
+ }
+
+ public function testCanBeConstructedForXdebugWithGivenFilterObject()
+ {
+ if (PHP_SAPI == 'phpdbg') {
+ $this->markTestSkipped('Requires PHP CLI and Xdebug');
+ }
+
+ $filter = new Filter;
+ $coverage = new CodeCoverage(null, $filter);
+
+ $this->assertAttributeInstanceOf(
+ Xdebug::class,
+ 'driver',
+ $coverage
+ );
+
+ $this->assertSame($filter, $coverage->filter());
+ }
+
+ public function testCanBeConstructedForPhpdbgWithoutGivenFilterObject()
+ {
+ if (PHP_SAPI != 'phpdbg') {
+ $this->markTestSkipped('Requires PHPDBG');
+ }
+
+ $this->assertAttributeInstanceOf(
+ PHPDBG::class,
+ 'driver',
+ $this->coverage
+ );
+
+ $this->assertAttributeInstanceOf(
+ Filter::class,
+ 'filter',
+ $this->coverage
+ );
+ }
+
+ public function testCanBeConstructedForPhpdbgWithGivenFilterObject()
+ {
+ if (PHP_SAPI != 'phpdbg') {
+ $this->markTestSkipped('Requires PHPDBG');
+ }
+
+ $filter = new Filter;
+ $coverage = new CodeCoverage(null, $filter);
+
+ $this->assertAttributeInstanceOf(
+ PHPDBG::class,
+ 'driver',
+ $coverage
+ );
+
+ $this->assertSame($filter, $coverage->filter());
+ }
+
+ /**
+ * @expectedException SebastianBergmann\CodeCoverage\Exception
+ */
+ public function testCannotStartWithInvalidArgument()
+ {
+ $this->coverage->start(null, null);
+ }
+
+ /**
+ * @expectedException SebastianBergmann\CodeCoverage\Exception
+ */
+ public function testCannotStopWithInvalidFirstArgument()
+ {
+ $this->coverage->stop(null);
+ }
+
+ /**
+ * @expectedException SebastianBergmann\CodeCoverage\Exception
+ */
+ public function testCannotStopWithInvalidSecondArgument()
+ {
+ $this->coverage->stop(true, null);
+ }
+
+ /**
+ * @expectedException SebastianBergmann\CodeCoverage\Exception
+ */
+ public function testCannotAppendWithInvalidArgument()
+ {
+ $this->coverage->append([], null);
+ }
+
+ /**
+ * @expectedException SebastianBergmann\CodeCoverage\Exception
+ */
+ public function testSetCacheTokensThrowsExceptionForInvalidArgument()
+ {
+ $this->coverage->setCacheTokens(null);
+ }
+
+ public function testSetCacheTokens()
+ {
+ $this->coverage->setCacheTokens(true);
+ $this->assertAttributeEquals(true, 'cacheTokens', $this->coverage);
+ }
+
+ /**
+ * @expectedException SebastianBergmann\CodeCoverage\Exception
+ */
+ public function testSetCheckForUnintentionallyCoveredCodeThrowsExceptionForInvalidArgument()
+ {
+ $this->coverage->setCheckForUnintentionallyCoveredCode(null);
+ }
+
+ public function testSetCheckForUnintentionallyCoveredCode()
+ {
+ $this->coverage->setCheckForUnintentionallyCoveredCode(true);
+ $this->assertAttributeEquals(
+ true,
+ 'checkForUnintentionallyCoveredCode',
+ $this->coverage
+ );
+ }
+
+ /**
+ * @expectedException SebastianBergmann\CodeCoverage\Exception
+ */
+ public function testSetForceCoversAnnotationThrowsExceptionForInvalidArgument()
+ {
+ $this->coverage->setForceCoversAnnotation(null);
+ }
+
+ public function testSetCheckForMissingCoversAnnotation()
+ {
+ $this->coverage->setCheckForMissingCoversAnnotation(true);
+ $this->assertAttributeEquals(
+ true,
+ 'checkForMissingCoversAnnotation',
+ $this->coverage
+ );
+ }
+
+ /**
+ * @expectedException SebastianBergmann\CodeCoverage\Exception
+ */
+ public function testSetCheckForMissingCoversAnnotationThrowsExceptionForInvalidArgument()
+ {
+ $this->coverage->setCheckForMissingCoversAnnotation(null);
+ }
+
+ public function testSetForceCoversAnnotation()
+ {
+ $this->coverage->setForceCoversAnnotation(true);
+ $this->assertAttributeEquals(
+ true,
+ 'forceCoversAnnotation',
+ $this->coverage
+ );
+ }
+
+ /**
+ * @expectedException SebastianBergmann\CodeCoverage\Exception
+ */
+ public function testSetCheckForUnexecutedCoveredCodeThrowsExceptionForInvalidArgument()
+ {
+ $this->coverage->setCheckForUnexecutedCoveredCode(null);
+ }
+
+ public function testSetCheckForUnexecutedCoveredCode()
+ {
+ $this->coverage->setCheckForUnexecutedCoveredCode(true);
+ $this->assertAttributeEquals(
+ true,
+ 'checkForUnexecutedCoveredCode',
+ $this->coverage
+ );
+ }
+
+ /**
+ * @expectedException SebastianBergmann\CodeCoverage\Exception
+ */
+ public function testSetAddUncoveredFilesFromWhitelistThrowsExceptionForInvalidArgument()
+ {
+ $this->coverage->setAddUncoveredFilesFromWhitelist(null);
+ }
+
+ public function testSetAddUncoveredFilesFromWhitelist()
+ {
+ $this->coverage->setAddUncoveredFilesFromWhitelist(true);
+ $this->assertAttributeEquals(
+ true,
+ 'addUncoveredFilesFromWhitelist',
+ $this->coverage
+ );
+ }
+
+ /**
+ * @expectedException SebastianBergmann\CodeCoverage\Exception
+ */
+ public function testSetProcessUncoveredFilesFromWhitelistThrowsExceptionForInvalidArgument()
+ {
+ $this->coverage->setProcessUncoveredFilesFromWhitelist(null);
+ }
+
+ public function testSetProcessUncoveredFilesFromWhitelist()
+ {
+ $this->coverage->setProcessUncoveredFilesFromWhitelist(true);
+ $this->assertAttributeEquals(
+ true,
+ 'processUncoveredFilesFromWhitelist',
+ $this->coverage
+ );
+ }
+
+ public function testSetIgnoreDeprecatedCode()
+ {
+ $this->coverage->setIgnoreDeprecatedCode(true);
+ $this->assertAttributeEquals(
+ true,
+ 'ignoreDeprecatedCode',
+ $this->coverage
+ );
+ }
+
+ /**
+ * @expectedException SebastianBergmann\CodeCoverage\Exception
+ */
+ public function testSetIgnoreDeprecatedCodeThrowsExceptionForInvalidArgument()
+ {
+ $this->coverage->setIgnoreDeprecatedCode(null);
+ }
+
+ public function testClear()
+ {
+ $this->coverage->clear();
+
+ $this->assertAttributeEquals(null, 'currentId', $this->coverage);
+ $this->assertAttributeEquals([], 'data', $this->coverage);
+ $this->assertAttributeEquals([], 'tests', $this->coverage);
+ }
+
+ public function testCollect()
+ {
+ $coverage = $this->getCoverageForBankAccount();
+
+ $this->assertEquals(
+ $this->getExpectedDataArrayForBankAccount(),
+ $coverage->getData()
+ );
+
+ if (version_compare(\PHPUnit_Runner_Version::id(), '4.7', '>=')) {
+ $size = 'unknown';
+ } else {
+ $size = 'small';
+ }
+
+ $this->assertEquals(
+ [
+ 'BankAccountTest::testBalanceIsInitiallyZero' => ['size' => $size, 'status' => null],
+ 'BankAccountTest::testBalanceCannotBecomeNegative' => ['size' => $size, 'status' => null],
+ 'BankAccountTest::testBalanceCannotBecomeNegative2' => ['size' => $size, 'status' => null],
+ 'BankAccountTest::testDepositWithdrawMoney' => ['size' => $size, 'status' => null]
+ ],
+ $coverage->getTests()
+ );
+ }
+
+ public function testMerge()
+ {
+ $coverage = $this->getCoverageForBankAccountForFirstTwoTests();
+ $coverage->merge($this->getCoverageForBankAccountForLastTwoTests());
+
+ $this->assertEquals(
+ $this->getExpectedDataArrayForBankAccount(),
+ $coverage->getData()
+ );
+ }
+
+ public function testMerge2()
+ {
+ $coverage = new CodeCoverage(
+ $this->createMock(Xdebug::class),
+ new Filter
+ );
+
+ $coverage->merge($this->getCoverageForBankAccount());
+
+ $this->assertEquals(
+ $this->getExpectedDataArrayForBankAccount(),
+ $coverage->getData()
+ );
+ }
+
+ public function testGetLinesToBeIgnored()
+ {
+ $this->assertEquals(
+ [
+ 1,
+ 3,
+ 4,
+ 5,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16,
+ 17,
+ 18,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 30,
+ 32,
+ 33,
+ 34,
+ 35,
+ 36,
+ 37,
+ 38
+ ],
+ $this->getLinesToBeIgnored()->invoke(
+ $this->coverage,
+ TEST_FILES_PATH . 'source_with_ignore.php'
+ )
+ );
+ }
+
+ public function testGetLinesToBeIgnored2()
+ {
+ $this->assertEquals(
+ [1, 5],
+ $this->getLinesToBeIgnored()->invoke(
+ $this->coverage,
+ TEST_FILES_PATH . 'source_without_ignore.php'
+ )
+ );
+ }
+
+ public function testGetLinesToBeIgnored3()
+ {
+ $this->assertEquals(
+ [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 8,
+ 11,
+ 15,
+ 16,
+ 19,
+ 20
+ ],
+ $this->getLinesToBeIgnored()->invoke(
+ $this->coverage,
+ TEST_FILES_PATH . 'source_with_class_and_anonymous_function.php'
+ )
+ );
+ }
+
+ public function testGetLinesToBeIgnoredOneLineAnnotations()
+ {
+ $this->assertEquals(
+ [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16,
+ 18,
+ 20,
+ 21,
+ 23,
+ 24,
+ 25,
+ 27,
+ 28,
+ 29,
+ 30,
+ 31,
+ 32,
+ 33,
+ 34,
+ 37
+ ],
+ $this->getLinesToBeIgnored()->invoke(
+ $this->coverage,
+ TEST_FILES_PATH . 'source_with_oneline_annotations.php'
+ )
+ );
+ }
+
+ /**
+ * @return \ReflectionMethod
+ */
+ private function getLinesToBeIgnored()
+ {
+ $getLinesToBeIgnored = new \ReflectionMethod(
+ 'SebastianBergmann\CodeCoverage\CodeCoverage',
+ 'getLinesToBeIgnored'
+ );
+
+ $getLinesToBeIgnored->setAccessible(true);
+
+ return $getLinesToBeIgnored;
+ }
+
+ public function testGetLinesToBeIgnoredWhenIgnoreIsDisabled()
+ {
+ $this->coverage->setDisableIgnoredLines(true);
+
+ $this->assertEquals(
+ [],
+ $this->getLinesToBeIgnored()->invoke(
+ $this->coverage,
+ TEST_FILES_PATH . 'source_with_ignore.php'
+ )
+ );
+ }
+
+ /**
+ * @expectedException SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException
+ */
+ public function testAppendThrowsExceptionIfCoveredCodeWasNotExecuted()
+ {
+ $this->coverage->filter()->addDirectoryToWhitelist(TEST_FILES_PATH);
+ $this->coverage->setCheckForUnexecutedCoveredCode(true);
+
+ $data = [
+ TEST_FILES_PATH . 'BankAccount.php' => [
+ 29 => -1,
+ 31 => -1
+ ]
+ ];
+
+ $linesToBeCovered = [
+ TEST_FILES_PATH . 'BankAccount.php' => [
+ 22,
+ 24
+ ]
+ ];
+
+ $linesToBeUsed = [];
+
+ $this->coverage->append($data, 'File1.php', true, $linesToBeCovered, $linesToBeUsed);
+ }
+
+ /**
+ * @expectedException SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException
+ */
+ public function testAppendThrowsExceptionIfUsedCodeWasNotExecuted()
+ {
+ $this->coverage->filter()->addDirectoryToWhitelist(TEST_FILES_PATH);
+ $this->coverage->setCheckForUnexecutedCoveredCode(true);
+
+ $data = [
+ TEST_FILES_PATH . 'BankAccount.php' => [
+ 29 => -1,
+ 31 => -1
+ ]
+ ];
+
+ $linesToBeCovered = [
+ TEST_FILES_PATH . 'BankAccount.php' => [
+ 29,
+ 31
+ ]
+ ];
+
+ $linesToBeUsed = [
+ TEST_FILES_PATH . 'BankAccount.php' => [
+ 22,
+ 24
+ ]
+ ];
+
+ $this->coverage->append($data, 'File1.php', true, $linesToBeCovered, $linesToBeUsed);
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/tests/Crap4jTest.php b/vendor/phpunit/php-code-coverage/tests/tests/Crap4jTest.php
new file mode 100644
index 0000000..faa1ac5
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/tests/Crap4jTest.php
@@ -0,0 +1,49 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report;
+
+use SebastianBergmann\CodeCoverage\TestCase;
+
+/**
+ * @covers SebastianBergmann\CodeCoverage\Report\Crap4j
+ */
+class Crap4jTest extends TestCase
+{
+ public function testForBankAccountTest()
+ {
+ $crap4j = new Crap4j;
+
+ $this->assertStringMatchesFormatFile(
+ TEST_FILES_PATH . 'BankAccount-crap4j.xml',
+ $crap4j->process($this->getCoverageForBankAccount(), null, 'BankAccount')
+ );
+ }
+
+ public function testForFileWithIgnoredLines()
+ {
+ $crap4j = new Crap4j;
+
+ $this->assertStringMatchesFormatFile(
+ TEST_FILES_PATH . 'ignored-lines-crap4j.xml',
+ $crap4j->process($this->getCoverageForFileWithIgnoredLines(), null, 'CoverageForFileWithIgnoredLines')
+ );
+ }
+
+ public function testForClassWithAnonymousFunction()
+ {
+ $crap4j = new Crap4j;
+
+ $this->assertStringMatchesFormatFile(
+ TEST_FILES_PATH . 'class-with-anonymous-function-crap4j.xml',
+ $crap4j->process($this->getCoverageForClassWithAnonymousFunction(), null, 'CoverageForClassWithAnonymousFunction')
+ );
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/tests/FilterTest.php b/vendor/phpunit/php-code-coverage/tests/tests/FilterTest.php
new file mode 100644
index 0000000..47ff21a
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/tests/FilterTest.php
@@ -0,0 +1,194 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage;
+
+class FilterTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var Filter
+ */
+ private $filter;
+
+ /**
+ * @var array
+ */
+ private $files = [];
+
+ protected function setUp()
+ {
+ $this->filter = unserialize('O:37:"SebastianBergmann\CodeCoverage\Filter":0:{}');
+
+ $this->files = [
+ TEST_FILES_PATH . 'BankAccount.php',
+ TEST_FILES_PATH . 'BankAccountTest.php',
+ TEST_FILES_PATH . 'CoverageClassExtendedTest.php',
+ TEST_FILES_PATH . 'CoverageClassTest.php',
+ TEST_FILES_PATH . 'CoverageFunctionParenthesesTest.php',
+ TEST_FILES_PATH . 'CoverageFunctionParenthesesWhitespaceTest.php',
+ TEST_FILES_PATH . 'CoverageFunctionTest.php',
+ TEST_FILES_PATH . 'CoverageMethodOneLineAnnotationTest.php',
+ TEST_FILES_PATH . 'CoverageMethodParenthesesTest.php',
+ TEST_FILES_PATH . 'CoverageMethodParenthesesWhitespaceTest.php',
+ TEST_FILES_PATH . 'CoverageMethodTest.php',
+ TEST_FILES_PATH . 'CoverageNoneTest.php',
+ TEST_FILES_PATH . 'CoverageNotPrivateTest.php',
+ TEST_FILES_PATH . 'CoverageNotProtectedTest.php',
+ TEST_FILES_PATH . 'CoverageNotPublicTest.php',
+ TEST_FILES_PATH . 'CoverageNothingTest.php',
+ TEST_FILES_PATH . 'CoveragePrivateTest.php',
+ TEST_FILES_PATH . 'CoverageProtectedTest.php',
+ TEST_FILES_PATH . 'CoveragePublicTest.php',
+ TEST_FILES_PATH . 'CoverageTwoDefaultClassAnnotations.php',
+ TEST_FILES_PATH . 'CoveredClass.php',
+ TEST_FILES_PATH . 'CoveredFunction.php',
+ TEST_FILES_PATH . 'NamespaceCoverageClassExtendedTest.php',
+ TEST_FILES_PATH . 'NamespaceCoverageClassTest.php',
+ TEST_FILES_PATH . 'NamespaceCoverageCoversClassPublicTest.php',
+ TEST_FILES_PATH . 'NamespaceCoverageCoversClassTest.php',
+ TEST_FILES_PATH . 'NamespaceCoverageMethodTest.php',
+ TEST_FILES_PATH . 'NamespaceCoverageNotPrivateTest.php',
+ TEST_FILES_PATH . 'NamespaceCoverageNotProtectedTest.php',
+ TEST_FILES_PATH . 'NamespaceCoverageNotPublicTest.php',
+ TEST_FILES_PATH . 'NamespaceCoveragePrivateTest.php',
+ TEST_FILES_PATH . 'NamespaceCoverageProtectedTest.php',
+ TEST_FILES_PATH . 'NamespaceCoveragePublicTest.php',
+ TEST_FILES_PATH . 'NamespaceCoveredClass.php',
+ TEST_FILES_PATH . 'NotExistingCoveredElementTest.php',
+ TEST_FILES_PATH . 'source_with_class_and_anonymous_function.php',
+ TEST_FILES_PATH . 'source_with_ignore.php',
+ TEST_FILES_PATH . 'source_with_namespace.php',
+ TEST_FILES_PATH . 'source_with_oneline_annotations.php',
+ TEST_FILES_PATH . 'source_without_ignore.php',
+ TEST_FILES_PATH . 'source_without_namespace.php'
+ ];
+ }
+
+ /**
+ * @covers SebastianBergmann\CodeCoverage\Filter::addFileToWhitelist
+ * @covers SebastianBergmann\CodeCoverage\Filter::getWhitelist
+ */
+ public function testAddingAFileToTheWhitelistWorks()
+ {
+ $this->filter->addFileToWhitelist($this->files[0]);
+
+ $this->assertEquals(
+ [$this->files[0]],
+ $this->filter->getWhitelist()
+ );
+ }
+
+ /**
+ * @covers SebastianBergmann\CodeCoverage\Filter::removeFileFromWhitelist
+ * @covers SebastianBergmann\CodeCoverage\Filter::getWhitelist
+ */
+ public function testRemovingAFileFromTheWhitelistWorks()
+ {
+ $this->filter->addFileToWhitelist($this->files[0]);
+ $this->filter->removeFileFromWhitelist($this->files[0]);
+
+ $this->assertEquals([], $this->filter->getWhitelist());
+ }
+
+ /**
+ * @covers SebastianBergmann\CodeCoverage\Filter::addDirectoryToWhitelist
+ * @covers SebastianBergmann\CodeCoverage\Filter::getWhitelist
+ * @depends testAddingAFileToTheWhitelistWorks
+ */
+ public function testAddingADirectoryToTheWhitelistWorks()
+ {
+ $this->filter->addDirectoryToWhitelist(TEST_FILES_PATH);
+
+ $whitelist = $this->filter->getWhitelist();
+ sort($whitelist);
+
+ $this->assertEquals($this->files, $whitelist);
+ }
+
+ /**
+ * @covers SebastianBergmann\CodeCoverage\Filter::addFilesToWhitelist
+ * @covers SebastianBergmann\CodeCoverage\Filter::getWhitelist
+ */
+ public function testAddingFilesToTheWhitelistWorks()
+ {
+ $facade = new \File_Iterator_Facade;
+
+ $files = $facade->getFilesAsArray(
+ TEST_FILES_PATH,
+ $suffixes = '.php'
+ );
+
+ $this->filter->addFilesToWhitelist($files);
+
+ $whitelist = $this->filter->getWhitelist();
+ sort($whitelist);
+
+ $this->assertEquals($this->files, $whitelist);
+ }
+
+ /**
+ * @covers SebastianBergmann\CodeCoverage\Filter::removeDirectoryFromWhitelist
+ * @covers SebastianBergmann\CodeCoverage\Filter::getWhitelist
+ * @depends testAddingADirectoryToTheWhitelistWorks
+ */
+ public function testRemovingADirectoryFromTheWhitelistWorks()
+ {
+ $this->filter->addDirectoryToWhitelist(TEST_FILES_PATH);
+ $this->filter->removeDirectoryFromWhitelist(TEST_FILES_PATH);
+
+ $this->assertEquals([], $this->filter->getWhitelist());
+ }
+
+ /**
+ * @covers SebastianBergmann\CodeCoverage\Filter::isFile
+ */
+ public function testIsFile()
+ {
+ $this->assertFalse($this->filter->isFile('vfs://root/a/path'));
+ $this->assertFalse($this->filter->isFile('xdebug://debug-eval'));
+ $this->assertFalse($this->filter->isFile('eval()\'d code'));
+ $this->assertFalse($this->filter->isFile('runtime-created function'));
+ $this->assertFalse($this->filter->isFile('assert code'));
+ $this->assertFalse($this->filter->isFile('regexp code'));
+ $this->assertTrue($this->filter->isFile(__FILE__));
+ }
+
+ /**
+ * @covers SebastianBergmann\CodeCoverage\Filter::isFiltered
+ */
+ public function testWhitelistedFileIsNotFiltered()
+ {
+ $this->filter->addFileToWhitelist($this->files[0]);
+ $this->assertFalse($this->filter->isFiltered($this->files[0]));
+ }
+
+ /**
+ * @covers SebastianBergmann\CodeCoverage\Filter::isFiltered
+ */
+ public function testNotWhitelistedFileIsFiltered()
+ {
+ $this->filter->addFileToWhitelist($this->files[0]);
+ $this->assertTrue($this->filter->isFiltered($this->files[1]));
+ }
+
+ /**
+ * @covers SebastianBergmann\CodeCoverage\Filter::isFiltered
+ * @covers SebastianBergmann\CodeCoverage\Filter::isFile
+ */
+ public function testNonFilesAreFiltered()
+ {
+ $this->assertTrue($this->filter->isFiltered('vfs://root/a/path'));
+ $this->assertTrue($this->filter->isFiltered('xdebug://debug-eval'));
+ $this->assertTrue($this->filter->isFiltered('eval()\'d code'));
+ $this->assertTrue($this->filter->isFiltered('runtime-created function'));
+ $this->assertTrue($this->filter->isFiltered('assert code'));
+ $this->assertTrue($this->filter->isFiltered('regexp code'));
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/tests/HTMLTest.php b/vendor/phpunit/php-code-coverage/tests/tests/HTMLTest.php
new file mode 100644
index 0000000..48353f0
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/tests/HTMLTest.php
@@ -0,0 +1,103 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Html;
+
+use SebastianBergmann\CodeCoverage\TestCase;
+
+class HTMLTest extends TestCase
+{
+ private static $TEST_REPORT_PATH_SOURCE;
+
+ public static function setUpBeforeClass()
+ {
+ parent::setUpBeforeClass();
+
+ self::$TEST_REPORT_PATH_SOURCE = TEST_FILES_PATH . 'Report' . DIRECTORY_SEPARATOR . 'HTML';
+ }
+
+ protected function tearDown()
+ {
+ parent::tearDown();
+
+ $tmpFilesIterator = new \RecursiveIteratorIterator(
+ new \RecursiveDirectoryIterator(self::$TEST_TMP_PATH, \RecursiveDirectoryIterator::SKIP_DOTS),
+ \RecursiveIteratorIterator::CHILD_FIRST
+ );
+
+ foreach ($tmpFilesIterator as $path => $fileInfo) {
+ /* @var \SplFileInfo $fileInfo */
+ $pathname = $fileInfo->getPathname();
+ $fileInfo->isDir() ? rmdir($pathname) : unlink($pathname);
+ }
+ }
+
+ public function testForBankAccountTest()
+ {
+ $expectedFilesPath = self::$TEST_REPORT_PATH_SOURCE . DIRECTORY_SEPARATOR . 'CoverageForBankAccount';
+
+ $report = new Facade;
+ $report->process($this->getCoverageForBankAccount(), self::$TEST_TMP_PATH);
+
+ $this->assertFilesEquals($expectedFilesPath, self::$TEST_TMP_PATH);
+ }
+
+ public function testForFileWithIgnoredLines()
+ {
+ $expectedFilesPath = self::$TEST_REPORT_PATH_SOURCE . DIRECTORY_SEPARATOR . 'CoverageForFileWithIgnoredLines';
+
+ $report = new Facade;
+ $report->process($this->getCoverageForFileWithIgnoredLines(), self::$TEST_TMP_PATH);
+
+ $this->assertFilesEquals($expectedFilesPath, self::$TEST_TMP_PATH);
+ }
+
+ public function testForClassWithAnonymousFunction()
+ {
+ $expectedFilesPath =
+ self::$TEST_REPORT_PATH_SOURCE . DIRECTORY_SEPARATOR . 'CoverageForClassWithAnonymousFunction';
+
+ $report = new Facade;
+ $report->process($this->getCoverageForClassWithAnonymousFunction(), self::$TEST_TMP_PATH);
+
+ $this->assertFilesEquals($expectedFilesPath, self::$TEST_TMP_PATH);
+ }
+
+ /**
+ * @param string $expectedFilesPath
+ * @param string $actualFilesPath
+ */
+ private function assertFilesEquals($expectedFilesPath, $actualFilesPath)
+ {
+ $expectedFilesIterator = new \FilesystemIterator($expectedFilesPath);
+ $actualFilesIterator = new \RegexIterator(new \FilesystemIterator($actualFilesPath), '/.html/');
+
+ $this->assertEquals(
+ iterator_count($expectedFilesIterator),
+ iterator_count($actualFilesIterator),
+ 'Generated files and expected files not match'
+ );
+
+ foreach ($expectedFilesIterator as $path => $fileInfo) {
+ /* @var \SplFileInfo $fileInfo */
+ $filename = $fileInfo->getFilename();
+
+ $actualFile = $actualFilesPath . DIRECTORY_SEPARATOR . $filename;
+
+ $this->assertFileExists($actualFile);
+
+ $this->assertStringMatchesFormatFile(
+ $fileInfo->getPathname(),
+ str_replace(PHP_EOL, "\n", file_get_contents($actualFile)),
+ "${filename} not match"
+ );
+ }
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/tests/TextTest.php b/vendor/phpunit/php-code-coverage/tests/tests/TextTest.php
new file mode 100644
index 0000000..04da00a
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/tests/TextTest.php
@@ -0,0 +1,49 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report;
+
+use SebastianBergmann\CodeCoverage\TestCase;
+
+/**
+ * @covers SebastianBergmann\CodeCoverage\Report\Text
+ */
+class TextTest extends TestCase
+{
+ public function testTextForBankAccountTest()
+ {
+ $text = new Text(50, 90, false, false);
+
+ $this->assertStringMatchesFormatFile(
+ TEST_FILES_PATH . 'BankAccount-text.txt',
+ str_replace(PHP_EOL, "\n", $text->process($this->getCoverageForBankAccount()))
+ );
+ }
+
+ public function testTextForFileWithIgnoredLines()
+ {
+ $text = new Text(50, 90, false, false);
+
+ $this->assertStringMatchesFormatFile(
+ TEST_FILES_PATH . 'ignored-lines-text.txt',
+ str_replace(PHP_EOL, "\n", $text->process($this->getCoverageForFileWithIgnoredLines()))
+ );
+ }
+
+ public function testTextForClassWithAnonymousFunction()
+ {
+ $text = new Text(50, 90, false, false);
+
+ $this->assertStringMatchesFormatFile(
+ TEST_FILES_PATH . 'class-with-anonymous-function-text.txt',
+ str_replace(PHP_EOL, "\n", $text->process($this->getCoverageForClassWithAnonymousFunction()))
+ );
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/tests/UtilTest.php b/vendor/phpunit/php-code-coverage/tests/tests/UtilTest.php
new file mode 100644
index 0000000..c29b693
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/tests/UtilTest.php
@@ -0,0 +1,27 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage;
+
+/**
+ * @covers SebastianBergmann\CodeCoverage\Util
+ */
+class UtilTest extends \PHPUnit_Framework_TestCase
+{
+ public function testPercent()
+ {
+ $this->assertEquals(100, Util::percent(100, 0));
+ $this->assertEquals(100, Util::percent(100, 100));
+ $this->assertEquals(
+ '100.00%',
+ Util::percent(100, 100, true)
+ );
+ }
+}
diff --git a/vendor/phpunit/php-code-coverage/tests/tests/XMLTest.php b/vendor/phpunit/php-code-coverage/tests/tests/XMLTest.php
new file mode 100644
index 0000000..7ce8db3
--- /dev/null
+++ b/vendor/phpunit/php-code-coverage/tests/tests/XMLTest.php
@@ -0,0 +1,99 @@
+<?php
+/*
+ * This file is part of the php-code-coverage package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeCoverage\Report\Xml;
+
+use SebastianBergmann\CodeCoverage\TestCase;
+
+class XMLTest extends TestCase
+{
+ private static $TEST_REPORT_PATH_SOURCE;
+
+ public static function setUpBeforeClass()
+ {
+ parent::setUpBeforeClass();
+
+ self::$TEST_REPORT_PATH_SOURCE = TEST_FILES_PATH . 'Report' . DIRECTORY_SEPARATOR . 'XML';
+ }
+
+ protected function tearDown()
+ {
+ parent::tearDown();
+
+ $tmpFilesIterator = new \FilesystemIterator(self::$TEST_TMP_PATH);
+
+ foreach ($tmpFilesIterator as $path => $fileInfo) {
+ /* @var \SplFileInfo $fileInfo */
+ unlink($fileInfo->getPathname());
+ }
+ }
+
+ public function testForBankAccountTest()
+ {
+ $expectedFilesPath = self::$TEST_REPORT_PATH_SOURCE . DIRECTORY_SEPARATOR . 'CoverageForBankAccount';
+
+ $xml = new Facade;
+ $xml->process($this->getCoverageForBankAccount(), self::$TEST_TMP_PATH);
+
+ $this->assertFilesEquals($expectedFilesPath, self::$TEST_TMP_PATH);
+ }
+
+ public function testForFileWithIgnoredLines()
+ {
+ $expectedFilesPath = self::$TEST_REPORT_PATH_SOURCE . DIRECTORY_SEPARATOR . 'CoverageForFileWithIgnoredLines';
+
+ $xml = new Facade;
+ $xml->process($this->getCoverageForFileWithIgnoredLines(), self::$TEST_TMP_PATH);
+
+ $this->assertFilesEquals($expectedFilesPath, self::$TEST_TMP_PATH);
+ }
+
+ public function testForClassWithAnonymousFunction()
+ {
+ $expectedFilesPath =
+ self::$TEST_REPORT_PATH_SOURCE . DIRECTORY_SEPARATOR . 'CoverageForClassWithAnonymousFunction';
+
+ $xml = new Facade;
+ $xml->process($this->getCoverageForClassWithAnonymousFunction(), self::$TEST_TMP_PATH);
+
+ $this->assertFilesEquals($expectedFilesPath, self::$TEST_TMP_PATH);
+ }
+
+ /**
+ * @param string $expectedFilesPath
+ * @param string $actualFilesPath
+ */
+ private function assertFilesEquals($expectedFilesPath, $actualFilesPath)
+ {
+ $expectedFilesIterator = new \FilesystemIterator($expectedFilesPath);
+ $actualFilesIterator = new \FilesystemIterator($actualFilesPath);
+
+ $this->assertEquals(
+ iterator_count($expectedFilesIterator),
+ iterator_count($actualFilesIterator),
+ 'Generated files and expected files not match'
+ );
+
+ foreach ($expectedFilesIterator as $path => $fileInfo) {
+ /* @var \SplFileInfo $fileInfo */
+ $filename = $fileInfo->getFilename();
+
+ $actualFile = $actualFilesPath . DIRECTORY_SEPARATOR . $filename;
+
+ $this->assertFileExists($actualFile);
+
+ $this->assertStringMatchesFormatFile(
+ $fileInfo->getPathname(),
+ file_get_contents($actualFile),
+ "${filename} not match"
+ );
+ }
+ }
+}
diff --git a/vendor/phpunit/php-file-iterator/.gitattributes b/vendor/phpunit/php-file-iterator/.gitattributes
new file mode 100644
index 0000000..461090b
--- /dev/null
+++ b/vendor/phpunit/php-file-iterator/.gitattributes
@@ -0,0 +1 @@
+*.php diff=php
diff --git a/vendor/phpunit/php-file-iterator/.gitignore b/vendor/phpunit/php-file-iterator/.gitignore
new file mode 100644
index 0000000..a741983
--- /dev/null
+++ b/vendor/phpunit/php-file-iterator/.gitignore
@@ -0,0 +1,7 @@
+build/api
+build/code-browser
+build/coverage
+build/logs
+build/pdepend
+cache.properties
+phpunit.xml
diff --git a/vendor/phpunit/php-file-iterator/ChangeLog.md b/vendor/phpunit/php-file-iterator/ChangeLog.md
new file mode 100644
index 0000000..5c842c6
--- /dev/null
+++ b/vendor/phpunit/php-file-iterator/ChangeLog.md
@@ -0,0 +1,41 @@
+# Change Log
+
+All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).
+
+## [1.4.5] - 2017-11-27
+
+### Fixed
+
+* Fixed [#37](https://github.com/sebastianbergmann/php-file-iterator/issues/37): Regression caused by fix for [#30](https://github.com/sebastianbergmann/php-file-iterator/issues/30)
+
+## [1.4.4] - 2017-11-27
+
+### Fixed
+
+* Fixed [#30](https://github.com/sebastianbergmann/php-file-iterator/issues/30): Exclude is not considered if it is a parent of the base path
+
+## [1.4.3] - 2017-11-25
+
+### Fixed
+
+* Fixed [#34](https://github.com/sebastianbergmann/php-file-iterator/issues/34): Factory should use canonical directory names
+
+## [1.4.2] - 2016-11-26
+
+No changes
+
+## [1.4.1] - 2015-07-26
+
+No changes
+
+## 1.4.0 - 2015-04-02
+
+### Added
+
+* [Added support for wildcards (glob) in exclude](https://github.com/sebastianbergmann/php-file-iterator/pull/23)
+
+[1.4.5]: https://github.com/sebastianbergmann/php-file-iterator/compare/1.4.4...1.4.5
+[1.4.4]: https://github.com/sebastianbergmann/php-file-iterator/compare/1.4.3...1.4.4
+[1.4.3]: https://github.com/sebastianbergmann/php-file-iterator/compare/1.4.2...1.4.3
+[1.4.2]: https://github.com/sebastianbergmann/php-file-iterator/compare/1.4.1...1.4.2
+[1.4.1]: https://github.com/sebastianbergmann/php-file-iterator/compare/1.4.0...1.4.1
diff --git a/vendor/phpunit/php-file-iterator/LICENSE b/vendor/phpunit/php-file-iterator/LICENSE
new file mode 100644
index 0000000..6cccbbb
--- /dev/null
+++ b/vendor/phpunit/php-file-iterator/LICENSE
@@ -0,0 +1,33 @@
+File_Iterator
+
+Copyright (c) 2009-2015, Sebastian Bergmann <sebastian@phpunit.de>.
+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/phpunit/php-file-iterator/README.md b/vendor/phpunit/php-file-iterator/README.md
new file mode 100644
index 0000000..8f2caf2
--- /dev/null
+++ b/vendor/phpunit/php-file-iterator/README.md
@@ -0,0 +1,12 @@
+# File_Iterator
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+ composer require phpunit/php-file-iterator
+
+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 phpunit/php-file-iterator
+
diff --git a/vendor/phpunit/php-file-iterator/composer.json b/vendor/phpunit/php-file-iterator/composer.json
new file mode 100644
index 0000000..c652794
--- /dev/null
+++ b/vendor/phpunit/php-file-iterator/composer.json
@@ -0,0 +1,36 @@
+{
+ "name": "phpunit/php-file-iterator",
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+ "type": "library",
+ "keywords": [
+ "iterator",
+ "filesystem"
+ ],
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
+ "irc": "irc://irc.freenode.net/phpunit"
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4.x-dev"
+ }
+ }
+}
+
diff --git a/vendor/phpunit/php-file-iterator/src/Facade.php b/vendor/phpunit/php-file-iterator/src/Facade.php
new file mode 100644
index 0000000..902a0af
--- /dev/null
+++ b/vendor/phpunit/php-file-iterator/src/Facade.php
@@ -0,0 +1,123 @@
+<?php
+/*
+ * This file is part of the File_Iterator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Façade implementation that uses File_Iterator_Factory to create a
+ * File_Iterator that operates on an AppendIterator that contains an
+ * RecursiveDirectoryIterator for each given path. The list of unique
+ * files is returned as an array.
+ *
+ * @since Class available since Release 1.3.0
+ */
+class File_Iterator_Facade
+{
+ /**
+ * @param array|string $paths
+ * @param array|string $suffixes
+ * @param array|string $prefixes
+ * @param array $exclude
+ * @param bool $commonPath
+ * @return array
+ */
+ public function getFilesAsArray($paths, $suffixes = '', $prefixes = '', array $exclude = array(), $commonPath = FALSE)
+ {
+ if (is_string($paths)) {
+ $paths = array($paths);
+ }
+
+ $factory = new File_Iterator_Factory;
+ $iterator = $factory->getFileIterator(
+ $paths, $suffixes, $prefixes, $exclude
+ );
+
+ $files = array();
+
+ foreach ($iterator as $file) {
+ $file = $file->getRealPath();
+
+ if ($file) {
+ $files[] = $file;
+ }
+ }
+
+ foreach ($paths as $path) {
+ if (is_file($path)) {
+ $files[] = realpath($path);
+ }
+ }
+
+ $files = array_unique($files);
+ sort($files);
+
+ if ($commonPath) {
+ return array(
+ 'commonPath' => $this->getCommonPath($files),
+ 'files' => $files
+ );
+ } else {
+ return $files;
+ }
+ }
+
+ /**
+ * Returns the common path of a set of files.
+ *
+ * @param array $files
+ * @return string
+ */
+ protected function getCommonPath(array $files)
+ {
+ $count = count($files);
+
+ if ($count == 0) {
+ return '';
+ }
+
+ if ($count == 1) {
+ return dirname($files[0]) . DIRECTORY_SEPARATOR;
+ }
+
+ $_files = array();
+
+ foreach ($files as $file) {
+ $_files[] = $_fileParts = explode(DIRECTORY_SEPARATOR, $file);
+
+ if (empty($_fileParts[0])) {
+ $_fileParts[0] = DIRECTORY_SEPARATOR;
+ }
+ }
+
+ $common = '';
+ $done = FALSE;
+ $j = 0;
+ $count--;
+
+ while (!$done) {
+ for ($i = 0; $i < $count; $i++) {
+ if ($_files[$i][$j] != $_files[$i+1][$j]) {
+ $done = TRUE;
+ break;
+ }
+ }
+
+ if (!$done) {
+ $common .= $_files[0][$j];
+
+ if ($j > 0) {
+ $common .= DIRECTORY_SEPARATOR;
+ }
+ }
+
+ $j++;
+ }
+
+ return DIRECTORY_SEPARATOR . $common;
+ }
+}
diff --git a/vendor/phpunit/php-file-iterator/src/Factory.php b/vendor/phpunit/php-file-iterator/src/Factory.php
new file mode 100644
index 0000000..9cc3fb7
--- /dev/null
+++ b/vendor/phpunit/php-file-iterator/src/Factory.php
@@ -0,0 +1,91 @@
+<?php
+/*
+ * This file is part of the File_Iterator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Factory Method implementation that creates a File_Iterator that operates on
+ * an AppendIterator that contains an RecursiveDirectoryIterator for each given
+ * path.
+ *
+ * @since Class available since Release 1.1.0
+ */
+class File_Iterator_Factory
+{
+ /**
+ * @param array|string $paths
+ * @param array|string $suffixes
+ * @param array|string $prefixes
+ * @param array $exclude
+ * @return AppendIterator
+ */
+ public function getFileIterator($paths, $suffixes = '', $prefixes = '', array $exclude = array())
+ {
+ if (is_string($paths)) {
+ $paths = array($paths);
+ }
+
+ $paths = $this->getPathsAfterResolvingWildcards($paths);
+ $exclude = $this->getPathsAfterResolvingWildcards($exclude);
+
+ if (is_string($prefixes)) {
+ if ($prefixes != '') {
+ $prefixes = array($prefixes);
+ } else {
+ $prefixes = array();
+ }
+ }
+
+ if (is_string($suffixes)) {
+ if ($suffixes != '') {
+ $suffixes = array($suffixes);
+ } else {
+ $suffixes = array();
+ }
+ }
+
+ $iterator = new AppendIterator;
+
+ foreach ($paths as $path) {
+ if (is_dir($path)) {
+ $iterator->append(
+ new File_Iterator(
+ new RecursiveIteratorIterator(
+ new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::FOLLOW_SYMLINKS)
+ ),
+ $suffixes,
+ $prefixes,
+ $exclude,
+ $path
+ )
+ );
+ }
+ }
+
+ return $iterator;
+ }
+
+ /**
+ * @param array $paths
+ * @return array
+ */
+ protected function getPathsAfterResolvingWildcards(array $paths)
+ {
+ $_paths = array();
+
+ foreach ($paths as $path) {
+ if ($locals = glob($path, GLOB_ONLYDIR)) {
+ $_paths = array_merge($_paths, array_map('realpath', $locals));
+ } else {
+ $_paths[] = realpath($path);
+ }
+ }
+
+ return $_paths;
+ }
+}
diff --git a/vendor/phpunit/php-file-iterator/src/Iterator.php b/vendor/phpunit/php-file-iterator/src/Iterator.php
new file mode 100644
index 0000000..c8f20a7
--- /dev/null
+++ b/vendor/phpunit/php-file-iterator/src/Iterator.php
@@ -0,0 +1,158 @@
+<?php
+/*
+ * This file is part of the File_Iterator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * FilterIterator implementation that filters files based on prefix(es) and/or
+ * suffix(es). Hidden files and files from hidden directories are also filtered.
+ *
+ * @since Class available since Release 1.0.0
+ */
+class File_Iterator extends FilterIterator
+{
+ const PREFIX = 0;
+ const SUFFIX = 1;
+
+ /**
+ * @var array
+ */
+ protected $suffixes = array();
+
+ /**
+ * @var array
+ */
+ protected $prefixes = array();
+
+ /**
+ * @var array
+ */
+ protected $exclude = array();
+
+ /**
+ * @var string
+ */
+ protected $basepath;
+
+ /**
+ * @param Iterator $iterator
+ * @param array $suffixes
+ * @param array $prefixes
+ * @param array $exclude
+ * @param string $basepath
+ */
+ public function __construct(Iterator $iterator, array $suffixes = array(), array $prefixes = array(), array $exclude = array(), $basepath = NULL)
+ {
+ $exclude = array_filter(array_map('realpath', $exclude));
+
+ if ($basepath !== NULL) {
+ $basepath = realpath($basepath);
+ }
+
+ if ($basepath === FALSE) {
+ $basepath = NULL;
+ } else {
+ foreach ($exclude as &$_exclude) {
+ $_exclude = str_replace($basepath, '', $_exclude);
+ }
+ }
+
+ $this->prefixes = $prefixes;
+ $this->suffixes = $suffixes;
+ $this->exclude = $exclude;
+ $this->basepath = $basepath;
+
+ parent::__construct($iterator);
+ }
+
+ /**
+ * @return bool
+ */
+ public function accept()
+ {
+ $current = $this->getInnerIterator()->current();
+ $filename = $current->getFilename();
+ $realpath = $current->getRealPath();
+
+ if ($this->basepath !== NULL) {
+ $realpath = str_replace($this->basepath, '', $realpath);
+ }
+
+ // Filter files in hidden directories.
+ if (preg_match('=/\.[^/]*/=', $realpath)) {
+ return FALSE;
+ }
+
+ return $this->acceptPath($realpath) &&
+ $this->acceptPrefix($filename) &&
+ $this->acceptSuffix($filename);
+ }
+
+ /**
+ * @param string $path
+ * @return bool
+ * @since Method available since Release 1.1.0
+ */
+ protected function acceptPath($path)
+ {
+ foreach ($this->exclude as $exclude) {
+ if (strpos($path, $exclude) === 0) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ }
+
+ /**
+ * @param string $filename
+ * @return bool
+ * @since Method available since Release 1.1.0
+ */
+ protected function acceptPrefix($filename)
+ {
+ return $this->acceptSubString($filename, $this->prefixes, self::PREFIX);
+ }
+
+ /**
+ * @param string $filename
+ * @return bool
+ * @since Method available since Release 1.1.0
+ */
+ protected function acceptSuffix($filename)
+ {
+ return $this->acceptSubString($filename, $this->suffixes, self::SUFFIX);
+ }
+
+ /**
+ * @param string $filename
+ * @param array $subStrings
+ * @param int $type
+ * @return bool
+ * @since Method available since Release 1.1.0
+ */
+ protected function acceptSubString($filename, array $subStrings, $type)
+ {
+ if (empty($subStrings)) {
+ return TRUE;
+ }
+
+ $matched = FALSE;
+
+ foreach ($subStrings as $string) {
+ if (($type == self::PREFIX && strpos($filename, $string) === 0) ||
+ ($type == self::SUFFIX &&
+ substr($filename, -1 * strlen($string)) == $string)) {
+ $matched = TRUE;
+ break;
+ }
+ }
+
+ return $matched;
+ }
+}
diff --git a/vendor/phpunit/php-text-template/.gitattributes b/vendor/phpunit/php-text-template/.gitattributes
new file mode 100644
index 0000000..461090b
--- /dev/null
+++ b/vendor/phpunit/php-text-template/.gitattributes
@@ -0,0 +1 @@
+*.php diff=php
diff --git a/vendor/phpunit/php-text-template/.gitignore b/vendor/phpunit/php-text-template/.gitignore
new file mode 100644
index 0000000..c599212
--- /dev/null
+++ b/vendor/phpunit/php-text-template/.gitignore
@@ -0,0 +1,5 @@
+/composer.lock
+/composer.phar
+/.idea
+/vendor
+
diff --git a/vendor/phpunit/php-text-template/LICENSE b/vendor/phpunit/php-text-template/LICENSE
new file mode 100644
index 0000000..9f9a32d
--- /dev/null
+++ b/vendor/phpunit/php-text-template/LICENSE
@@ -0,0 +1,33 @@
+Text_Template
+
+Copyright (c) 2009-2015, Sebastian Bergmann <sebastian@phpunit.de>.
+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/phpunit/php-text-template/README.md b/vendor/phpunit/php-text-template/README.md
new file mode 100644
index 0000000..ec8f593
--- /dev/null
+++ b/vendor/phpunit/php-text-template/README.md
@@ -0,0 +1,14 @@
+# Text_Template
+
+## Installation
+
+## Installation
+
+To add this package as a local, per-project dependency to your project, simply add a dependency on `phpunit/php-text-template` to your project's `composer.json` file. Here is a minimal example of a `composer.json` file that just defines a dependency on Text_Template:
+
+ {
+ "require": {
+ "phpunit/php-text-template": "~1.2"
+ }
+ }
+
diff --git a/vendor/phpunit/php-text-template/composer.json b/vendor/phpunit/php-text-template/composer.json
new file mode 100644
index 0000000..a5779c8
--- /dev/null
+++ b/vendor/phpunit/php-text-template/composer.json
@@ -0,0 +1,29 @@
+{
+ "name": "phpunit/php-text-template",
+ "description": "Simple template engine.",
+ "type": "library",
+ "keywords": [
+ "template"
+ ],
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-text-template/issues"
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ }
+}
+
diff --git a/vendor/phpunit/php-text-template/src/Template.php b/vendor/phpunit/php-text-template/src/Template.php
new file mode 100644
index 0000000..9eb39ad
--- /dev/null
+++ b/vendor/phpunit/php-text-template/src/Template.php
@@ -0,0 +1,135 @@
+<?php
+/*
+ * This file is part of the Text_Template package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A simple template engine.
+ *
+ * @since Class available since Release 1.0.0
+ */
+class Text_Template
+{
+ /**
+ * @var string
+ */
+ protected $template = '';
+
+ /**
+ * @var string
+ */
+ protected $openDelimiter = '{';
+
+ /**
+ * @var string
+ */
+ protected $closeDelimiter = '}';
+
+ /**
+ * @var array
+ */
+ protected $values = array();
+
+ /**
+ * Constructor.
+ *
+ * @param string $file
+ * @throws InvalidArgumentException
+ */
+ public function __construct($file = '', $openDelimiter = '{', $closeDelimiter = '}')
+ {
+ $this->setFile($file);
+ $this->openDelimiter = $openDelimiter;
+ $this->closeDelimiter = $closeDelimiter;
+ }
+
+ /**
+ * Sets the template file.
+ *
+ * @param string $file
+ * @throws InvalidArgumentException
+ */
+ public function setFile($file)
+ {
+ $distFile = $file . '.dist';
+
+ if (file_exists($file)) {
+ $this->template = file_get_contents($file);
+ }
+
+ else if (file_exists($distFile)) {
+ $this->template = file_get_contents($distFile);
+ }
+
+ else {
+ throw new InvalidArgumentException(
+ 'Template file could not be loaded.'
+ );
+ }
+ }
+
+ /**
+ * Sets one or more template variables.
+ *
+ * @param array $values
+ * @param bool $merge
+ */
+ public function setVar(array $values, $merge = TRUE)
+ {
+ if (!$merge || empty($this->values)) {
+ $this->values = $values;
+ } else {
+ $this->values = array_merge($this->values, $values);
+ }
+ }
+
+ /**
+ * Renders the template and returns the result.
+ *
+ * @return string
+ */
+ public function render()
+ {
+ $keys = array();
+
+ foreach ($this->values as $key => $value) {
+ $keys[] = $this->openDelimiter . $key . $this->closeDelimiter;
+ }
+
+ return str_replace($keys, $this->values, $this->template);
+ }
+
+ /**
+ * Renders the template and writes the result to a file.
+ *
+ * @param string $target
+ */
+ public function renderTo($target)
+ {
+ $fp = @fopen($target, 'wt');
+
+ if ($fp) {
+ fwrite($fp, $this->render());
+ fclose($fp);
+ } else {
+ $error = error_get_last();
+
+ throw new RuntimeException(
+ sprintf(
+ 'Could not write to %s: %s',
+ $target,
+ substr(
+ $error['message'],
+ strpos($error['message'], ':') + 2
+ )
+ )
+ );
+ }
+ }
+}
+
diff --git a/vendor/phpunit/php-timer/.gitattributes b/vendor/phpunit/php-timer/.gitattributes
new file mode 100644
index 0000000..461090b
--- /dev/null
+++ b/vendor/phpunit/php-timer/.gitattributes
@@ -0,0 +1 @@
+*.php diff=php
diff --git a/vendor/phpunit/php-timer/.gitignore b/vendor/phpunit/php-timer/.gitignore
new file mode 100644
index 0000000..c03c89b
--- /dev/null
+++ b/vendor/phpunit/php-timer/.gitignore
@@ -0,0 +1,4 @@
+/.idea
+/vendor
+/composer.lock
+
diff --git a/vendor/phpunit/php-timer/.travis.yml b/vendor/phpunit/php-timer/.travis.yml
new file mode 100644
index 0000000..7fc8996
--- /dev/null
+++ b/vendor/phpunit/php-timer/.travis.yml
@@ -0,0 +1,27 @@
+language: php
+
+php:
+ - 5.3
+ - 5.4
+ - 5.5
+ - 5.6
+ - 7.0
+ - 7.0snapshot
+ - 7.1
+ - 7.1snapshot
+ - master
+
+sudo: false
+
+before_install:
+ - composer self-update
+ - composer clear-cache
+
+install:
+ - travis_retry composer update --no-interaction --no-ansi --no-progress --no-suggest --optimize-autoloader --prefer-stable
+
+script:
+ - ./vendor/bin/phpunit
+
+notifications:
+ email: false
diff --git a/vendor/phpunit/php-timer/LICENSE b/vendor/phpunit/php-timer/LICENSE
new file mode 100644
index 0000000..16c4599
--- /dev/null
+++ b/vendor/phpunit/php-timer/LICENSE
@@ -0,0 +1,33 @@
+PHP_Timer
+
+Copyright (c) 2010-2015, Sebastian Bergmann <sebastian@phpunit.de>.
+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/phpunit/php-timer/README.md b/vendor/phpunit/php-timer/README.md
new file mode 100644
index 0000000..47abb57
--- /dev/null
+++ b/vendor/phpunit/php-timer/README.md
@@ -0,0 +1,45 @@
+[![Build Status](https://travis-ci.org/sebastianbergmann/php-timer.svg?branch=master)](https://travis-ci.org/sebastianbergmann/php-timer)
+
+# PHP_Timer
+
+Utility class for timing things, 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 phpunit/php-timer
+
+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 phpunit/php-timer
+
+## Usage
+
+### Basic Timing
+
+```php
+PHP_Timer::start();
+
+// ...
+
+$time = PHP_Timer::stop();
+var_dump($time);
+
+print PHP_Timer::secondsToTimeString($time);
+```
+
+The code above yields the output below:
+
+ double(1.0967254638672E-5)
+ 0 ms
+
+### Resource Consumption Since PHP Startup
+
+```php
+print PHP_Timer::resourceUsage();
+```
+
+The code above yields the output below:
+
+ Time: 0 ms, Memory: 0.50MB
diff --git a/vendor/phpunit/php-timer/composer.json b/vendor/phpunit/php-timer/composer.json
new file mode 100644
index 0000000..0f16164
--- /dev/null
+++ b/vendor/phpunit/php-timer/composer.json
@@ -0,0 +1,37 @@
+{
+ "name": "phpunit/php-timer",
+ "description": "Utility class for timing",
+ "type": "library",
+ "keywords": [
+ "timer"
+ ],
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-timer/issues"
+ },
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ }
+}
+
diff --git a/vendor/phpunit/php-timer/phpunit.xml b/vendor/phpunit/php-timer/phpunit.xml
new file mode 100644
index 0000000..68febeb
--- /dev/null
+++ b/vendor/phpunit/php-timer/phpunit.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.0/phpunit.xsd"
+ bootstrap="vendor/autoload.php"
+ forceCoversAnnotation="true"
+ beStrictAboutCoversAnnotation="true"
+ beStrictAboutOutputDuringTests="true"
+ beStrictAboutTodoAnnotatedTests="true"
+ verbose="true">
+ <testsuite>
+ <directory suffix="Test.php">tests</directory>
+ </testsuite>
+
+ <filter>
+ <whitelist processUncoveredFilesFromWhitelist="true">
+ <directory suffix=".php">src</directory>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/vendor/phpunit/php-timer/src/Timer.php b/vendor/phpunit/php-timer/src/Timer.php
new file mode 100644
index 0000000..7b5c432
--- /dev/null
+++ b/vendor/phpunit/php-timer/src/Timer.php
@@ -0,0 +1,105 @@
+<?php
+/*
+ * This file is part of the PHP_Timer package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Utility class for timing.
+ */
+class PHP_Timer
+{
+ /**
+ * @var array
+ */
+ private static $times = array(
+ 'hour' => 3600000,
+ 'minute' => 60000,
+ 'second' => 1000
+ );
+
+ /**
+ * @var array
+ */
+ private static $startTimes = array();
+
+ /**
+ * @var float
+ */
+ public static $requestTime;
+
+ /**
+ * Starts the timer.
+ */
+ public static function start()
+ {
+ array_push(self::$startTimes, microtime(true));
+ }
+
+ /**
+ * Stops the timer and returns the elapsed time.
+ *
+ * @return float
+ */
+ public static function stop()
+ {
+ return microtime(true) - array_pop(self::$startTimes);
+ }
+
+ /**
+ * Formats the elapsed time as a string.
+ *
+ * @param float $time
+ * @return string
+ */
+ public static function secondsToTimeString($time)
+ {
+ $ms = round($time * 1000);
+
+ foreach (self::$times as $unit => $value) {
+ if ($ms >= $value) {
+ $time = floor($ms / $value * 100.0) / 100.0;
+
+ return $time . ' ' . ($time == 1 ? $unit : $unit . 's');
+ }
+ }
+
+ return $ms . ' ms';
+ }
+
+ /**
+ * Formats the elapsed time since the start of the request as a string.
+ *
+ * @return string
+ */
+ public static function timeSinceStartOfRequest()
+ {
+ return self::secondsToTimeString(microtime(true) - self::$requestTime);
+ }
+
+ /**
+ * Returns the resources (time, memory) of the request as a string.
+ *
+ * @return string
+ */
+ public static function resourceUsage()
+ {
+ return sprintf(
+ 'Time: %s, Memory: %4.2fMB',
+ self::timeSinceStartOfRequest(),
+ memory_get_peak_usage(true) / 1048576
+ );
+ }
+}
+
+if (isset($_SERVER['REQUEST_TIME_FLOAT'])) {
+ PHP_Timer::$requestTime = $_SERVER['REQUEST_TIME_FLOAT'];
+} elseif (isset($_SERVER['REQUEST_TIME'])) {
+ PHP_Timer::$requestTime = $_SERVER['REQUEST_TIME'];
+} else {
+ PHP_Timer::$requestTime = microtime(true);
+}
diff --git a/vendor/phpunit/php-timer/tests/TimerTest.php b/vendor/phpunit/php-timer/tests/TimerTest.php
new file mode 100644
index 0000000..34ebc50
--- /dev/null
+++ b/vendor/phpunit/php-timer/tests/TimerTest.php
@@ -0,0 +1,98 @@
+<?php
+/*
+ * This file is part of the PHP_Timer package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use PHPUnit\Framework\TestCase;
+
+class PHP_TimerTest extends TestCase
+{
+ /**
+ * @covers PHP_Timer::start
+ * @covers PHP_Timer::stop
+ */
+ public function testStartStop()
+ {
+ $this->assertInternalType('float', PHP_Timer::stop());
+ }
+
+ /**
+ * @covers PHP_Timer::secondsToTimeString
+ * @dataProvider secondsProvider
+ */
+ public function testSecondsToTimeString($string, $seconds)
+ {
+ $this->assertEquals(
+ $string,
+ PHP_Timer::secondsToTimeString($seconds)
+ );
+ }
+
+ /**
+ * @covers PHP_Timer::timeSinceStartOfRequest
+ */
+ public function testTimeSinceStartOfRequest()
+ {
+ $this->assertStringMatchesFormat(
+ '%f %s',
+ PHP_Timer::timeSinceStartOfRequest()
+ );
+ }
+
+
+ /**
+ * @covers PHP_Timer::resourceUsage
+ */
+ public function testResourceUsage()
+ {
+ $this->assertStringMatchesFormat(
+ 'Time: %s, Memory: %fMB',
+ PHP_Timer::resourceUsage()
+ );
+ }
+
+ public function secondsProvider()
+ {
+ return array(
+ array('0 ms', 0),
+ array('1 ms', .001),
+ array('10 ms', .01),
+ array('100 ms', .1),
+ array('999 ms', .999),
+ array('1 second', .9999),
+ array('1 second', 1),
+ array('2 seconds', 2),
+ array('59.9 seconds', 59.9),
+ array('59.99 seconds', 59.99),
+ array('59.99 seconds', 59.999),
+ array('1 minute', 59.9999),
+ array('59 seconds', 59.001),
+ array('59.01 seconds', 59.01),
+ array('1 minute', 60),
+ array('1.01 minutes', 61),
+ array('2 minutes', 120),
+ array('2.01 minutes', 121),
+ array('59.99 minutes', 3599.9),
+ array('59.99 minutes', 3599.99),
+ array('59.99 minutes', 3599.999),
+ array('1 hour', 3599.9999),
+ array('59.98 minutes', 3599.001),
+ array('59.98 minutes', 3599.01),
+ array('1 hour', 3600),
+ array('1 hour', 3601),
+ array('1 hour', 3601.9),
+ array('1 hour', 3601.99),
+ array('1 hour', 3601.999),
+ array('1 hour', 3601.9999),
+ array('1.01 hours', 3659.9999),
+ array('1.01 hours', 3659.001),
+ array('1.01 hours', 3659.01),
+ array('2 hours', 7199.9999),
+ );
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/.gitattributes b/vendor/phpunit/php-token-stream/.gitattributes
new file mode 100644
index 0000000..461090b
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/.gitattributes
@@ -0,0 +1 @@
+*.php diff=php
diff --git a/vendor/phpunit/php-token-stream/.gitignore b/vendor/phpunit/php-token-stream/.gitignore
new file mode 100644
index 0000000..77aae3d
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/.gitignore
@@ -0,0 +1,3 @@
+/.idea
+/composer.lock
+/vendor
diff --git a/vendor/phpunit/php-token-stream/.travis.yml b/vendor/phpunit/php-token-stream/.travis.yml
new file mode 100644
index 0000000..e8f407d
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/.travis.yml
@@ -0,0 +1,26 @@
+language: php
+
+php:
+ - 7.0
+ - 7.1
+ - 7.2
+ - master
+
+sudo: false
+
+before_install:
+ - composer self-update
+ - composer clear-cache
+
+install:
+ - travis_retry composer update --no-interaction --no-ansi --no-progress --no-suggest
+
+script:
+ - ./vendor/bin/phpunit --coverage-clover=coverage.xml
+
+after_success:
+ - bash <(curl -s https://codecov.io/bash)
+
+notifications:
+ email: false
+
diff --git a/vendor/phpunit/php-token-stream/ChangeLog.md b/vendor/phpunit/php-token-stream/ChangeLog.md
new file mode 100644
index 0000000..efeec72
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/ChangeLog.md
@@ -0,0 +1,19 @@
+# Change Log
+
+All notable changes to `sebastianbergmann/php-token-stream` are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+
+## [2.0.2] - 2017-11-27
+
+* Fixed [#69](https://github.com/sebastianbergmann/php-token-stream/issues/69): `PHP_Token_USE_FUNCTION` does not serialize correctly
+
+## [2.0.1] - 2017-08-20
+
+### Fixed
+
+* Fixed [#68](https://github.com/sebastianbergmann/php-token-stream/issues/68): Method with name `empty` wrongly recognized as anonymous function
+
+## [2.0.0] - 2017-08-03
+
+[2.0.2]: https://github.com/sebastianbergmann/php-token-stream/compare/2.0.1...2.0.2
+[2.0.1]: https://github.com/sebastianbergmann/php-token-stream/compare/2.0.0...2.0.1
+[2.0.0]: https://github.com/sebastianbergmann/php-token-stream/compare/1.4.11...2.0.0
diff --git a/vendor/phpunit/php-token-stream/LICENSE b/vendor/phpunit/php-token-stream/LICENSE
new file mode 100644
index 0000000..cdd1374
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/LICENSE
@@ -0,0 +1,33 @@
+PHP_TokenStream
+
+Copyright (c) 2009-2017, Sebastian Bergmann <sebastian@phpunit.de>.
+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/phpunit/php-token-stream/README.md b/vendor/phpunit/php-token-stream/README.md
new file mode 100644
index 0000000..149b7e2
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/README.md
@@ -0,0 +1,14 @@
+[![Build Status](https://travis-ci.org/sebastianbergmann/php-token-stream.svg?branch=master)](https://travis-ci.org/sebastianbergmann/php-token-stream)
+
+# php-token-stream
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+ composer require phpunit/php-token-stream
+
+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 phpunit/php-token-stream
+
diff --git a/vendor/phpunit/php-token-stream/build.xml b/vendor/phpunit/php-token-stream/build.xml
new file mode 100644
index 0000000..0da8056
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/build.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="php-token-stream" default="setup">
+ <target name="setup" depends="clean,composer"/>
+
+ <target name="clean" description="Cleanup build artifacts">
+ <delete dir="${basedir}/vendor"/>
+ <delete file="${basedir}/composer.lock"/>
+ </target>
+
+ <target name="composer" depends="clean" description="Install dependencies with Composer">
+ <exec executable="composer" taskname="composer">
+ <env key="COMPOSER_DISABLE_XDEBUG_WARN" value="1"/>
+ <arg value="update"/>
+ <arg value="--no-interaction"/>
+ <arg value="--no-progress"/>
+ <arg value="--no-ansi"/>
+ <arg value="--no-suggest"/>
+ </exec>
+ </target>
+</project>
+
diff --git a/vendor/phpunit/php-token-stream/composer.json b/vendor/phpunit/php-token-stream/composer.json
new file mode 100644
index 0000000..4bf07e7
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/composer.json
@@ -0,0 +1,38 @@
+{
+ "name": "phpunit/php-token-stream",
+ "description": "Wrapper around PHP's tokenizer extension.",
+ "type": "library",
+ "keywords": ["tokenizer"],
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-token-stream/issues"
+ },
+ "require": {
+ "php": "^7.0",
+ "ext-tokenizer": "*"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.2.4"
+ },
+ "config": {
+ "optimize-autoloader": true,
+ "sort-packages": true
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/phpunit.xml b/vendor/phpunit/php-token-stream/phpunit.xml
new file mode 100644
index 0000000..1f789ba
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/phpunit.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.0/phpunit.xsd"
+ bootstrap="tests/bootstrap.php"
+ beStrictAboutOutputDuringTests="true"
+ beStrictAboutTodoAnnotatedTests="true"
+ verbose="true">
+ <testsuite>
+ <directory suffix="Test.php">tests</directory>
+ </testsuite>
+
+ <filter>
+ <whitelist processUncoveredFilesFromWhitelist="true">
+ <directory suffix=".php">src</directory>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/vendor/phpunit/php-token-stream/src/Token.php b/vendor/phpunit/php-token-stream/src/Token.php
new file mode 100644
index 0000000..f4db9a7
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Token.php
@@ -0,0 +1,1460 @@
+<?php
+/*
+ * This file is part of php-token-stream.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A PHP token.
+ */
+abstract class PHP_Token
+{
+ /**
+ * @var string
+ */
+ protected $text;
+
+ /**
+ * @var int
+ */
+ protected $line;
+
+ /**
+ * @var PHP_Token_Stream
+ */
+ protected $tokenStream;
+
+ /**
+ * @var int
+ */
+ protected $id;
+
+ /**
+ * @param string $text
+ * @param int $line
+ * @param PHP_Token_Stream $tokenStream
+ * @param int $id
+ */
+ public function __construct($text, $line, PHP_Token_Stream $tokenStream, $id)
+ {
+ $this->text = $text;
+ $this->line = $line;
+ $this->tokenStream = $tokenStream;
+ $this->id = $id;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->text;
+ }
+
+ /**
+ * @return int
+ */
+ public function getLine()
+ {
+ return $this->line;
+ }
+
+ /**
+ * @return int
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+}
+
+abstract class PHP_TokenWithScope extends PHP_Token
+{
+ /**
+ * @var int
+ */
+ protected $endTokenId;
+
+ /**
+ * Get the docblock for this token
+ *
+ * This method will fetch the docblock belonging to the current token. The
+ * docblock must be placed on the line directly above the token to be
+ * recognized.
+ *
+ * @return string|null Returns the docblock as a string if found
+ */
+ public function getDocblock()
+ {
+ $tokens = $this->tokenStream->tokens();
+ $currentLineNumber = $tokens[$this->id]->getLine();
+ $prevLineNumber = $currentLineNumber - 1;
+
+ for ($i = $this->id - 1; $i; $i--) {
+ if (!isset($tokens[$i])) {
+ return;
+ }
+
+ if ($tokens[$i] instanceof PHP_Token_FUNCTION ||
+ $tokens[$i] instanceof PHP_Token_CLASS ||
+ $tokens[$i] instanceof PHP_Token_TRAIT) {
+ // Some other trait, class or function, no docblock can be
+ // used for the current token
+ break;
+ }
+
+ $line = $tokens[$i]->getLine();
+
+ if ($line == $currentLineNumber ||
+ ($line == $prevLineNumber &&
+ $tokens[$i] instanceof PHP_Token_WHITESPACE)) {
+ continue;
+ }
+
+ if ($line < $currentLineNumber &&
+ !$tokens[$i] instanceof PHP_Token_DOC_COMMENT) {
+ break;
+ }
+
+ return (string) $tokens[$i];
+ }
+ }
+
+ /**
+ * @return int
+ */
+ public function getEndTokenId()
+ {
+ $block = 0;
+ $i = $this->id;
+ $tokens = $this->tokenStream->tokens();
+
+ while ($this->endTokenId === null && isset($tokens[$i])) {
+ if ($tokens[$i] instanceof PHP_Token_OPEN_CURLY ||
+ $tokens[$i] instanceof PHP_Token_CURLY_OPEN) {
+ $block++;
+ } elseif ($tokens[$i] instanceof PHP_Token_CLOSE_CURLY) {
+ $block--;
+
+ if ($block === 0) {
+ $this->endTokenId = $i;
+ }
+ } elseif (($this instanceof PHP_Token_FUNCTION ||
+ $this instanceof PHP_Token_NAMESPACE) &&
+ $tokens[$i] instanceof PHP_Token_SEMICOLON) {
+ if ($block === 0) {
+ $this->endTokenId = $i;
+ }
+ }
+
+ $i++;
+ }
+
+ if ($this->endTokenId === null) {
+ $this->endTokenId = $this->id;
+ }
+
+ return $this->endTokenId;
+ }
+
+ /**
+ * @return int
+ */
+ public function getEndLine()
+ {
+ return $this->tokenStream[$this->getEndTokenId()]->getLine();
+ }
+}
+
+abstract class PHP_TokenWithScopeAndVisibility extends PHP_TokenWithScope
+{
+ /**
+ * @return string
+ */
+ public function getVisibility()
+ {
+ $tokens = $this->tokenStream->tokens();
+
+ for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) {
+ if (isset($tokens[$i]) &&
+ ($tokens[$i] instanceof PHP_Token_PRIVATE ||
+ $tokens[$i] instanceof PHP_Token_PROTECTED ||
+ $tokens[$i] instanceof PHP_Token_PUBLIC)) {
+ return strtolower(
+ str_replace('PHP_Token_', '', get_class($tokens[$i]))
+ );
+ }
+ if (isset($tokens[$i]) &&
+ !($tokens[$i] instanceof PHP_Token_STATIC ||
+ $tokens[$i] instanceof PHP_Token_FINAL ||
+ $tokens[$i] instanceof PHP_Token_ABSTRACT)) {
+ // no keywords; stop visibility search
+ break;
+ }
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function getKeywords()
+ {
+ $keywords = [];
+ $tokens = $this->tokenStream->tokens();
+
+ for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) {
+ if (isset($tokens[$i]) &&
+ ($tokens[$i] instanceof PHP_Token_PRIVATE ||
+ $tokens[$i] instanceof PHP_Token_PROTECTED ||
+ $tokens[$i] instanceof PHP_Token_PUBLIC)) {
+ continue;
+ }
+
+ if (isset($tokens[$i]) &&
+ ($tokens[$i] instanceof PHP_Token_STATIC ||
+ $tokens[$i] instanceof PHP_Token_FINAL ||
+ $tokens[$i] instanceof PHP_Token_ABSTRACT)) {
+ $keywords[] = strtolower(
+ str_replace('PHP_Token_', '', get_class($tokens[$i]))
+ );
+ }
+ }
+
+ return implode(',', $keywords);
+ }
+}
+
+abstract class PHP_Token_Includes extends PHP_Token
+{
+ /**
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * @var string
+ */
+ protected $type;
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ if ($this->name === null) {
+ $this->process();
+ }
+
+ return $this->name;
+ }
+
+ /**
+ * @return string
+ */
+ public function getType()
+ {
+ if ($this->type === null) {
+ $this->process();
+ }
+
+ return $this->type;
+ }
+
+ private function process()
+ {
+ $tokens = $this->tokenStream->tokens();
+
+ if ($tokens[$this->id + 2] instanceof PHP_Token_CONSTANT_ENCAPSED_STRING) {
+ $this->name = trim($tokens[$this->id + 2], "'\"");
+ $this->type = strtolower(
+ str_replace('PHP_Token_', '', get_class($tokens[$this->id]))
+ );
+ }
+ }
+}
+
+class PHP_Token_FUNCTION extends PHP_TokenWithScopeAndVisibility
+{
+ /**
+ * @var array
+ */
+ protected $arguments;
+
+ /**
+ * @var int
+ */
+ protected $ccn;
+
+ /**
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * @var string
+ */
+ protected $signature;
+
+ /**
+ * @var bool
+ */
+ private $anonymous = false;
+
+ /**
+ * @return array
+ */
+ public function getArguments()
+ {
+ if ($this->arguments !== null) {
+ return $this->arguments;
+ }
+
+ $this->arguments = [];
+ $tokens = $this->tokenStream->tokens();
+ $typeDeclaration = null;
+
+ // Search for first token inside brackets
+ $i = $this->id + 2;
+
+ while (!$tokens[$i - 1] instanceof PHP_Token_OPEN_BRACKET) {
+ $i++;
+ }
+
+ while (!$tokens[$i] instanceof PHP_Token_CLOSE_BRACKET) {
+ if ($tokens[$i] instanceof PHP_Token_STRING) {
+ $typeDeclaration = (string) $tokens[$i];
+ } elseif ($tokens[$i] instanceof PHP_Token_VARIABLE) {
+ $this->arguments[(string) $tokens[$i]] = $typeDeclaration;
+ $typeDeclaration = null;
+ }
+
+ $i++;
+ }
+
+ return $this->arguments;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ if ($this->name !== null) {
+ return $this->name;
+ }
+
+ $tokens = $this->tokenStream->tokens();
+
+ $i = $this->id + 1;
+
+ if ($tokens[$i] instanceof PHP_Token_WHITESPACE) {
+ $i++;
+ }
+
+ if ($tokens[$i] instanceof PHP_Token_AMPERSAND) {
+ $i++;
+ }
+
+ if ($tokens[$i + 1] instanceof PHP_Token_OPEN_BRACKET) {
+ $this->name = (string) $tokens[$i];
+ } elseif ($tokens[$i + 1] instanceof PHP_Token_WHITESPACE && $tokens[$i + 2] instanceof PHP_Token_OPEN_BRACKET) {
+ $this->name = (string) $tokens[$i];
+ } else {
+ $this->anonymous = true;
+
+ $this->name = sprintf(
+ 'anonymousFunction:%s#%s',
+ $this->getLine(),
+ $this->getId()
+ );
+ }
+
+ if (!$this->isAnonymous()) {
+ for ($i = $this->id; $i; --$i) {
+ if ($tokens[$i] instanceof PHP_Token_NAMESPACE) {
+ $this->name = $tokens[$i]->getName() . '\\' . $this->name;
+
+ break;
+ }
+
+ if ($tokens[$i] instanceof PHP_Token_INTERFACE) {
+ break;
+ }
+ }
+ }
+
+ return $this->name;
+ }
+
+ /**
+ * @return int
+ */
+ public function getCCN()
+ {
+ if ($this->ccn !== null) {
+ return $this->ccn;
+ }
+
+ $this->ccn = 1;
+ $end = $this->getEndTokenId();
+ $tokens = $this->tokenStream->tokens();
+
+ for ($i = $this->id; $i <= $end; $i++) {
+ switch (get_class($tokens[$i])) {
+ case 'PHP_Token_IF':
+ case 'PHP_Token_ELSEIF':
+ case 'PHP_Token_FOR':
+ case 'PHP_Token_FOREACH':
+ case 'PHP_Token_WHILE':
+ case 'PHP_Token_CASE':
+ case 'PHP_Token_CATCH':
+ case 'PHP_Token_BOOLEAN_AND':
+ case 'PHP_Token_LOGICAL_AND':
+ case 'PHP_Token_BOOLEAN_OR':
+ case 'PHP_Token_LOGICAL_OR':
+ case 'PHP_Token_QUESTION_MARK':
+ $this->ccn++;
+ break;
+ }
+ }
+
+ return $this->ccn;
+ }
+
+ /**
+ * @return string
+ */
+ public function getSignature()
+ {
+ if ($this->signature !== null) {
+ return $this->signature;
+ }
+
+ if ($this->isAnonymous()) {
+ $this->signature = 'anonymousFunction';
+ $i = $this->id + 1;
+ } else {
+ $this->signature = '';
+ $i = $this->id + 2;
+ }
+
+ $tokens = $this->tokenStream->tokens();
+
+ while (isset($tokens[$i]) &&
+ !$tokens[$i] instanceof PHP_Token_OPEN_CURLY &&
+ !$tokens[$i] instanceof PHP_Token_SEMICOLON) {
+ $this->signature .= $tokens[$i++];
+ }
+
+ $this->signature = trim($this->signature);
+
+ return $this->signature;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isAnonymous()
+ {
+ return $this->anonymous;
+ }
+}
+
+class PHP_Token_INTERFACE extends PHP_TokenWithScopeAndVisibility
+{
+ /**
+ * @var array
+ */
+ protected $interfaces;
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ return (string) $this->tokenStream[$this->id + 2];
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasParent()
+ {
+ return $this->tokenStream[$this->id + 4] instanceof PHP_Token_EXTENDS;
+ }
+
+ /**
+ * @return array
+ */
+ public function getPackage()
+ {
+ $className = $this->getName();
+ $docComment = $this->getDocblock();
+
+ $result = [
+ 'namespace' => '',
+ 'fullPackage' => '',
+ 'category' => '',
+ 'package' => '',
+ 'subpackage' => ''
+ ];
+
+ for ($i = $this->id; $i; --$i) {
+ if ($this->tokenStream[$i] instanceof PHP_Token_NAMESPACE) {
+ $result['namespace'] = $this->tokenStream[$i]->getName();
+ break;
+ }
+ }
+
+ if (preg_match('/@category[\s]+([\.\w]+)/', $docComment, $matches)) {
+ $result['category'] = $matches[1];
+ }
+
+ if (preg_match('/@package[\s]+([\.\w]+)/', $docComment, $matches)) {
+ $result['package'] = $matches[1];
+ $result['fullPackage'] = $matches[1];
+ }
+
+ if (preg_match('/@subpackage[\s]+([\.\w]+)/', $docComment, $matches)) {
+ $result['subpackage'] = $matches[1];
+ $result['fullPackage'] .= '.' . $matches[1];
+ }
+
+ if (empty($result['fullPackage'])) {
+ $result['fullPackage'] = $this->arrayToName(
+ explode('_', str_replace('\\', '_', $className)),
+ '.'
+ );
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param array $parts
+ * @param string $join
+ *
+ * @return string
+ */
+ protected function arrayToName(array $parts, $join = '\\')
+ {
+ $result = '';
+
+ if (count($parts) > 1) {
+ array_pop($parts);
+
+ $result = implode($join, $parts);
+ }
+
+ return $result;
+ }
+
+ /**
+ * @return bool|string
+ */
+ public function getParent()
+ {
+ if (!$this->hasParent()) {
+ return false;
+ }
+
+ $i = $this->id + 6;
+ $tokens = $this->tokenStream->tokens();
+ $className = (string) $tokens[$i];
+
+ while (isset($tokens[$i + 1]) &&
+ !$tokens[$i + 1] instanceof PHP_Token_WHITESPACE) {
+ $className .= (string) $tokens[++$i];
+ }
+
+ return $className;
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasInterfaces()
+ {
+ return (isset($this->tokenStream[$this->id + 4]) &&
+ $this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) ||
+ (isset($this->tokenStream[$this->id + 8]) &&
+ $this->tokenStream[$this->id + 8] instanceof PHP_Token_IMPLEMENTS);
+ }
+
+ /**
+ * @return array|bool
+ */
+ public function getInterfaces()
+ {
+ if ($this->interfaces !== null) {
+ return $this->interfaces;
+ }
+
+ if (!$this->hasInterfaces()) {
+ return ($this->interfaces = false);
+ }
+
+ if ($this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) {
+ $i = $this->id + 3;
+ } else {
+ $i = $this->id + 7;
+ }
+
+ $tokens = $this->tokenStream->tokens();
+
+ while (!$tokens[$i + 1] instanceof PHP_Token_OPEN_CURLY) {
+ $i++;
+
+ if ($tokens[$i] instanceof PHP_Token_STRING) {
+ $this->interfaces[] = (string) $tokens[$i];
+ }
+ }
+
+ return $this->interfaces;
+ }
+}
+
+class PHP_Token_ABSTRACT extends PHP_Token
+{
+}
+
+class PHP_Token_AMPERSAND extends PHP_Token
+{
+}
+
+class PHP_Token_AND_EQUAL extends PHP_Token
+{
+}
+
+class PHP_Token_ARRAY extends PHP_Token
+{
+}
+
+class PHP_Token_ARRAY_CAST extends PHP_Token
+{
+}
+
+class PHP_Token_AS extends PHP_Token
+{
+}
+
+class PHP_Token_AT extends PHP_Token
+{
+}
+
+class PHP_Token_BACKTICK extends PHP_Token
+{
+}
+
+class PHP_Token_BAD_CHARACTER extends PHP_Token
+{
+}
+
+class PHP_Token_BOOLEAN_AND extends PHP_Token
+{
+}
+
+class PHP_Token_BOOLEAN_OR extends PHP_Token
+{
+}
+
+class PHP_Token_BOOL_CAST extends PHP_Token
+{
+}
+
+class PHP_Token_BREAK extends PHP_Token
+{
+}
+
+class PHP_Token_CARET extends PHP_Token
+{
+}
+
+class PHP_Token_CASE extends PHP_Token
+{
+}
+
+class PHP_Token_CATCH extends PHP_Token
+{
+}
+
+class PHP_Token_CHARACTER extends PHP_Token
+{
+}
+
+class PHP_Token_CLASS extends PHP_Token_INTERFACE
+{
+ /**
+ * @var bool
+ */
+ private $anonymous = false;
+
+ /**
+ * @var string
+ */
+ private $name;
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ if ($this->name !== null) {
+ return $this->name;
+ }
+
+ $next = $this->tokenStream[$this->id + 1];
+
+ if ($next instanceof PHP_Token_WHITESPACE) {
+ $next = $this->tokenStream[$this->id + 2];
+ }
+
+ if ($next instanceof PHP_Token_STRING) {
+ $this->name =(string) $next;
+
+ return $this->name;
+ }
+
+ if ($next instanceof PHP_Token_OPEN_CURLY ||
+ $next instanceof PHP_Token_EXTENDS ||
+ $next instanceof PHP_Token_IMPLEMENTS) {
+
+ $this->name = sprintf(
+ 'AnonymousClass:%s#%s',
+ $this->getLine(),
+ $this->getId()
+ );
+
+ $this->anonymous = true;
+
+ return $this->name;
+ }
+ }
+
+ public function isAnonymous()
+ {
+ return $this->anonymous;
+ }
+}
+
+class PHP_Token_CLASS_C extends PHP_Token
+{
+}
+
+class PHP_Token_CLASS_NAME_CONSTANT extends PHP_Token
+{
+}
+
+class PHP_Token_CLONE extends PHP_Token
+{
+}
+
+class PHP_Token_CLOSE_BRACKET extends PHP_Token
+{
+}
+
+class PHP_Token_CLOSE_CURLY extends PHP_Token
+{
+}
+
+class PHP_Token_CLOSE_SQUARE extends PHP_Token
+{
+}
+
+class PHP_Token_CLOSE_TAG extends PHP_Token
+{
+}
+
+class PHP_Token_COLON extends PHP_Token
+{
+}
+
+class PHP_Token_COMMA extends PHP_Token
+{
+}
+
+class PHP_Token_COMMENT extends PHP_Token
+{
+}
+
+class PHP_Token_CONCAT_EQUAL extends PHP_Token
+{
+}
+
+class PHP_Token_CONST extends PHP_Token
+{
+}
+
+class PHP_Token_CONSTANT_ENCAPSED_STRING extends PHP_Token
+{
+}
+
+class PHP_Token_CONTINUE extends PHP_Token
+{
+}
+
+class PHP_Token_CURLY_OPEN extends PHP_Token
+{
+}
+
+class PHP_Token_DEC extends PHP_Token
+{
+}
+
+class PHP_Token_DECLARE extends PHP_Token
+{
+}
+
+class PHP_Token_DEFAULT extends PHP_Token
+{
+}
+
+class PHP_Token_DIV extends PHP_Token
+{
+}
+
+class PHP_Token_DIV_EQUAL extends PHP_Token
+{
+}
+
+class PHP_Token_DNUMBER extends PHP_Token
+{
+}
+
+class PHP_Token_DO extends PHP_Token
+{
+}
+
+class PHP_Token_DOC_COMMENT extends PHP_Token
+{
+}
+
+class PHP_Token_DOLLAR extends PHP_Token
+{
+}
+
+class PHP_Token_DOLLAR_OPEN_CURLY_BRACES extends PHP_Token
+{
+}
+
+class PHP_Token_DOT extends PHP_Token
+{
+}
+
+class PHP_Token_DOUBLE_ARROW extends PHP_Token
+{
+}
+
+class PHP_Token_DOUBLE_CAST extends PHP_Token
+{
+}
+
+class PHP_Token_DOUBLE_COLON extends PHP_Token
+{
+}
+
+class PHP_Token_DOUBLE_QUOTES extends PHP_Token
+{
+}
+
+class PHP_Token_ECHO extends PHP_Token
+{
+}
+
+class PHP_Token_ELSE extends PHP_Token
+{
+}
+
+class PHP_Token_ELSEIF extends PHP_Token
+{
+}
+
+class PHP_Token_EMPTY extends PHP_Token
+{
+}
+
+class PHP_Token_ENCAPSED_AND_WHITESPACE extends PHP_Token
+{
+}
+
+class PHP_Token_ENDDECLARE extends PHP_Token
+{
+}
+
+class PHP_Token_ENDFOR extends PHP_Token
+{
+}
+
+class PHP_Token_ENDFOREACH extends PHP_Token
+{
+}
+
+class PHP_Token_ENDIF extends PHP_Token
+{
+}
+
+class PHP_Token_ENDSWITCH extends PHP_Token
+{
+}
+
+class PHP_Token_ENDWHILE extends PHP_Token
+{
+}
+
+class PHP_Token_END_HEREDOC extends PHP_Token
+{
+}
+
+class PHP_Token_EQUAL extends PHP_Token
+{
+}
+
+class PHP_Token_EVAL extends PHP_Token
+{
+}
+
+class PHP_Token_EXCLAMATION_MARK extends PHP_Token
+{
+}
+
+class PHP_Token_EXIT extends PHP_Token
+{
+}
+
+class PHP_Token_EXTENDS extends PHP_Token
+{
+}
+
+class PHP_Token_FILE extends PHP_Token
+{
+}
+
+class PHP_Token_FINAL extends PHP_Token
+{
+}
+
+class PHP_Token_FOR extends PHP_Token
+{
+}
+
+class PHP_Token_FOREACH extends PHP_Token
+{
+}
+
+class PHP_Token_FUNC_C extends PHP_Token
+{
+}
+
+class PHP_Token_GLOBAL extends PHP_Token
+{
+}
+
+class PHP_Token_GT extends PHP_Token
+{
+}
+
+class PHP_Token_IF extends PHP_Token
+{
+}
+
+class PHP_Token_IMPLEMENTS extends PHP_Token
+{
+}
+
+class PHP_Token_INC extends PHP_Token
+{
+}
+
+class PHP_Token_INCLUDE extends PHP_Token_Includes
+{
+}
+
+class PHP_Token_INCLUDE_ONCE extends PHP_Token_Includes
+{
+}
+
+class PHP_Token_INLINE_HTML extends PHP_Token
+{
+}
+
+class PHP_Token_INSTANCEOF extends PHP_Token
+{
+}
+
+class PHP_Token_INT_CAST extends PHP_Token
+{
+}
+
+class PHP_Token_ISSET extends PHP_Token
+{
+}
+
+class PHP_Token_IS_EQUAL extends PHP_Token
+{
+}
+
+class PHP_Token_IS_GREATER_OR_EQUAL extends PHP_Token
+{
+}
+
+class PHP_Token_IS_IDENTICAL extends PHP_Token
+{
+}
+
+class PHP_Token_IS_NOT_EQUAL extends PHP_Token
+{
+}
+
+class PHP_Token_IS_NOT_IDENTICAL extends PHP_Token
+{
+}
+
+class PHP_Token_IS_SMALLER_OR_EQUAL extends PHP_Token
+{
+}
+
+class PHP_Token_LINE extends PHP_Token
+{
+}
+
+class PHP_Token_LIST extends PHP_Token
+{
+}
+
+class PHP_Token_LNUMBER extends PHP_Token
+{
+}
+
+class PHP_Token_LOGICAL_AND extends PHP_Token
+{
+}
+
+class PHP_Token_LOGICAL_OR extends PHP_Token
+{
+}
+
+class PHP_Token_LOGICAL_XOR extends PHP_Token
+{
+}
+
+class PHP_Token_LT extends PHP_Token
+{
+}
+
+class PHP_Token_METHOD_C extends PHP_Token
+{
+}
+
+class PHP_Token_MINUS extends PHP_Token
+{
+}
+
+class PHP_Token_MINUS_EQUAL extends PHP_Token
+{
+}
+
+class PHP_Token_MOD_EQUAL extends PHP_Token
+{
+}
+
+class PHP_Token_MULT extends PHP_Token
+{
+}
+
+class PHP_Token_MUL_EQUAL extends PHP_Token
+{
+}
+
+class PHP_Token_NEW extends PHP_Token
+{
+}
+
+class PHP_Token_NUM_STRING extends PHP_Token
+{
+}
+
+class PHP_Token_OBJECT_CAST extends PHP_Token
+{
+}
+
+class PHP_Token_OBJECT_OPERATOR extends PHP_Token
+{
+}
+
+class PHP_Token_OPEN_BRACKET extends PHP_Token
+{
+}
+
+class PHP_Token_OPEN_CURLY extends PHP_Token
+{
+}
+
+class PHP_Token_OPEN_SQUARE extends PHP_Token
+{
+}
+
+class PHP_Token_OPEN_TAG extends PHP_Token
+{
+}
+
+class PHP_Token_OPEN_TAG_WITH_ECHO extends PHP_Token
+{
+}
+
+class PHP_Token_OR_EQUAL extends PHP_Token
+{
+}
+
+class PHP_Token_PAAMAYIM_NEKUDOTAYIM extends PHP_Token
+{
+}
+
+class PHP_Token_PERCENT extends PHP_Token
+{
+}
+
+class PHP_Token_PIPE extends PHP_Token
+{
+}
+
+class PHP_Token_PLUS extends PHP_Token
+{
+}
+
+class PHP_Token_PLUS_EQUAL extends PHP_Token
+{
+}
+
+class PHP_Token_PRINT extends PHP_Token
+{
+}
+
+class PHP_Token_PRIVATE extends PHP_Token
+{
+}
+
+class PHP_Token_PROTECTED extends PHP_Token
+{
+}
+
+class PHP_Token_PUBLIC extends PHP_Token
+{
+}
+
+class PHP_Token_QUESTION_MARK extends PHP_Token
+{
+}
+
+class PHP_Token_REQUIRE extends PHP_Token_Includes
+{
+}
+
+class PHP_Token_REQUIRE_ONCE extends PHP_Token_Includes
+{
+}
+
+class PHP_Token_RETURN extends PHP_Token
+{
+}
+
+class PHP_Token_SEMICOLON extends PHP_Token
+{
+}
+
+class PHP_Token_SL extends PHP_Token
+{
+}
+
+class PHP_Token_SL_EQUAL extends PHP_Token
+{
+}
+
+class PHP_Token_SR extends PHP_Token
+{
+}
+
+class PHP_Token_SR_EQUAL extends PHP_Token
+{
+}
+
+class PHP_Token_START_HEREDOC extends PHP_Token
+{
+}
+
+class PHP_Token_STATIC extends PHP_Token
+{
+}
+
+class PHP_Token_STRING extends PHP_Token
+{
+}
+
+class PHP_Token_STRING_CAST extends PHP_Token
+{
+}
+
+class PHP_Token_STRING_VARNAME extends PHP_Token
+{
+}
+
+class PHP_Token_SWITCH extends PHP_Token
+{
+}
+
+class PHP_Token_THROW extends PHP_Token
+{
+}
+
+class PHP_Token_TILDE extends PHP_Token
+{
+}
+
+class PHP_Token_TRY extends PHP_Token
+{
+}
+
+class PHP_Token_UNSET extends PHP_Token
+{
+}
+
+class PHP_Token_UNSET_CAST extends PHP_Token
+{
+}
+
+class PHP_Token_USE extends PHP_Token
+{
+}
+
+class PHP_Token_USE_FUNCTION extends PHP_Token
+{
+}
+
+class PHP_Token_VAR extends PHP_Token
+{
+}
+
+class PHP_Token_VARIABLE extends PHP_Token
+{
+}
+
+class PHP_Token_WHILE extends PHP_Token
+{
+}
+
+class PHP_Token_WHITESPACE extends PHP_Token
+{
+}
+
+class PHP_Token_XOR_EQUAL extends PHP_Token
+{
+}
+
+// Tokens introduced in PHP 5.1
+class PHP_Token_HALT_COMPILER extends PHP_Token
+{
+}
+
+// Tokens introduced in PHP 5.3
+class PHP_Token_DIR extends PHP_Token
+{
+}
+
+class PHP_Token_GOTO extends PHP_Token
+{
+}
+
+class PHP_Token_NAMESPACE extends PHP_TokenWithScope
+{
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ $tokens = $this->tokenStream->tokens();
+ $namespace = (string) $tokens[$this->id + 2];
+
+ for ($i = $this->id + 3;; $i += 2) {
+ if (isset($tokens[$i]) &&
+ $tokens[$i] instanceof PHP_Token_NS_SEPARATOR) {
+ $namespace .= '\\' . $tokens[$i + 1];
+ } else {
+ break;
+ }
+ }
+
+ return $namespace;
+ }
+}
+
+class PHP_Token_NS_C extends PHP_Token
+{
+}
+
+class PHP_Token_NS_SEPARATOR extends PHP_Token
+{
+}
+
+// Tokens introduced in PHP 5.4
+class PHP_Token_CALLABLE extends PHP_Token
+{
+}
+
+class PHP_Token_INSTEADOF extends PHP_Token
+{
+}
+
+class PHP_Token_TRAIT extends PHP_Token_INTERFACE
+{
+}
+
+class PHP_Token_TRAIT_C extends PHP_Token
+{
+}
+
+// Tokens introduced in PHP 5.5
+class PHP_Token_FINALLY extends PHP_Token
+{
+}
+
+class PHP_Token_YIELD extends PHP_Token
+{
+}
+
+// Tokens introduced in PHP 5.6
+class PHP_Token_ELLIPSIS extends PHP_Token
+{
+}
+
+class PHP_Token_POW extends PHP_Token
+{
+}
+
+class PHP_Token_POW_EQUAL extends PHP_Token
+{
+}
+
+// Tokens introduced in PHP 7.0
+class PHP_Token_COALESCE extends PHP_Token
+{
+}
+
+class PHP_Token_SPACESHIP extends PHP_Token
+{
+}
+
+class PHP_Token_YIELD_FROM extends PHP_Token
+{
+}
+
+// Tokens introduced in HackLang / HHVM
+class PHP_Token_ASYNC extends PHP_Token
+{
+}
+
+class PHP_Token_AWAIT extends PHP_Token
+{
+}
+
+class PHP_Token_COMPILER_HALT_OFFSET extends PHP_Token
+{
+}
+
+class PHP_Token_ENUM extends PHP_Token
+{
+}
+
+class PHP_Token_EQUALS extends PHP_Token
+{
+}
+
+class PHP_Token_IN extends PHP_Token
+{
+}
+
+class PHP_Token_JOIN extends PHP_Token
+{
+}
+
+class PHP_Token_LAMBDA_ARROW extends PHP_Token
+{
+}
+
+class PHP_Token_LAMBDA_CP extends PHP_Token
+{
+}
+
+class PHP_Token_LAMBDA_OP extends PHP_Token
+{
+}
+
+class PHP_Token_ONUMBER extends PHP_Token
+{
+}
+
+class PHP_Token_NULLSAFE_OBJECT_OPERATOR extends PHP_Token
+{
+}
+
+class PHP_Token_SHAPE extends PHP_Token
+{
+}
+
+class PHP_Token_SUPER extends PHP_Token
+{
+}
+
+class PHP_Token_TYPE extends PHP_Token
+{
+}
+
+class PHP_Token_TYPELIST_GT extends PHP_Token
+{
+}
+
+class PHP_Token_TYPELIST_LT extends PHP_Token
+{
+}
+
+class PHP_Token_WHERE extends PHP_Token
+{
+}
+
+class PHP_Token_XHP_ATTRIBUTE extends PHP_Token
+{
+}
+
+class PHP_Token_XHP_CATEGORY extends PHP_Token
+{
+}
+
+class PHP_Token_XHP_CATEGORY_LABEL extends PHP_Token
+{
+}
+
+class PHP_Token_XHP_CHILDREN extends PHP_Token
+{
+}
+
+class PHP_Token_XHP_LABEL extends PHP_Token
+{
+}
+
+class PHP_Token_XHP_REQUIRED extends PHP_Token
+{
+}
+
+class PHP_Token_XHP_TAG_GT extends PHP_Token
+{
+}
+
+class PHP_Token_XHP_TAG_LT extends PHP_Token
+{
+}
+
+class PHP_Token_XHP_TEXT extends PHP_Token
+{
+}
diff --git a/vendor/phpunit/php-token-stream/src/Token/Stream.php b/vendor/phpunit/php-token-stream/src/Token/Stream.php
new file mode 100644
index 0000000..fc3e3c3
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Token/Stream.php
@@ -0,0 +1,607 @@
+<?php
+/*
+ * This file is part of php-token-stream.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A stream of PHP tokens.
+ */
+class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
+{
+ /**
+ * @var array
+ */
+ protected static $customTokens = [
+ '(' => 'PHP_Token_OPEN_BRACKET',
+ ')' => 'PHP_Token_CLOSE_BRACKET',
+ '[' => 'PHP_Token_OPEN_SQUARE',
+ ']' => 'PHP_Token_CLOSE_SQUARE',
+ '{' => 'PHP_Token_OPEN_CURLY',
+ '}' => 'PHP_Token_CLOSE_CURLY',
+ ';' => 'PHP_Token_SEMICOLON',
+ '.' => 'PHP_Token_DOT',
+ ',' => 'PHP_Token_COMMA',
+ '=' => 'PHP_Token_EQUAL',
+ '<' => 'PHP_Token_LT',
+ '>' => 'PHP_Token_GT',
+ '+' => 'PHP_Token_PLUS',
+ '-' => 'PHP_Token_MINUS',
+ '*' => 'PHP_Token_MULT',
+ '/' => 'PHP_Token_DIV',
+ '?' => 'PHP_Token_QUESTION_MARK',
+ '!' => 'PHP_Token_EXCLAMATION_MARK',
+ ':' => 'PHP_Token_COLON',
+ '"' => 'PHP_Token_DOUBLE_QUOTES',
+ '@' => 'PHP_Token_AT',
+ '&' => 'PHP_Token_AMPERSAND',
+ '%' => 'PHP_Token_PERCENT',
+ '|' => 'PHP_Token_PIPE',
+ '$' => 'PHP_Token_DOLLAR',
+ '^' => 'PHP_Token_CARET',
+ '~' => 'PHP_Token_TILDE',
+ '`' => 'PHP_Token_BACKTICK'
+ ];
+
+ /**
+ * @var string
+ */
+ protected $filename;
+
+ /**
+ * @var array
+ */
+ protected $tokens = [];
+
+ /**
+ * @var int
+ */
+ protected $position = 0;
+
+ /**
+ * @var array
+ */
+ protected $linesOfCode = ['loc' => 0, 'cloc' => 0, 'ncloc' => 0];
+
+ /**
+ * @var array
+ */
+ protected $classes;
+
+ /**
+ * @var array
+ */
+ protected $functions;
+
+ /**
+ * @var array
+ */
+ protected $includes;
+
+ /**
+ * @var array
+ */
+ protected $interfaces;
+
+ /**
+ * @var array
+ */
+ protected $traits;
+
+ /**
+ * @var array
+ */
+ protected $lineToFunctionMap = [];
+
+ /**
+ * Constructor.
+ *
+ * @param string $sourceCode
+ */
+ public function __construct($sourceCode)
+ {
+ if (is_file($sourceCode)) {
+ $this->filename = $sourceCode;
+ $sourceCode = file_get_contents($sourceCode);
+ }
+
+ $this->scan($sourceCode);
+ }
+
+ /**
+ * Destructor.
+ */
+ public function __destruct()
+ {
+ $this->tokens = [];
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ $buffer = '';
+
+ foreach ($this as $token) {
+ $buffer .= $token;
+ }
+
+ return $buffer;
+ }
+
+ /**
+ * @return string
+ */
+ public function getFilename()
+ {
+ return $this->filename;
+ }
+
+ /**
+ * Scans the source for sequences of characters and converts them into a
+ * stream of tokens.
+ *
+ * @param string $sourceCode
+ */
+ protected function scan($sourceCode)
+ {
+ $id = 0;
+ $line = 1;
+ $tokens = token_get_all($sourceCode);
+ $numTokens = count($tokens);
+
+ $lastNonWhitespaceTokenWasDoubleColon = false;
+
+ for ($i = 0; $i < $numTokens; ++$i) {
+ $token = $tokens[$i];
+ $skip = 0;
+
+ if (is_array($token)) {
+ $name = substr(token_name($token[0]), 2);
+ $text = $token[1];
+
+ if ($lastNonWhitespaceTokenWasDoubleColon && $name == 'CLASS') {
+ $name = 'CLASS_NAME_CONSTANT';
+ } elseif ($name == 'USE' && isset($tokens[$i + 2][0]) && $tokens[$i + 2][0] == T_FUNCTION) {
+ $name = 'USE_FUNCTION';
+ $text .= $tokens[$i + 1][1] . $tokens[$i + 2][1];
+ $skip = 2;
+ }
+
+ $tokenClass = 'PHP_Token_' . $name;
+ } else {
+ $text = $token;
+ $tokenClass = self::$customTokens[$token];
+ }
+
+ $this->tokens[] = new $tokenClass($text, $line, $this, $id++);
+ $lines = substr_count($text, "\n");
+ $line += $lines;
+
+ if ($tokenClass == 'PHP_Token_HALT_COMPILER') {
+ break;
+ } elseif ($tokenClass == 'PHP_Token_COMMENT' ||
+ $tokenClass == 'PHP_Token_DOC_COMMENT') {
+ $this->linesOfCode['cloc'] += $lines + 1;
+ }
+
+ if ($name == 'DOUBLE_COLON') {
+ $lastNonWhitespaceTokenWasDoubleColon = true;
+ } elseif ($name != 'WHITESPACE') {
+ $lastNonWhitespaceTokenWasDoubleColon = false;
+ }
+
+ $i += $skip;
+ }
+
+ $this->linesOfCode['loc'] = substr_count($sourceCode, "\n");
+ $this->linesOfCode['ncloc'] = $this->linesOfCode['loc'] -
+ $this->linesOfCode['cloc'];
+ }
+
+ /**
+ * @return int
+ */
+ public function count()
+ {
+ return count($this->tokens);
+ }
+
+ /**
+ * @return PHP_Token[]
+ */
+ public function tokens()
+ {
+ return $this->tokens;
+ }
+
+ /**
+ * @return array
+ */
+ public function getClasses()
+ {
+ if ($this->classes !== null) {
+ return $this->classes;
+ }
+
+ $this->parse();
+
+ return $this->classes;
+ }
+
+ /**
+ * @return array
+ */
+ public function getFunctions()
+ {
+ if ($this->functions !== null) {
+ return $this->functions;
+ }
+
+ $this->parse();
+
+ return $this->functions;
+ }
+
+ /**
+ * @return array
+ */
+ public function getInterfaces()
+ {
+ if ($this->interfaces !== null) {
+ return $this->interfaces;
+ }
+
+ $this->parse();
+
+ return $this->interfaces;
+ }
+
+ /**
+ * @return array
+ */
+ public function getTraits()
+ {
+ if ($this->traits !== null) {
+ return $this->traits;
+ }
+
+ $this->parse();
+
+ return $this->traits;
+ }
+
+ /**
+ * Gets the names of all files that have been included
+ * using include(), include_once(), require() or require_once().
+ *
+ * Parameter $categorize set to TRUE causing this function to return a
+ * multi-dimensional array with categories in the keys of the first dimension
+ * and constants and their values in the second dimension.
+ *
+ * Parameter $category allow to filter following specific inclusion type
+ *
+ * @param bool $categorize OPTIONAL
+ * @param string $category OPTIONAL Either 'require_once', 'require',
+ * 'include_once', 'include'.
+ *
+ * @return array
+ */
+ public function getIncludes($categorize = false, $category = null)
+ {
+ if ($this->includes === null) {
+ $this->includes = [
+ 'require_once' => [],
+ 'require' => [],
+ 'include_once' => [],
+ 'include' => []
+ ];
+
+ foreach ($this->tokens as $token) {
+ switch (get_class($token)) {
+ case 'PHP_Token_REQUIRE_ONCE':
+ case 'PHP_Token_REQUIRE':
+ case 'PHP_Token_INCLUDE_ONCE':
+ case 'PHP_Token_INCLUDE':
+ $this->includes[$token->getType()][] = $token->getName();
+ break;
+ }
+ }
+ }
+
+ if (isset($this->includes[$category])) {
+ $includes = $this->includes[$category];
+ } elseif ($categorize === false) {
+ $includes = array_merge(
+ $this->includes['require_once'],
+ $this->includes['require'],
+ $this->includes['include_once'],
+ $this->includes['include']
+ );
+ } else {
+ $includes = $this->includes;
+ }
+
+ return $includes;
+ }
+
+ /**
+ * Returns the name of the function or method a line belongs to.
+ *
+ * @return string or null if the line is not in a function or method
+ */
+ public function getFunctionForLine($line)
+ {
+ $this->parse();
+
+ if (isset($this->lineToFunctionMap[$line])) {
+ return $this->lineToFunctionMap[$line];
+ }
+ }
+
+ protected function parse()
+ {
+ $this->interfaces = [];
+ $this->classes = [];
+ $this->traits = [];
+ $this->functions = [];
+ $class = [];
+ $classEndLine = [];
+ $trait = false;
+ $traitEndLine = false;
+ $interface = false;
+ $interfaceEndLine = false;
+
+ foreach ($this->tokens as $token) {
+ switch (get_class($token)) {
+ case 'PHP_Token_HALT_COMPILER':
+ return;
+
+ case 'PHP_Token_INTERFACE':
+ $interface = $token->getName();
+ $interfaceEndLine = $token->getEndLine();
+
+ $this->interfaces[$interface] = [
+ 'methods' => [],
+ 'parent' => $token->getParent(),
+ 'keywords' => $token->getKeywords(),
+ 'docblock' => $token->getDocblock(),
+ 'startLine' => $token->getLine(),
+ 'endLine' => $interfaceEndLine,
+ 'package' => $token->getPackage(),
+ 'file' => $this->filename
+ ];
+ break;
+
+ case 'PHP_Token_CLASS':
+ case 'PHP_Token_TRAIT':
+ $tmp = [
+ 'methods' => [],
+ 'parent' => $token->getParent(),
+ 'interfaces'=> $token->getInterfaces(),
+ 'keywords' => $token->getKeywords(),
+ 'docblock' => $token->getDocblock(),
+ 'startLine' => $token->getLine(),
+ 'endLine' => $token->getEndLine(),
+ 'package' => $token->getPackage(),
+ 'file' => $this->filename
+ ];
+
+ if ($token instanceof PHP_Token_CLASS) {
+ $class[] = $token->getName();
+ $classEndLine[] = $token->getEndLine();
+
+ $this->classes[$class[count($class) - 1]] = $tmp;
+ } else {
+ $trait = $token->getName();
+ $traitEndLine = $token->getEndLine();
+ $this->traits[$trait] = $tmp;
+ }
+ break;
+
+ case 'PHP_Token_FUNCTION':
+ $name = $token->getName();
+ $tmp = [
+ 'docblock' => $token->getDocblock(),
+ 'keywords' => $token->getKeywords(),
+ 'visibility'=> $token->getVisibility(),
+ 'signature' => $token->getSignature(),
+ 'startLine' => $token->getLine(),
+ 'endLine' => $token->getEndLine(),
+ 'ccn' => $token->getCCN(),
+ 'file' => $this->filename
+ ];
+
+ if (empty($class) &&
+ $trait === false &&
+ $interface === false) {
+ $this->functions[$name] = $tmp;
+
+ $this->addFunctionToMap(
+ $name,
+ $tmp['startLine'],
+ $tmp['endLine']
+ );
+ } elseif (!empty($class)) {
+ $this->classes[$class[count($class) - 1]]['methods'][$name] = $tmp;
+
+ $this->addFunctionToMap(
+ $class[count($class) - 1] . '::' . $name,
+ $tmp['startLine'],
+ $tmp['endLine']
+ );
+ } elseif ($trait !== false) {
+ $this->traits[$trait]['methods'][$name] = $tmp;
+
+ $this->addFunctionToMap(
+ $trait . '::' . $name,
+ $tmp['startLine'],
+ $tmp['endLine']
+ );
+ } else {
+ $this->interfaces[$interface]['methods'][$name] = $tmp;
+ }
+ break;
+
+ case 'PHP_Token_CLOSE_CURLY':
+ if (!empty($classEndLine) &&
+ $classEndLine[count($classEndLine) - 1] == $token->getLine()) {
+ array_pop($classEndLine);
+ array_pop($class);
+ } elseif ($traitEndLine !== false &&
+ $traitEndLine == $token->getLine()) {
+ $trait = false;
+ $traitEndLine = false;
+ } elseif ($interfaceEndLine !== false &&
+ $interfaceEndLine == $token->getLine()) {
+ $interface = false;
+ $interfaceEndLine = false;
+ }
+ break;
+ }
+ }
+ }
+
+ /**
+ * @return array
+ */
+ public function getLinesOfCode()
+ {
+ return $this->linesOfCode;
+ }
+
+ /**
+ */
+ public function rewind()
+ {
+ $this->position = 0;
+ }
+
+ /**
+ * @return bool
+ */
+ public function valid()
+ {
+ return isset($this->tokens[$this->position]);
+ }
+
+ /**
+ * @return int
+ */
+ public function key()
+ {
+ return $this->position;
+ }
+
+ /**
+ * @return PHP_Token
+ */
+ public function current()
+ {
+ return $this->tokens[$this->position];
+ }
+
+ /**
+ */
+ public function next()
+ {
+ $this->position++;
+ }
+
+ /**
+ * @param int $offset
+ *
+ * @return bool
+ */
+ public function offsetExists($offset)
+ {
+ return isset($this->tokens[$offset]);
+ }
+
+ /**
+ * @param int $offset
+ *
+ * @return mixed
+ *
+ * @throws OutOfBoundsException
+ */
+ public function offsetGet($offset)
+ {
+ if (!$this->offsetExists($offset)) {
+ throw new OutOfBoundsException(
+ sprintf(
+ 'No token at position "%s"',
+ $offset
+ )
+ );
+ }
+
+ return $this->tokens[$offset];
+ }
+
+ /**
+ * @param int $offset
+ * @param mixed $value
+ */
+ public function offsetSet($offset, $value)
+ {
+ $this->tokens[$offset] = $value;
+ }
+
+ /**
+ * @param int $offset
+ *
+ * @throws OutOfBoundsException
+ */
+ public function offsetUnset($offset)
+ {
+ if (!$this->offsetExists($offset)) {
+ throw new OutOfBoundsException(
+ sprintf(
+ 'No token at position "%s"',
+ $offset
+ )
+ );
+ }
+
+ unset($this->tokens[$offset]);
+ }
+
+ /**
+ * Seek to an absolute position.
+ *
+ * @param int $position
+ *
+ * @throws OutOfBoundsException
+ */
+ public function seek($position)
+ {
+ $this->position = $position;
+
+ if (!$this->valid()) {
+ throw new OutOfBoundsException(
+ sprintf(
+ 'No token at position "%s"',
+ $this->position
+ )
+ );
+ }
+ }
+
+ /**
+ * @param string $name
+ * @param int $startLine
+ * @param int $endLine
+ */
+ private function addFunctionToMap($name, $startLine, $endLine)
+ {
+ for ($line = $startLine; $line <= $endLine; $line++) {
+ $this->lineToFunctionMap[$line] = $name;
+ }
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php b/vendor/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php
new file mode 100644
index 0000000..9d69393
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php
@@ -0,0 +1,46 @@
+<?php
+/*
+ * This file is part of php-token-stream.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A caching factory for token stream objects.
+ */
+class PHP_Token_Stream_CachingFactory
+{
+ /**
+ * @var array
+ */
+ protected static $cache = [];
+
+ /**
+ * @param string $filename
+ *
+ * @return PHP_Token_Stream
+ */
+ public static function get($filename)
+ {
+ if (!isset(self::$cache[$filename])) {
+ self::$cache[$filename] = new PHP_Token_Stream($filename);
+ }
+
+ return self::$cache[$filename];
+ }
+
+ /**
+ * @param string $filename
+ */
+ public static function clear($filename = null)
+ {
+ if (is_string($filename)) {
+ unset(self::$cache[$filename]);
+ } else {
+ self::$cache = [];
+ }
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/tests/Token/ClassTest.php b/vendor/phpunit/php-token-stream/tests/Token/ClassTest.php
new file mode 100644
index 0000000..265a656
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/Token/ClassTest.php
@@ -0,0 +1,169 @@
+<?php
+/*
+ * This file is part of php-token-stream.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use PHPUnit\Framework\TestCase;
+
+class PHP_Token_ClassTest extends TestCase
+{
+ /**
+ * @var PHP_Token_CLASS
+ */
+ private $class;
+
+ /**
+ * @var PHP_Token_FUNCTION
+ */
+ private $function;
+
+ protected function setUp()
+ {
+ $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'source2.php');
+
+ foreach ($ts as $token) {
+ if ($token instanceof PHP_Token_CLASS) {
+ $this->class = $token;
+ }
+
+ if ($token instanceof PHP_Token_FUNCTION) {
+ $this->function = $token;
+ break;
+ }
+ }
+ }
+
+ /**
+ * @covers PHP_Token_CLASS::getKeywords
+ */
+ public function testGetClassKeywords()
+ {
+ $this->assertEquals('abstract', $this->class->getKeywords());
+ }
+
+ /**
+ * @covers PHP_Token_FUNCTION::getKeywords
+ */
+ public function testGetFunctionKeywords()
+ {
+ $this->assertEquals('abstract,static', $this->function->getKeywords());
+ }
+
+ /**
+ * @covers PHP_Token_FUNCTION::getVisibility
+ */
+ public function testGetFunctionVisibility()
+ {
+ $this->assertEquals('public', $this->function->getVisibility());
+ }
+
+ public function testIssue19()
+ {
+ $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'issue19.php');
+
+ foreach ($ts as $token) {
+ if ($token instanceof PHP_Token_CLASS) {
+ $this->assertFalse($token->hasInterfaces());
+ }
+ }
+ }
+
+ public function testIssue30()
+ {
+ $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'issue30.php');
+ $this->assertCount(1, $ts->getClasses());
+ }
+
+ public function testAnonymousClassesAreHandledCorrectly()
+ {
+ $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'class_with_method_that_declares_anonymous_class.php');
+
+ $classes = $ts->getClasses();
+
+ $this->assertEquals(
+ [
+ 'class_with_method_that_declares_anonymous_class',
+ 'AnonymousClass:9#31',
+ 'AnonymousClass:10#55',
+ 'AnonymousClass:11#75',
+ 'AnonymousClass:12#91',
+ 'AnonymousClass:13#107'
+ ],
+ array_keys($classes)
+ );
+ }
+
+ /**
+ * @ticket https://github.com/sebastianbergmann/php-token-stream/issues/52
+ */
+ public function testAnonymousClassesAreHandledCorrectly2()
+ {
+ $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'class_with_method_that_declares_anonymous_class2.php');
+
+ $classes = $ts->getClasses();
+
+ $this->assertEquals(['Test', 'AnonymousClass:4#23'], array_keys($classes));
+ $this->assertEquals(['methodOne', 'methodTwo'], array_keys($classes['Test']['methods']));
+
+ $this->assertEmpty($ts->getFunctions());
+ }
+
+ public function testImportedFunctionsAreHandledCorrectly()
+ {
+ $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'classUsesNamespacedFunction.php');
+
+ $this->assertEmpty($ts->getFunctions());
+ $this->assertCount(1, $ts->getClasses());
+ }
+
+ /**
+ * @ticket https://github.com/sebastianbergmann/php-code-coverage/issues/543
+ */
+ public function testClassWithMultipleAnonymousClassesAndFunctionsIsHandledCorrectly()
+ {
+ $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'class_with_multiple_anonymous_classes_and_functions.php');
+
+ $classes = $ts->getClasses();
+
+ $this->assertArrayHasKey('class_with_multiple_anonymous_classes_and_functions', $classes);
+ $this->assertArrayHasKey('AnonymousClass:6#23', $classes);
+ $this->assertArrayHasKey('AnonymousClass:12#53', $classes);
+ $this->assertArrayHasKey('m', $classes['class_with_multiple_anonymous_classes_and_functions']['methods']);
+ $this->assertArrayHasKey('anonymousFunction:18#81', $classes['class_with_multiple_anonymous_classes_and_functions']['methods']);
+ $this->assertArrayHasKey('anonymousFunction:22#108', $classes['class_with_multiple_anonymous_classes_and_functions']['methods']);
+ }
+
+ /**
+ * @ticket https://github.com/sebastianbergmann/php-token-stream/issues/68
+ */
+ public function testClassWithMethodNamedEmptyIsHandledCorrectly()
+ {
+ $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'class_with_method_named_empty.php');
+
+ $classes = $ts->getClasses();
+
+ $this->assertArrayHasKey('class_with_method_named_empty', $classes);
+ $this->assertArrayHasKey('empty', $classes['class_with_method_named_empty']['methods']);
+ }
+
+ /**
+ * @ticket https://github.com/sebastianbergmann/php-code-coverage/issues/424
+ */
+ public function testSomething()
+ {
+ $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'php-code-coverage-issue-424.php');
+
+ $classes = $ts->getClasses();
+
+ $this->assertSame(5, $classes['Example']['methods']['even']['startLine']);
+ $this->assertSame(12, $classes['Example']['methods']['even']['endLine']);
+
+ $this->assertSame(7, $classes['Example']['methods']['anonymousFunction:7#28']['startLine']);
+ $this->assertSame(9, $classes['Example']['methods']['anonymousFunction:7#28']['endLine']);
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/tests/Token/ClosureTest.php b/vendor/phpunit/php-token-stream/tests/Token/ClosureTest.php
new file mode 100644
index 0000000..b4a6735
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/Token/ClosureTest.php
@@ -0,0 +1,78 @@
+<?php
+/*
+ * This file is part of php-token-stream.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use PHPUnit\Framework\TestCase;
+
+class PHP_Token_ClosureTest extends TestCase
+{
+ /**
+ * @var PHP_Token_FUNCTION[]
+ */
+ private $functions;
+
+ protected function setUp()
+ {
+ $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'closure.php');
+
+ foreach ($ts as $token) {
+ if ($token instanceof PHP_Token_FUNCTION) {
+ $this->functions[] = $token;
+ }
+ }
+ }
+
+ /**
+ * @covers PHP_Token_FUNCTION::getArguments
+ */
+ public function testGetArguments()
+ {
+ $this->assertEquals(['$foo' => null, '$bar' => null], $this->functions[0]->getArguments());
+ $this->assertEquals(['$foo' => 'Foo', '$bar' => null], $this->functions[1]->getArguments());
+ $this->assertEquals(['$foo' => null, '$bar' => null, '$baz' => null], $this->functions[2]->getArguments());
+ $this->assertEquals(['$foo' => 'Foo', '$bar' => null, '$baz' => null], $this->functions[3]->getArguments());
+ $this->assertEquals([], $this->functions[4]->getArguments());
+ $this->assertEquals([], $this->functions[5]->getArguments());
+ }
+
+ /**
+ * @covers PHP_Token_FUNCTION::getName
+ */
+ public function testGetName()
+ {
+ $this->assertEquals('anonymousFunction:2#5', $this->functions[0]->getName());
+ $this->assertEquals('anonymousFunction:3#27', $this->functions[1]->getName());
+ $this->assertEquals('anonymousFunction:4#51', $this->functions[2]->getName());
+ $this->assertEquals('anonymousFunction:5#71', $this->functions[3]->getName());
+ $this->assertEquals('anonymousFunction:6#93', $this->functions[4]->getName());
+ $this->assertEquals('anonymousFunction:7#106', $this->functions[5]->getName());
+ }
+
+ /**
+ * @covers PHP_Token::getLine
+ */
+ public function testGetLine()
+ {
+ $this->assertEquals(2, $this->functions[0]->getLine());
+ $this->assertEquals(3, $this->functions[1]->getLine());
+ $this->assertEquals(4, $this->functions[2]->getLine());
+ $this->assertEquals(5, $this->functions[3]->getLine());
+ }
+
+ /**
+ * @covers PHP_TokenWithScope::getEndLine
+ */
+ public function testGetEndLine()
+ {
+ $this->assertEquals(2, $this->functions[0]->getLine());
+ $this->assertEquals(3, $this->functions[1]->getLine());
+ $this->assertEquals(4, $this->functions[2]->getLine());
+ $this->assertEquals(5, $this->functions[3]->getLine());
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/tests/Token/FunctionTest.php b/vendor/phpunit/php-token-stream/tests/Token/FunctionTest.php
new file mode 100644
index 0000000..539f827
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/Token/FunctionTest.php
@@ -0,0 +1,139 @@
+<?php
+/*
+ * This file is part of php-token-stream.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use PHPUnit\Framework\TestCase;
+
+class PHP_Token_FunctionTest extends TestCase
+{
+ /**
+ * @var PHP_Token_FUNCTION[]
+ */
+ private $functions;
+
+ protected function setUp()
+ {
+ $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'source.php');
+
+ foreach ($ts as $token) {
+ if ($token instanceof PHP_Token_FUNCTION) {
+ $this->functions[] = $token;
+ }
+ }
+ }
+
+ /**
+ * @covers PHP_Token_FUNCTION::getArguments
+ */
+ public function testGetArguments()
+ {
+ $this->assertEquals([], $this->functions[0]->getArguments());
+
+ $this->assertEquals(
+ ['$baz' => 'Baz'], $this->functions[1]->getArguments()
+ );
+
+ $this->assertEquals(
+ ['$foobar' => 'Foobar'], $this->functions[2]->getArguments()
+ );
+
+ $this->assertEquals(
+ ['$barfoo' => 'Barfoo'], $this->functions[3]->getArguments()
+ );
+
+ $this->assertEquals([], $this->functions[4]->getArguments());
+
+ $this->assertEquals(['$x' => null, '$y' => null], $this->functions[5]->getArguments());
+ }
+
+ /**
+ * @covers PHP_Token_FUNCTION::getName
+ */
+ public function testGetName()
+ {
+ $this->assertEquals('foo', $this->functions[0]->getName());
+ $this->assertEquals('bar', $this->functions[1]->getName());
+ $this->assertEquals('foobar', $this->functions[2]->getName());
+ $this->assertEquals('barfoo', $this->functions[3]->getName());
+ $this->assertEquals('baz', $this->functions[4]->getName());
+ }
+
+ /**
+ * @covers PHP_Token::getLine
+ */
+ public function testGetLine()
+ {
+ $this->assertEquals(5, $this->functions[0]->getLine());
+ $this->assertEquals(10, $this->functions[1]->getLine());
+ $this->assertEquals(17, $this->functions[2]->getLine());
+ $this->assertEquals(21, $this->functions[3]->getLine());
+ $this->assertEquals(29, $this->functions[4]->getLine());
+ }
+
+ /**
+ * @covers PHP_TokenWithScope::getEndLine
+ */
+ public function testGetEndLine()
+ {
+ $this->assertEquals(5, $this->functions[0]->getEndLine());
+ $this->assertEquals(12, $this->functions[1]->getEndLine());
+ $this->assertEquals(19, $this->functions[2]->getEndLine());
+ $this->assertEquals(23, $this->functions[3]->getEndLine());
+ $this->assertEquals(31, $this->functions[4]->getEndLine());
+ }
+
+ /**
+ * @covers PHP_Token_FUNCTION::getDocblock
+ */
+ public function testGetDocblock()
+ {
+ $this->assertNull($this->functions[0]->getDocblock());
+
+ $this->assertEquals(
+ "/**\n * @param Baz \$baz\n */",
+ $this->functions[1]->getDocblock()
+ );
+
+ $this->assertEquals(
+ "/**\n * @param Foobar \$foobar\n */",
+ $this->functions[2]->getDocblock()
+ );
+
+ $this->assertNull($this->functions[3]->getDocblock());
+ $this->assertNull($this->functions[4]->getDocblock());
+ }
+
+ public function testSignature()
+ {
+ $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'source5.php');
+ $f = $ts->getFunctions();
+ $c = $ts->getClasses();
+ $i = $ts->getInterfaces();
+
+ $this->assertEquals(
+ 'foo($a, array $b, array $c = array())',
+ $f['foo']['signature']
+ );
+
+ $this->assertEquals(
+ 'm($a, array $b, array $c = array())',
+ $c['c']['methods']['m']['signature']
+ );
+
+ $this->assertEquals(
+ 'm($a, array $b, array $c = array())',
+ $c['a']['methods']['m']['signature']
+ );
+
+ $this->assertEquals(
+ 'm($a, array $b, array $c = array())',
+ $i['i']['methods']['m']['signature']
+ );
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/tests/Token/IncludeTest.php b/vendor/phpunit/php-token-stream/tests/Token/IncludeTest.php
new file mode 100644
index 0000000..2056d12
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/Token/IncludeTest.php
@@ -0,0 +1,65 @@
+<?php
+/*
+ * This file is part of php-token-stream.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use PHPUnit\Framework\TestCase;
+
+class PHP_Token_IncludeTest extends TestCase
+{
+ /**
+ * @var PHP_Token_Stream
+ */
+ private $ts;
+
+ protected function setUp()
+ {
+ $this->ts = new PHP_Token_Stream(TEST_FILES_PATH . 'source3.php');
+ }
+
+ /**
+ * @covers PHP_Token_Includes::getName
+ * @covers PHP_Token_Includes::getType
+ */
+ public function testGetIncludes()
+ {
+ $this->assertSame(
+ ['test4.php', 'test3.php', 'test2.php', 'test1.php'],
+ $this->ts->getIncludes()
+ );
+ }
+
+ /**
+ * @covers PHP_Token_Includes::getName
+ * @covers PHP_Token_Includes::getType
+ */
+ public function testGetIncludesCategorized()
+ {
+ $this->assertSame(
+ [
+ 'require_once' => ['test4.php'],
+ 'require' => ['test3.php'],
+ 'include_once' => ['test2.php'],
+ 'include' => ['test1.php']
+ ],
+ $this->ts->getIncludes(true)
+ );
+ }
+
+ /**
+ * @covers PHP_Token_Includes::getName
+ * @covers PHP_Token_Includes::getType
+ */
+ public function testGetIncludesCategory()
+ {
+ $this->assertSame(
+ ['test4.php'],
+ $this->ts->getIncludes(true, 'require_once')
+ );
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/tests/Token/InterfaceTest.php b/vendor/phpunit/php-token-stream/tests/Token/InterfaceTest.php
new file mode 100644
index 0000000..9e8cb24
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/Token/InterfaceTest.php
@@ -0,0 +1,195 @@
+<?php
+/*
+ * This file is part of php-token-stream.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use PHPUnit\Framework\TestCase;
+
+class PHP_Token_InterfaceTest extends TestCase
+{
+ /**
+ * @var PHP_Token_CLASS
+ */
+ private $class;
+
+ /**
+ * @var PHP_Token_INTERFACE[]
+ */
+ private $interfaces;
+
+ protected function setUp()
+ {
+ $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'source4.php');
+ $i = 0;
+
+ foreach ($ts as $token) {
+ if ($token instanceof PHP_Token_CLASS) {
+ $this->class = $token;
+ } elseif ($token instanceof PHP_Token_INTERFACE) {
+ $this->interfaces[$i] = $token;
+ $i++;
+ }
+ }
+ }
+
+ /**
+ * @covers PHP_Token_INTERFACE::getName
+ */
+ public function testGetName()
+ {
+ $this->assertEquals(
+ 'iTemplate', $this->interfaces[0]->getName()
+ );
+ }
+
+ /**
+ * @covers PHP_Token_INTERFACE::getParent
+ */
+ public function testGetParentNotExists()
+ {
+ $this->assertFalse(
+ $this->interfaces[0]->getParent()
+ );
+ }
+
+ /**
+ * @covers PHP_Token_INTERFACE::hasParent
+ */
+ public function testHasParentNotExists()
+ {
+ $this->assertFalse(
+ $this->interfaces[0]->hasParent()
+ );
+ }
+
+ /**
+ * @covers PHP_Token_INTERFACE::getParent
+ */
+ public function testGetParentExists()
+ {
+ $this->assertEquals(
+ 'a', $this->interfaces[2]->getParent()
+ );
+ }
+
+ /**
+ * @covers PHP_Token_INTERFACE::hasParent
+ */
+ public function testHasParentExists()
+ {
+ $this->assertTrue(
+ $this->interfaces[2]->hasParent()
+ );
+ }
+
+ /**
+ * @covers PHP_Token_INTERFACE::getInterfaces
+ */
+ public function testGetInterfacesExists()
+ {
+ $this->assertEquals(
+ ['b'],
+ $this->class->getInterfaces()
+ );
+ }
+
+ /**
+ * @covers PHP_Token_INTERFACE::hasInterfaces
+ */
+ public function testHasInterfacesExists()
+ {
+ $this->assertTrue(
+ $this->class->hasInterfaces()
+ );
+ }
+
+ /**
+ * @covers PHP_Token_INTERFACE::getPackage
+ */
+ public function testGetPackageNamespace()
+ {
+ $tokenStream = new PHP_Token_Stream(TEST_FILES_PATH . 'classInNamespace.php');
+ foreach ($tokenStream as $token) {
+ if ($token instanceof PHP_Token_INTERFACE) {
+ $package = $token->getPackage();
+ $this->assertSame('Foo\\Bar', $package['namespace']);
+ }
+ }
+ }
+
+
+ public function provideFilesWithClassesWithinMultipleNamespaces()
+ {
+ return [
+ [TEST_FILES_PATH . 'multipleNamespacesWithOneClassUsingBraces.php'],
+ [TEST_FILES_PATH . 'multipleNamespacesWithOneClassUsingNonBraceSyntax.php'],
+ ];
+ }
+
+ /**
+ * @dataProvider provideFilesWithClassesWithinMultipleNamespaces
+ * @covers PHP_Token_INTERFACE::getPackage
+ */
+ public function testGetPackageNamespaceForFileWithMultipleNamespaces($filepath)
+ {
+ $tokenStream = new PHP_Token_Stream($filepath);
+ $firstClassFound = false;
+ foreach ($tokenStream as $token) {
+ if ($firstClassFound === false && $token instanceof PHP_Token_INTERFACE) {
+ $package = $token->getPackage();
+ $this->assertSame('TestClassInBar', $token->getName());
+ $this->assertSame('Foo\\Bar', $package['namespace']);
+ $firstClassFound = true;
+ continue;
+ }
+ // Secound class
+ if ($token instanceof PHP_Token_INTERFACE) {
+ $package = $token->getPackage();
+ $this->assertSame('TestClassInBaz', $token->getName());
+ $this->assertSame('Foo\\Baz', $package['namespace']);
+
+ return;
+ }
+ }
+ $this->fail('Seachring for 2 classes failed');
+ }
+
+ public function testGetPackageNamespaceIsEmptyForInterfacesThatAreNotWithinNamespaces()
+ {
+ foreach ($this->interfaces as $token) {
+ $package = $token->getPackage();
+ $this->assertSame('', $package['namespace']);
+ }
+ }
+
+ /**
+ * @covers PHP_Token_INTERFACE::getPackage
+ */
+ public function testGetPackageNamespaceWhenExtentingFromNamespaceClass()
+ {
+ $tokenStream = new PHP_Token_Stream(TEST_FILES_PATH . 'classExtendsNamespacedClass.php');
+ $firstClassFound = false;
+ foreach ($tokenStream as $token) {
+ if ($firstClassFound === false && $token instanceof PHP_Token_INTERFACE) {
+ $package = $token->getPackage();
+ $this->assertSame('Baz', $token->getName());
+ $this->assertSame('Foo\\Bar', $package['namespace']);
+ $firstClassFound = true;
+ continue;
+ }
+ if ($token instanceof PHP_Token_INTERFACE) {
+ $package = $token->getPackage();
+ $this->assertSame('Extender', $token->getName());
+ $this->assertSame('Other\\Space', $package['namespace']);
+
+ return;
+ }
+ }
+ $this->fail('Searching for 2 classes failed');
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/tests/Token/NamespaceTest.php b/vendor/phpunit/php-token-stream/tests/Token/NamespaceTest.php
new file mode 100644
index 0000000..98360cf
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/Token/NamespaceTest.php
@@ -0,0 +1,69 @@
+<?php
+/*
+ * This file is part of php-token-stream.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use PHPUnit\Framework\TestCase;
+
+class PHP_Token_NamespaceTest extends TestCase
+{
+ /**
+ * @covers PHP_Token_NAMESPACE::getName
+ */
+ public function testGetName()
+ {
+ $tokenStream = new PHP_Token_Stream(
+ TEST_FILES_PATH . 'classInNamespace.php'
+ );
+
+ foreach ($tokenStream as $token) {
+ if ($token instanceof PHP_Token_NAMESPACE) {
+ $this->assertSame('Foo\\Bar', $token->getName());
+ }
+ }
+ }
+
+ public function testGetStartLineWithUnscopedNamespace()
+ {
+ $tokenStream = new PHP_Token_Stream(TEST_FILES_PATH . 'classInNamespace.php');
+ foreach ($tokenStream as $token) {
+ if ($token instanceof PHP_Token_NAMESPACE) {
+ $this->assertSame(2, $token->getLine());
+ }
+ }
+ }
+
+ public function testGetEndLineWithUnscopedNamespace()
+ {
+ $tokenStream = new PHP_Token_Stream(TEST_FILES_PATH . 'classInNamespace.php');
+ foreach ($tokenStream as $token) {
+ if ($token instanceof PHP_Token_NAMESPACE) {
+ $this->assertSame(2, $token->getEndLine());
+ }
+ }
+ }
+ public function testGetStartLineWithScopedNamespace()
+ {
+ $tokenStream = new PHP_Token_Stream(TEST_FILES_PATH . 'classInScopedNamespace.php');
+ foreach ($tokenStream as $token) {
+ if ($token instanceof PHP_Token_NAMESPACE) {
+ $this->assertSame(2, $token->getLine());
+ }
+ }
+ }
+
+ public function testGetEndLineWithScopedNamespace()
+ {
+ $tokenStream = new PHP_Token_Stream(TEST_FILES_PATH . 'classInScopedNamespace.php');
+ foreach ($tokenStream as $token) {
+ if ($token instanceof PHP_Token_NAMESPACE) {
+ $this->assertSame(8, $token->getEndLine());
+ }
+ }
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/tests/TokenTest.php b/vendor/phpunit/php-token-stream/tests/TokenTest.php
new file mode 100644
index 0000000..e4bbb80
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/TokenTest.php
@@ -0,0 +1,32 @@
+<?php
+/*
+ * This file is part of php-token-stream.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use PHPUnit\Framework\TestCase;
+
+class PHP_TokenTest extends TestCase
+{
+ /**
+ * @covers PHP_Token::__construct
+ * @covers PHP_Token::__toString
+ */
+ public function testToString()
+ {
+ $this->markTestIncomplete();
+ }
+
+ /**
+ * @covers PHP_Token::__construct
+ * @covers PHP_Token::getLine
+ */
+ public function testGetLine()
+ {
+ $this->markTestIncomplete();
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/classExtendsNamespacedClass.php b/vendor/phpunit/php-token-stream/tests/_fixture/classExtendsNamespacedClass.php
new file mode 100644
index 0000000..560eec9
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/classExtendsNamespacedClass.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace Foo\Bar;
+
+class Baz {}
+
+namespace Other\Space;
+
+class Extender extends \Foo\Bar\Baz {}
+
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/classInNamespace.php b/vendor/phpunit/php-token-stream/tests/_fixture/classInNamespace.php
new file mode 100644
index 0000000..8ade7cd
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/classInNamespace.php
@@ -0,0 +1,6 @@
+<?php
+namespace Foo\Bar;
+
+class TestClass
+{
+}
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/classInScopedNamespace.php b/vendor/phpunit/php-token-stream/tests/_fixture/classInScopedNamespace.php
new file mode 100644
index 0000000..1ba475c
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/classInScopedNamespace.php
@@ -0,0 +1,9 @@
+<?php
+namespace Foo\BarScoped {
+
+ class TestClass {
+
+ }
+
+}
+
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/classUsesNamespacedFunction.php b/vendor/phpunit/php-token-stream/tests/_fixture/classUsesNamespacedFunction.php
new file mode 100644
index 0000000..5e08a12
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/classUsesNamespacedFunction.php
@@ -0,0 +1,8 @@
+<?php
+namespace foo;
+
+use function bar\baz;
+
+class Foo
+{
+} \ No newline at end of file
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_named_empty.php b/vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_named_empty.php
new file mode 100644
index 0000000..1dafc18
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_named_empty.php
@@ -0,0 +1,7 @@
+<?php
+class class_with_method_named_empty
+{
+ public function empty(): void
+ {
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_that_declares_anonymous_class.php b/vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_that_declares_anonymous_class.php
new file mode 100644
index 0000000..4a02fe1
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_that_declares_anonymous_class.php
@@ -0,0 +1,15 @@
+<?php
+interface foo {
+}
+
+class class_with_method_that_declares_anonymous_class
+{
+ public function method()
+ {
+ $o = new class { public function foo() {} };
+ $o = new class{public function foo(){}};
+ $o = new class extends stdClass {};
+ $o = new class extends stdClass {};
+ $o = new class implements foo {};
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_that_declares_anonymous_class2.php b/vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_that_declares_anonymous_class2.php
new file mode 100644
index 0000000..9f3ee28
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_that_declares_anonymous_class2.php
@@ -0,0 +1,16 @@
+<?php
+class Test {
+ public function methodOne() {
+ $foo = new class {
+ public function method_in_anonymous_class() {
+ return true;
+ }
+ };
+
+ return $foo->method_in_anonymous_class();
+ }
+
+ public function methodTwo() {
+ return false;
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/class_with_multiple_anonymous_classes_and_functions.php b/vendor/phpunit/php-token-stream/tests/_fixture/class_with_multiple_anonymous_classes_and_functions.php
new file mode 100644
index 0000000..3267ba5
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/class_with_multiple_anonymous_classes_and_functions.php
@@ -0,0 +1,26 @@
+<?php
+class class_with_multiple_anonymous_classes_and_functions
+{
+ public function m()
+ {
+ $c = new class {
+ public function n() {
+ return true;
+ }
+ };
+
+ $d = new class {
+ public function o() {
+ return false;
+ }
+ };
+
+ $f = function ($a, $b) {
+ return $a + $b;
+ };
+
+ $g = function ($a, $b) {
+ return $a - $b;
+ };
+ }
+} \ No newline at end of file
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/closure.php b/vendor/phpunit/php-token-stream/tests/_fixture/closure.php
new file mode 100644
index 0000000..a0e3a81
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/closure.php
@@ -0,0 +1,7 @@
+<?php
+$function1 = function($foo, $bar) use ($var) {};
+$function2 = function(Foo $foo, $bar) use ($var) {};
+$function3 = function ($foo, $bar, $baz) {};
+$function4 = function (Foo $foo, $bar, $baz) {};
+$function5 = function () {};
+$function6 = function() {};
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/issue19.php b/vendor/phpunit/php-token-stream/tests/_fixture/issue19.php
new file mode 100644
index 0000000..91eeb47
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/issue19.php
@@ -0,0 +1,3 @@
+<?php
+class TestClass {
+}
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/issue30.php b/vendor/phpunit/php-token-stream/tests/_fixture/issue30.php
new file mode 100644
index 0000000..0d1f6f3
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/issue30.php
@@ -0,0 +1,8 @@
+<?php
+class Foo
+{
+ public function bar()
+ {
+ return Foo::CLASS;
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/multipleNamespacesWithOneClassUsingBraces.php b/vendor/phpunit/php-token-stream/tests/_fixture/multipleNamespacesWithOneClassUsingBraces.php
new file mode 100644
index 0000000..d3a12e3
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/multipleNamespacesWithOneClassUsingBraces.php
@@ -0,0 +1,12 @@
+<?php
+namespace Foo\Bar;
+
+class TestClassInBar
+{
+}
+
+namespace Foo\Baz;
+
+class TestClassInBaz
+{
+}
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/multipleNamespacesWithOneClassUsingNonBraceSyntax.php b/vendor/phpunit/php-token-stream/tests/_fixture/multipleNamespacesWithOneClassUsingNonBraceSyntax.php
new file mode 100644
index 0000000..4ee4f24
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/multipleNamespacesWithOneClassUsingNonBraceSyntax.php
@@ -0,0 +1,14 @@
+<?php
+namespace Foo\Bar
+{
+ class TestClassInBar
+ {
+ }
+}
+
+namespace Foo\Baz
+{
+ class TestClassInBaz
+ {
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/php-code-coverage-issue-424.php b/vendor/phpunit/php-token-stream/tests/_fixture/php-code-coverage-issue-424.php
new file mode 100644
index 0000000..457e0bb
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/php-code-coverage-issue-424.php
@@ -0,0 +1,13 @@
+<?php
+
+class Example
+{
+ public function even($numbers)
+ {
+ $numbers = array_filter($numbers, function($number) {
+ return $number % 2 === 0;
+ });
+
+ return array_merge($numbers);
+ }
+} \ No newline at end of file
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/source.php b/vendor/phpunit/php-token-stream/tests/_fixture/source.php
new file mode 100644
index 0000000..0c9b87f
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/source.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Some comment
+ */
+class Foo{function foo(){}
+
+ /**
+ * @param Baz $baz
+ */
+ public function bar(Baz $baz)
+ {
+ }
+
+ /**
+ * @param Foobar $foobar
+ */
+ static public function foobar(Foobar $foobar)
+ {
+ }
+
+ public function barfoo(Barfoo $barfoo)
+ {
+ }
+
+ /**
+ * This docblock does not belong to the baz function
+ */
+
+ public function baz()
+ {
+ }
+
+ public function blaz($x, $y)
+ {
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/source2.php b/vendor/phpunit/php-token-stream/tests/_fixture/source2.php
new file mode 100644
index 0000000..b33dce1
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/source2.php
@@ -0,0 +1,6 @@
+<?php
+// short desc
+abstract class A {
+ /* abst meth: */
+ public static abstract function method();
+}
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/source3.php b/vendor/phpunit/php-token-stream/tests/_fixture/source3.php
new file mode 100644
index 0000000..7e42b60
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/source3.php
@@ -0,0 +1,14 @@
+<?php
+// This file is example#1
+// from http://www.php.net/manual/en/function.get-included-files.php
+
+include 'test1.php';
+include_once 'test2.php';
+require 'test3.php';
+require_once 'test4.php';
+
+$included_files = get_included_files();
+
+foreach ($included_files as $filename) {
+ echo "$filename\n";
+}
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/source4.php b/vendor/phpunit/php-token-stream/tests/_fixture/source4.php
new file mode 100644
index 0000000..6b064fc
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/source4.php
@@ -0,0 +1,30 @@
+<?php
+// Declare the interface 'iTemplate'
+interface iTemplate
+{
+ public function setVariable($name, $var);
+ public function
+ getHtml($template);
+}
+
+interface a
+{
+ public function foo();
+}
+
+interface b extends a
+{
+ public function baz(Baz $baz);
+}
+
+// short desc for class that implement a unique interface
+class c implements b
+{
+ public function foo()
+ {
+ }
+
+ public function baz(Baz $baz)
+ {
+ }
+}
diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/source5.php b/vendor/phpunit/php-token-stream/tests/_fixture/source5.php
new file mode 100644
index 0000000..ef7d474
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/_fixture/source5.php
@@ -0,0 +1,5 @@
+<?php
+function foo($a, array $b, array $c = array()) {}
+interface i { public function m($a, array $b, array $c = array()); }
+abstract class a { abstract public function m($a, array $b, array $c = array()); }
+class c { public function m($a, array $b, array $c = array()) {} }
diff --git a/vendor/phpunit/php-token-stream/tests/bootstrap.php b/vendor/phpunit/php-token-stream/tests/bootstrap.php
new file mode 100644
index 0000000..bcd0f64
--- /dev/null
+++ b/vendor/phpunit/php-token-stream/tests/bootstrap.php
@@ -0,0 +1,15 @@
+<?php
+/*
+ * This file is part of php-token-stream.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+require __DIR__ . '/../vendor/autoload.php';
+
+define(
+ 'TEST_FILES_PATH',
+ __DIR__ . DIRECTORY_SEPARATOR . '_fixture' . DIRECTORY_SEPARATOR
+);
diff --git a/vendor/phpunit/phpunit-mock-objects/.gitattributes b/vendor/phpunit/phpunit-mock-objects/.gitattributes
new file mode 100644
index 0000000..461090b
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/.gitattributes
@@ -0,0 +1 @@
+*.php diff=php
diff --git a/vendor/phpunit/phpunit-mock-objects/.gitignore b/vendor/phpunit/phpunit-mock-objects/.gitignore
new file mode 100644
index 0000000..77352f5
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/.gitignore
@@ -0,0 +1,7 @@
+build/coverage
+build/logs
+cache.properties
+/vendor
+/composer.lock
+/composer.phar
+/.idea
diff --git a/vendor/phpunit/phpunit-mock-objects/.php_cs b/vendor/phpunit/phpunit-mock-objects/.php_cs
new file mode 100644
index 0000000..b7393bd
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/.php_cs
@@ -0,0 +1,67 @@
+<?php
+$finder = Symfony\CS\Finder\DefaultFinder::create()
+ ->files()
+ ->in('src')
+ ->in('tests')
+ ->name('*.php');
+
+return Symfony\CS\Config\Config::create()
+ ->level(\Symfony\CS\FixerInterface::NONE_LEVEL)
+ ->fixers(
+ array(
+ 'align_double_arrow',
+ 'align_equals',
+ 'braces',
+ 'concat_with_spaces',
+ 'duplicate_semicolon',
+ 'elseif',
+ 'empty_return',
+ 'encoding',
+ 'eof_ending',
+ 'extra_empty_lines',
+ 'function_call_space',
+ 'function_declaration',
+ 'indentation',
+ 'join_function',
+ 'line_after_namespace',
+ 'linefeed',
+ 'list_commas',
+ 'lowercase_constants',
+ 'lowercase_keywords',
+ 'method_argument_space',
+ 'multiple_use',
+ 'namespace_no_leading_whitespace',
+ 'no_blank_lines_after_class_opening',
+ 'no_empty_lines_after_phpdocs',
+ 'parenthesis',
+ 'php_closing_tag',
+ 'phpdoc_indent',
+ 'phpdoc_no_access',
+ 'phpdoc_no_empty_return',
+ 'phpdoc_no_package',
+ 'phpdoc_params',
+ 'phpdoc_scalar',
+ 'phpdoc_separation',
+ 'phpdoc_to_comment',
+ 'phpdoc_trim',
+ 'phpdoc_types',
+ 'phpdoc_var_without_name',
+ 'remove_lines_between_uses',
+ 'return',
+ 'self_accessor',
+ 'short_array_syntax',
+ 'short_tag',
+ 'single_line_after_imports',
+ 'single_quote',
+ 'spaces_before_semicolon',
+ 'spaces_cast',
+ 'ternary_spaces',
+ 'trailing_spaces',
+ 'trim_array_spaces',
+ 'unused_use',
+ 'visibility',
+ 'whitespacy_lines'
+ )
+ )
+ ->finder($finder);
+
diff --git a/vendor/phpunit/phpunit-mock-objects/.travis.yml b/vendor/phpunit/phpunit-mock-objects/.travis.yml
new file mode 100644
index 0000000..1e11d43
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/.travis.yml
@@ -0,0 +1,28 @@
+language: php
+
+php:
+ - 5.6
+ - 7.0
+ - 7.0snapshot
+ - 7.1
+ - 7.1snapshot
+ - master
+
+sudo: false
+
+before_install:
+ - composer self-update
+ - composer clear-cache
+
+install:
+ - travis_retry composer update --no-interaction --no-ansi --no-progress --no-suggest --optimize-autoloader --prefer-stable
+
+script:
+ - ./vendor/bin/phpunit --coverage-clover=coverage.xml
+
+after_success:
+ - bash <(curl -s https://codecov.io/bash)
+
+notifications:
+ email: false
+
diff --git a/vendor/phpunit/phpunit-mock-objects/CONTRIBUTING.md b/vendor/phpunit/phpunit-mock-objects/CONTRIBUTING.md
new file mode 100644
index 0000000..76a4345
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/CONTRIBUTING.md
@@ -0,0 +1 @@
+Please refer to [https://github.com/sebastianbergmann/phpunit/blob/master/CONTRIBUTING.md](https://github.com/sebastianbergmann/phpunit/blob/master/CONTRIBUTING.md) for details on how to contribute to this project.
diff --git a/vendor/phpunit/phpunit-mock-objects/LICENSE b/vendor/phpunit/phpunit-mock-objects/LICENSE
new file mode 100644
index 0000000..3705d2b
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/LICENSE
@@ -0,0 +1,33 @@
+PHPUnit_MockObject
+
+Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
+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/phpunit/phpunit-mock-objects/README.md b/vendor/phpunit/phpunit-mock-objects/README.md
new file mode 100644
index 0000000..0f828ba
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/README.md
@@ -0,0 +1,22 @@
+[![Latest Stable Version](https://img.shields.io/packagist/v/phpunit/phpunit-mock-objects.svg?style=flat-square)](https://packagist.org/packages/phpunit/phpunit-mock-objects)
+[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%205.6-8892BF.svg?style=flat-square)](https://php.net/)
+[![Build Status](https://img.shields.io/travis/sebastianbergmann/phpunit-mock-objects/master.svg?style=flat-square)](https://travis-ci.org/sebastianbergmann/phpunit-mock-objects)
+
+# PHPUnit_MockObject
+
+**PHPUnit_MockObject** is the default mock object library for PHPUnit.
+
+## Requirements
+
+* PHP 5.6 is required but using the latest version of PHP is highly recommended
+
+## Installation
+
+You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
+
+ composer require phpunit/phpunit-mock-objects
+
+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 phpunit/phpunit-mock-objects
+
diff --git a/vendor/phpunit/phpunit-mock-objects/build.xml b/vendor/phpunit/phpunit-mock-objects/build.xml
new file mode 100644
index 0000000..c93503e
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/build.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="PHPUnit_MockObjects">
+ <target name="clean" description="Cleanup build artifacts">
+ <delete dir="${basedir}/vendor"/>
+ <delete file="${basedir}/composer.lock"/>
+
+ <delete>
+ <fileset dir="${basedir}/build">
+ <include name="**/*.phar" />
+ </fileset>
+ </delete>
+ </target>
+
+ <target name="composer" depends="clean" description="Install dependencies with Composer">
+ <tstamp>
+ <format property="thirty.days.ago" pattern="MM/dd/yyyy hh:mm aa" offset="-30" unit="day"/>
+ </tstamp>
+ <delete>
+ <fileset dir="${basedir}">
+ <include name="composer.phar" />
+ <date datetime="${thirty.days.ago}" when="before"/>
+ </fileset>
+ </delete>
+
+ <get src="https://getcomposer.org/composer.phar" dest="${basedir}/composer.phar" skipexisting="true"/>
+
+ <exec executable="php">
+ <arg value="composer.phar"/>
+ <arg value="install"/>
+ </exec>
+ </target>
+
+ <target name="phpcs" description="Find coding standard violations using PHP_CodeSniffer">
+ <exec executable="phpcs">
+ <arg value="--standard=PSR2" />
+ <arg value="--extensions=php" />
+ <arg path="${basedir}/src" />
+ <arg path="${basedir}/tests" />
+ </exec>
+ </target>
+</project>
+
diff --git a/vendor/phpunit/phpunit-mock-objects/composer.json b/vendor/phpunit/phpunit-mock-objects/composer.json
new file mode 100644
index 0000000..78dfcf2
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/composer.json
@@ -0,0 +1,53 @@
+{
+ "name": "phpunit/phpunit-mock-objects",
+ "description": "Mock Object library for PHPUnit",
+ "type": "library",
+ "keywords": [
+ "xunit",
+ "mock"
+ ],
+ "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/phpunit-mock-objects/issues",
+ "irc": "irc://irc.freenode.net/phpunit"
+ },
+ "require": {
+ "php": "^5.6 || ^7.0",
+ "phpunit/php-text-template": "^1.2",
+ "doctrine/instantiator": "^1.0.2",
+ "sebastian/exporter": "^1.2 || ^2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.4"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<5.4.0"
+ },
+ "suggest": {
+ "ext-soap": "*"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "autoload-dev": {
+ "classmap": [
+ "tests/_fixture/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2.x-dev"
+ }
+ }
+}
+
diff --git a/vendor/phpunit/phpunit-mock-objects/phpunit.xml b/vendor/phpunit/phpunit-mock-objects/phpunit.xml
new file mode 100644
index 0000000..b370d6a
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/phpunit.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/5.6/phpunit.xsd"
+ bootstrap="tests/bootstrap.php"
+ backupGlobals="false"
+ beStrictAboutCoversAnnotation="true"
+ beStrictAboutOutputDuringTests="true"
+ beStrictAboutTestsThatDoNotTestAnything="true"
+ beStrictAboutTodoAnnotatedTests="true"
+ verbose="true">
+ <testsuite>
+ <directory suffix="Test.php">tests</directory>
+ <directory suffix=".phpt">tests</directory>
+ </testsuite>
+
+ <filter>
+ <whitelist processUncoveredFilesFromWhitelist="true">
+ <directory suffix=".php">src</directory>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Identity.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Identity.php
new file mode 100644
index 0000000..cb3a8fc
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Identity.php
@@ -0,0 +1,31 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Builder interface for unique identifiers.
+ *
+ * Defines the interface for recording unique identifiers. The identifiers
+ * can be used to define the invocation order of expectations. The expectation
+ * is recorded using id() and then defined in order using
+ * PHPUnit_Framework_MockObject_Builder_Match::after().
+ *
+ * @since Interface available since Release 1.0.0
+ */
+interface PHPUnit_Framework_MockObject_Builder_Identity
+{
+ /**
+ * Sets the identification of the expectation to $id.
+ *
+ * @note The identifier is unique per mock object.
+ *
+ * @param string $id Unique identification of expectation.
+ */
+ public function id($id);
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/InvocationMocker.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/InvocationMocker.php
new file mode 100644
index 0000000..7f507c8
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/InvocationMocker.php
@@ -0,0 +1,291 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Builder for mocked or stubbed invocations.
+ *
+ * Provides methods for building expectations without having to resort to
+ * instantiating the various matchers manually. These methods also form a
+ * more natural way of reading the expectation. This class should be together
+ * with the test case PHPUnit_Framework_MockObject_TestCase.
+ *
+ * @since Class available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_Builder_InvocationMocker implements PHPUnit_Framework_MockObject_Builder_MethodNameMatch
+{
+ /**
+ * @var PHPUnit_Framework_MockObject_Stub_MatcherCollection
+ */
+ protected $collection;
+
+ /**
+ * @var PHPUnit_Framework_MockObject_Matcher
+ */
+ protected $matcher;
+
+ /**
+ * @var string[]
+ */
+ private $configurableMethods = [];
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Stub_MatcherCollection $collection
+ * @param PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher
+ * @param array $configurableMethods
+ */
+ public function __construct(PHPUnit_Framework_MockObject_Stub_MatcherCollection $collection, PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher, array $configurableMethods)
+ {
+ $this->collection = $collection;
+ $this->matcher = new PHPUnit_Framework_MockObject_Matcher(
+ $invocationMatcher
+ );
+
+ $this->collection->addMatcher($this->matcher);
+
+ $this->configurableMethods = $configurableMethods;
+ }
+
+ /**
+ * @return PHPUnit_Framework_MockObject_Matcher
+ */
+ public function getMatcher()
+ {
+ return $this->matcher;
+ }
+
+ /**
+ * @param mixed $id
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
+ */
+ public function id($id)
+ {
+ $this->collection->registerId($id, $this);
+
+ return $this;
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Stub $stub
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
+ */
+ public function will(PHPUnit_Framework_MockObject_Stub $stub)
+ {
+ $this->matcher->stub = $stub;
+
+ return $this;
+ }
+
+ /**
+ * @param mixed $value
+ * @param mixed $nextValues, ...
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
+ */
+ public function willReturn($value, ...$nextValues)
+ {
+ $stub = count($nextValues) === 0 ?
+ new PHPUnit_Framework_MockObject_Stub_Return($value) :
+ new PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls(
+ array_merge([$value], $nextValues)
+ );
+
+ return $this->will($stub);
+ }
+
+ /**
+ * @param mixed $reference
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
+ */
+ public function willReturnReference(&$reference)
+ {
+ $stub = new PHPUnit_Framework_MockObject_Stub_ReturnReference($reference);
+
+ return $this->will($stub);
+ }
+
+ /**
+ * @param array $valueMap
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
+ */
+ public function willReturnMap(array $valueMap)
+ {
+ $stub = new PHPUnit_Framework_MockObject_Stub_ReturnValueMap(
+ $valueMap
+ );
+
+ return $this->will($stub);
+ }
+
+ /**
+ * @param mixed $argumentIndex
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
+ */
+ public function willReturnArgument($argumentIndex)
+ {
+ $stub = new PHPUnit_Framework_MockObject_Stub_ReturnArgument(
+ $argumentIndex
+ );
+
+ return $this->will($stub);
+ }
+
+ /**
+ * @param callable $callback
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
+ */
+ public function willReturnCallback($callback)
+ {
+ $stub = new PHPUnit_Framework_MockObject_Stub_ReturnCallback(
+ $callback
+ );
+
+ return $this->will($stub);
+ }
+
+ /**
+ * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
+ */
+ public function willReturnSelf()
+ {
+ $stub = new PHPUnit_Framework_MockObject_Stub_ReturnSelf;
+
+ return $this->will($stub);
+ }
+
+ /**
+ * @param mixed $values, ...
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
+ */
+ public function willReturnOnConsecutiveCalls(...$values)
+ {
+ $stub = new PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls($values);
+
+ return $this->will($stub);
+ }
+
+ /**
+ * @param Exception $exception
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
+ */
+ public function willThrowException(Exception $exception)
+ {
+ $stub = new PHPUnit_Framework_MockObject_Stub_Exception($exception);
+
+ return $this->will($stub);
+ }
+
+ /**
+ * @param mixed $id
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
+ */
+ public function after($id)
+ {
+ $this->matcher->afterMatchBuilderId = $id;
+
+ return $this;
+ }
+
+ /**
+ * Validate that a parameters matcher can be defined, throw exceptions otherwise.
+ *
+ * @throws PHPUnit_Framework_MockObject_RuntimeException
+ */
+ private function canDefineParameters()
+ {
+ if ($this->matcher->methodNameMatcher === null) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ 'Method name matcher is not defined, cannot define parameter ' .
+ 'matcher without one'
+ );
+ }
+
+ if ($this->matcher->parametersMatcher !== null) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ 'Parameter matcher is already defined, cannot redefine'
+ );
+ }
+ }
+
+ /**
+ * @param array ...$arguments
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
+ */
+ public function with(...$arguments)
+ {
+ $this->canDefineParameters();
+
+ $this->matcher->parametersMatcher = new PHPUnit_Framework_MockObject_Matcher_Parameters($arguments);
+
+ return $this;
+ }
+
+ /**
+ * @param array ...$arguments
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
+ */
+ public function withConsecutive(...$arguments)
+ {
+ $this->canDefineParameters();
+
+ $this->matcher->parametersMatcher = new PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters($arguments);
+
+ return $this;
+ }
+
+ /**
+ * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
+ */
+ public function withAnyParameters()
+ {
+ $this->canDefineParameters();
+
+ $this->matcher->parametersMatcher = new PHPUnit_Framework_MockObject_Matcher_AnyParameters;
+
+ return $this;
+ }
+
+ /**
+ * @param PHPUnit_Framework_Constraint|string $constraint
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
+ */
+ public function method($constraint)
+ {
+ if ($this->matcher->methodNameMatcher !== null) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ 'Method name matcher is already defined, cannot redefine'
+ );
+ }
+
+ if (is_string($constraint) && !in_array(strtolower($constraint), $this->configurableMethods)) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ sprintf(
+ 'Trying to configure method "%s" which cannot be configured because it does not exist, has not been specified, is final, or is static',
+ $constraint
+ )
+ );
+ }
+
+ $this->matcher->methodNameMatcher = new PHPUnit_Framework_MockObject_Matcher_MethodName($constraint);
+
+ return $this;
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Match.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Match.php
new file mode 100644
index 0000000..16880ac
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Match.php
@@ -0,0 +1,27 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Builder interface for invocation order matches.
+ *
+ * @since Interface available since Release 1.0.0
+ */
+interface PHPUnit_Framework_MockObject_Builder_Match extends PHPUnit_Framework_MockObject_Builder_Stub
+{
+ /**
+ * Defines the expectation which must occur before the current is valid.
+ *
+ * @param string $id The identification of the expectation that should
+ * occur before this one.
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_Stub
+ */
+ public function after($id);
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/MethodNameMatch.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/MethodNameMatch.php
new file mode 100644
index 0000000..b3a4590
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/MethodNameMatch.php
@@ -0,0 +1,27 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Builder interface for matcher of method names.
+ *
+ * @since Interface available since Release 1.0.0
+ */
+interface PHPUnit_Framework_MockObject_Builder_MethodNameMatch extends PHPUnit_Framework_MockObject_Builder_ParametersMatch
+{
+ /**
+ * Adds a new method name match and returns the parameter match object for
+ * further matching possibilities.
+ *
+ * @param PHPUnit_Framework_Constraint $name Constraint for matching method, if a string is passed it will use the PHPUnit_Framework_Constraint_IsEqual
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_ParametersMatch
+ */
+ public function method($name);
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Namespace.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Namespace.php
new file mode 100644
index 0000000..960f455
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Namespace.php
@@ -0,0 +1,38 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface for builders which can register builders with a given identification.
+ *
+ * This interface relates to PHPUnit_Framework_MockObject_Builder_Identity.
+ *
+ * @since Interface available since Release 1.0.0
+ */
+interface PHPUnit_Framework_MockObject_Builder_Namespace
+{
+ /**
+ * Looks up the match builder with identification $id and returns it.
+ *
+ * @param string $id The identification of the match builder
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_Match
+ */
+ public function lookupId($id);
+
+ /**
+ * Registers the match builder $builder with the identification $id. The
+ * builder can later be looked up using lookupId() to figure out if it
+ * has been invoked.
+ *
+ * @param string $id The identification of the match builder
+ * @param PHPUnit_Framework_MockObject_Builder_Match $builder The builder which is being registered
+ */
+ public function registerId($id, PHPUnit_Framework_MockObject_Builder_Match $builder);
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/ParametersMatch.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/ParametersMatch.php
new file mode 100644
index 0000000..2b2097a
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/ParametersMatch.php
@@ -0,0 +1,49 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Builder interface for parameter matchers.
+ *
+ * @since Interface available since Release 1.0.0
+ */
+interface PHPUnit_Framework_MockObject_Builder_ParametersMatch extends PHPUnit_Framework_MockObject_Builder_Match
+{
+ /**
+ * Sets the parameters to match for, each parameter to this funtion will
+ * be part of match. To perform specific matches or constraints create a
+ * new PHPUnit_Framework_Constraint and use it for the parameter.
+ * If the parameter value is not a constraint it will use the
+ * PHPUnit_Framework_Constraint_IsEqual for the value.
+ *
+ * Some examples:
+ * <code>
+ * // match first parameter with value 2
+ * $b->with(2);
+ * // match first parameter with value 'smock' and second identical to 42
+ * $b->with('smock', new PHPUnit_Framework_Constraint_IsEqual(42));
+ * </code>
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_ParametersMatch
+ */
+ public function with(...$arguments);
+
+ /**
+ * Sets a matcher which allows any kind of parameters.
+ *
+ * Some examples:
+ * <code>
+ * // match any number of parameters
+ * $b->withAnyParameters();
+ * </code>
+ *
+ * @return PHPUnit_Framework_MockObject_Matcher_AnyParameters
+ */
+ public function withAnyParameters();
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Stub.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Stub.php
new file mode 100644
index 0000000..103e8f2
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Stub.php
@@ -0,0 +1,27 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Builder interface for stubs which are actions replacing an invocation.
+ *
+ * @since Interface available since Release 1.0.0
+ */
+interface PHPUnit_Framework_MockObject_Builder_Stub extends PHPUnit_Framework_MockObject_Builder_Identity
+{
+ /**
+ * Stubs the matching method with the stub object $stub. Any invocations of
+ * the matched method will now be handled by the stub instead.
+ *
+ * @param PHPUnit_Framework_MockObject_Stub $stub
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_Identity
+ */
+ public function will(PHPUnit_Framework_MockObject_Stub $stub);
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/BadMethodCallException.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/BadMethodCallException.php
new file mode 100644
index 0000000..736784b
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/BadMethodCallException.php
@@ -0,0 +1,16 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @since Class available since Release 2.0.6
+ */
+class PHPUnit_Framework_MockObject_BadMethodCallException extends BadMethodCallException implements PHPUnit_Framework_MockObject_Exception
+{
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/Exception.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/Exception.php
new file mode 100644
index 0000000..bc8c81d
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/Exception.php
@@ -0,0 +1,18 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface for exceptions used by PHPUnit_MockObject.
+ *
+ * @since Interface available since Release 2.0.6
+ */
+interface PHPUnit_Framework_MockObject_Exception
+{
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/RuntimeException.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/RuntimeException.php
new file mode 100644
index 0000000..1e9b6f1
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/RuntimeException.php
@@ -0,0 +1,16 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @since Class available since Release 2.0.6
+ */
+class PHPUnit_Framework_MockObject_RuntimeException extends RuntimeException implements PHPUnit_Framework_MockObject_Exception
+{
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php
new file mode 100644
index 0000000..bfb899d
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php
@@ -0,0 +1,1324 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Doctrine\Instantiator\Instantiator;
+use Doctrine\Instantiator\Exception\InvalidArgumentException as InstantiatorInvalidArgumentException;
+use Doctrine\Instantiator\Exception\UnexpectedValueException as InstantiatorUnexpectedValueException;
+
+/**
+ * Mock Object Code Generator
+ *
+ * @since Class available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_Generator
+{
+ /**
+ * @var array
+ */
+ private static $cache = [];
+
+ /**
+ * @var Text_Template[]
+ */
+ private static $templates = [];
+
+ /**
+ * @var array
+ */
+ private $legacyBlacklistedMethodNames = [
+ '__CLASS__' => true,
+ '__DIR__' => true,
+ '__FILE__' => true,
+ '__FUNCTION__' => true,
+ '__LINE__' => true,
+ '__METHOD__' => true,
+ '__NAMESPACE__' => true,
+ '__TRAIT__' => true,
+ '__clone' => true,
+ '__halt_compiler' => true,
+ 'abstract' => true,
+ 'and' => true,
+ 'array' => true,
+ 'as' => true,
+ 'break' => true,
+ 'callable' => true,
+ 'case' => true,
+ 'catch' => true,
+ 'class' => true,
+ 'clone' => true,
+ 'const' => true,
+ 'continue' => true,
+ 'declare' => true,
+ 'default' => true,
+ 'die' => true,
+ 'do' => true,
+ 'echo' => true,
+ 'else' => true,
+ 'elseif' => true,
+ 'empty' => true,
+ 'enddeclare' => true,
+ 'endfor' => true,
+ 'endforeach' => true,
+ 'endif' => true,
+ 'endswitch' => true,
+ 'endwhile' => true,
+ 'eval' => true,
+ 'exit' => true,
+ 'expects' => true,
+ 'extends' => true,
+ 'final' => true,
+ 'for' => true,
+ 'foreach' => true,
+ 'function' => true,
+ 'global' => true,
+ 'goto' => true,
+ 'if' => true,
+ 'implements' => true,
+ 'include' => true,
+ 'include_once' => true,
+ 'instanceof' => true,
+ 'insteadof' => true,
+ 'interface' => true,
+ 'isset' => true,
+ 'list' => true,
+ 'namespace' => true,
+ 'new' => true,
+ 'or' => true,
+ 'print' => true,
+ 'private' => true,
+ 'protected' => true,
+ 'public' => true,
+ 'require' => true,
+ 'require_once' => true,
+ 'return' => true,
+ 'static' => true,
+ 'switch' => true,
+ 'throw' => true,
+ 'trait' => true,
+ 'try' => true,
+ 'unset' => true,
+ 'use' => true,
+ 'var' => true,
+ 'while' => true,
+ 'xor' => true
+ ];
+
+ /**
+ * @var array
+ */
+ private $blacklistedMethodNames = [
+ '__CLASS__' => true,
+ '__DIR__' => true,
+ '__FILE__' => true,
+ '__FUNCTION__' => true,
+ '__LINE__' => true,
+ '__METHOD__' => true,
+ '__NAMESPACE__' => true,
+ '__TRAIT__' => true,
+ '__clone' => true,
+ '__halt_compiler' => true,
+ ];
+
+ /**
+ * Returns a mock object for the specified class.
+ *
+ * @param array|string $type
+ * @param array $methods
+ * @param array $arguments
+ * @param string $mockClassName
+ * @param bool $callOriginalConstructor
+ * @param bool $callOriginalClone
+ * @param bool $callAutoload
+ * @param bool $cloneArguments
+ * @param bool $callOriginalMethods
+ * @param object $proxyTarget
+ * @param bool $allowMockingUnknownTypes
+ *
+ * @return PHPUnit_Framework_MockObject_MockObject
+ *
+ * @throws InvalidArgumentException
+ * @throws PHPUnit_Framework_Exception
+ * @throws PHPUnit_Framework_MockObject_RuntimeException
+ *
+ * @since Method available since Release 1.0.0
+ */
+ public function getMock($type, $methods = [], array $arguments = [], $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $cloneArguments = true, $callOriginalMethods = false, $proxyTarget = null, $allowMockingUnknownTypes = true)
+ {
+ if (!is_array($type) && !is_string($type)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'array or string');
+ }
+
+ if (!is_string($mockClassName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(4, 'string');
+ }
+
+ if (!is_array($methods) && !is_null($methods)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'array', $methods);
+ }
+
+ if ($type === 'Traversable' || $type === '\\Traversable') {
+ $type = 'Iterator';
+ }
+
+ if (is_array($type)) {
+ $type = array_unique(
+ array_map(
+ function ($type) {
+ if ($type === 'Traversable' ||
+ $type === '\\Traversable' ||
+ $type === '\\Iterator') {
+ return 'Iterator';
+ }
+
+ return $type;
+ },
+ $type
+ )
+ );
+ }
+
+ if (!$allowMockingUnknownTypes) {
+ if (is_array($type)) {
+ foreach ($type as $_type) {
+ if (!class_exists($_type, $callAutoload) &&
+ !interface_exists($_type, $callAutoload)) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ sprintf(
+ 'Cannot stub or mock class or interface "%s" which does not exist',
+ $_type
+ )
+ );
+ }
+ }
+ } else {
+ if (!class_exists($type, $callAutoload) &&
+ !interface_exists($type, $callAutoload)
+ ) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ sprintf(
+ 'Cannot stub or mock class or interface "%s" which does not exist',
+ $type
+ )
+ );
+ }
+ }
+ }
+
+ if (null !== $methods) {
+ foreach ($methods as $method) {
+ if (!preg_match('~[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*~', $method)) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ sprintf(
+ 'Cannot stub or mock method with invalid name "%s"',
+ $method
+ )
+ );
+ }
+ }
+
+ if ($methods != array_unique($methods)) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ sprintf(
+ 'Cannot stub or mock using a method list that contains duplicates: "%s" (duplicate: "%s")',
+ implode(', ', $methods),
+ implode(', ', array_unique(array_diff_assoc($methods, array_unique($methods))))
+ )
+ );
+ }
+ }
+
+ if ($mockClassName != '' && class_exists($mockClassName, false)) {
+ $reflect = new ReflectionClass($mockClassName);
+
+ if (!$reflect->implementsInterface('PHPUnit_Framework_MockObject_MockObject')) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ sprintf(
+ 'Class "%s" already exists.',
+ $mockClassName
+ )
+ );
+ }
+ }
+
+ if ($callOriginalConstructor === false && $callOriginalMethods === true) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ 'Proxying to original methods requires invoking the original constructor'
+ );
+ }
+
+ $mock = $this->generate(
+ $type,
+ $methods,
+ $mockClassName,
+ $callOriginalClone,
+ $callAutoload,
+ $cloneArguments,
+ $callOriginalMethods
+ );
+
+ return $this->getObject(
+ $mock['code'],
+ $mock['mockClassName'],
+ $type,
+ $callOriginalConstructor,
+ $callAutoload,
+ $arguments,
+ $callOriginalMethods,
+ $proxyTarget
+ );
+ }
+
+ /**
+ * @param string $code
+ * @param string $className
+ * @param array|string $type
+ * @param bool $callOriginalConstructor
+ * @param bool $callAutoload
+ * @param array $arguments
+ * @param bool $callOriginalMethods
+ * @param object $proxyTarget
+ *
+ * @return object
+ */
+ private function getObject($code, $className, $type = '', $callOriginalConstructor = false, $callAutoload = false, array $arguments = [], $callOriginalMethods = false, $proxyTarget = null)
+ {
+ $this->evalClass($code, $className);
+
+ if ($callOriginalConstructor &&
+ is_string($type) &&
+ !interface_exists($type, $callAutoload)) {
+ if (count($arguments) == 0) {
+ $object = new $className;
+ } else {
+ $class = new ReflectionClass($className);
+ $object = $class->newInstanceArgs($arguments);
+ }
+ } else {
+ try {
+ $instantiator = new Instantiator;
+ $object = $instantiator->instantiate($className);
+ } catch (InstantiatorUnexpectedValueException $exception) {
+ if ($exception->getPrevious()) {
+ $exception = $exception->getPrevious();
+ }
+
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ $exception->getMessage()
+ );
+ } catch (InstantiatorInvalidArgumentException $exception) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ $exception->getMessage()
+ );
+ }
+ }
+
+ if ($callOriginalMethods) {
+ if (!is_object($proxyTarget)) {
+ if (count($arguments) == 0) {
+ $proxyTarget = new $type;
+ } else {
+ $class = new ReflectionClass($type);
+ $proxyTarget = $class->newInstanceArgs($arguments);
+ }
+ }
+
+ $object->__phpunit_setOriginalObject($proxyTarget);
+ }
+
+ return $object;
+ }
+
+ /**
+ * @param string $code
+ * @param string $className
+ */
+ private function evalClass($code, $className)
+ {
+ if (!class_exists($className, false)) {
+ eval($code);
+ }
+ }
+
+ /**
+ * Returns a mock object for the specified abstract class with all abstract
+ * methods of the class mocked. Concrete methods to mock can be specified with
+ * the last parameter
+ *
+ * @param string $originalClassName
+ * @param array $arguments
+ * @param string $mockClassName
+ * @param bool $callOriginalConstructor
+ * @param bool $callOriginalClone
+ * @param bool $callAutoload
+ * @param array $mockedMethods
+ * @param bool $cloneArguments
+ *
+ * @return PHPUnit_Framework_MockObject_MockObject
+ *
+ * @throws PHPUnit_Framework_MockObject_RuntimeException
+ * @throws PHPUnit_Framework_Exception
+ *
+ * @since Method available since Release 1.0.0
+ */
+ public function getMockForAbstractClass($originalClassName, array $arguments = [], $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = [], $cloneArguments = true)
+ {
+ if (!is_string($originalClassName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!is_string($mockClassName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'string');
+ }
+
+ if (class_exists($originalClassName, $callAutoload) ||
+ interface_exists($originalClassName, $callAutoload)) {
+ $reflector = new ReflectionClass($originalClassName);
+ $methods = $mockedMethods;
+
+ foreach ($reflector->getMethods() as $method) {
+ if ($method->isAbstract() && !in_array($method->getName(), $methods)) {
+ $methods[] = $method->getName();
+ }
+ }
+
+ if (empty($methods)) {
+ $methods = null;
+ }
+
+ return $this->getMock(
+ $originalClassName,
+ $methods,
+ $arguments,
+ $mockClassName,
+ $callOriginalConstructor,
+ $callOriginalClone,
+ $callAutoload,
+ $cloneArguments
+ );
+ } else {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ sprintf('Class "%s" does not exist.', $originalClassName)
+ );
+ }
+ }
+
+ /**
+ * Returns a mock object for the specified trait with all abstract methods
+ * of the trait mocked. Concrete methods to mock can be specified with the
+ * `$mockedMethods` parameter.
+ *
+ * @param string $traitName
+ * @param array $arguments
+ * @param string $mockClassName
+ * @param bool $callOriginalConstructor
+ * @param bool $callOriginalClone
+ * @param bool $callAutoload
+ * @param array $mockedMethods
+ * @param bool $cloneArguments
+ *
+ * @return PHPUnit_Framework_MockObject_MockObject
+ *
+ * @throws PHPUnit_Framework_MockObject_RuntimeException
+ * @throws PHPUnit_Framework_Exception
+ *
+ * @since Method available since Release 1.2.3
+ */
+ public function getMockForTrait($traitName, array $arguments = [], $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = [], $cloneArguments = true)
+ {
+ if (!is_string($traitName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!is_string($mockClassName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'string');
+ }
+
+ if (!trait_exists($traitName, $callAutoload)) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ sprintf(
+ 'Trait "%s" does not exist.',
+ $traitName
+ )
+ );
+ }
+
+ $className = $this->generateClassName(
+ $traitName,
+ '',
+ 'Trait_'
+ );
+
+ $templateDir = __DIR__ . DIRECTORY_SEPARATOR . 'Generator' . DIRECTORY_SEPARATOR;
+ $classTemplate = $this->getTemplate($templateDir . 'trait_class.tpl');
+
+ $classTemplate->setVar(
+ [
+ 'prologue' => 'abstract ',
+ 'class_name' => $className['className'],
+ 'trait_name' => $traitName
+ ]
+ );
+
+ $this->evalClass(
+ $classTemplate->render(),
+ $className['className']
+ );
+
+ return $this->getMockForAbstractClass($className['className'], $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments);
+ }
+
+ /**
+ * Returns an object for the specified trait.
+ *
+ * @param string $traitName
+ * @param array $arguments
+ * @param string $traitClassName
+ * @param bool $callOriginalConstructor
+ * @param bool $callOriginalClone
+ * @param bool $callAutoload
+ *
+ * @return object
+ *
+ * @throws PHPUnit_Framework_MockObject_RuntimeException
+ * @throws PHPUnit_Framework_Exception
+ *
+ * @since Method available since Release 1.1.0
+ */
+ public function getObjectForTrait($traitName, array $arguments = [], $traitClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true)
+ {
+ if (!is_string($traitName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!is_string($traitClassName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'string');
+ }
+
+ if (!trait_exists($traitName, $callAutoload)) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ sprintf(
+ 'Trait "%s" does not exist.',
+ $traitName
+ )
+ );
+ }
+
+ $className = $this->generateClassName(
+ $traitName,
+ $traitClassName,
+ 'Trait_'
+ );
+
+ $templateDir = __DIR__ . DIRECTORY_SEPARATOR . 'Generator' . DIRECTORY_SEPARATOR;
+ $classTemplate = $this->getTemplate($templateDir . 'trait_class.tpl');
+
+ $classTemplate->setVar(
+ [
+ 'prologue' => '',
+ 'class_name' => $className['className'],
+ 'trait_name' => $traitName
+ ]
+ );
+
+ return $this->getObject(
+ $classTemplate->render(),
+ $className['className']
+ );
+ }
+
+ /**
+ * @param array|string $type
+ * @param array $methods
+ * @param string $mockClassName
+ * @param bool $callOriginalClone
+ * @param bool $callAutoload
+ * @param bool $cloneArguments
+ * @param bool $callOriginalMethods
+ *
+ * @return array
+ */
+ public function generate($type, array $methods = null, $mockClassName = '', $callOriginalClone = true, $callAutoload = true, $cloneArguments = true, $callOriginalMethods = false)
+ {
+ if (is_array($type)) {
+ sort($type);
+ }
+
+ if ($mockClassName == '') {
+ $key = md5(
+ is_array($type) ? implode('_', $type) : $type .
+ serialize($methods) .
+ serialize($callOriginalClone) .
+ serialize($cloneArguments) .
+ serialize($callOriginalMethods)
+ );
+
+ if (isset(self::$cache[$key])) {
+ return self::$cache[$key];
+ }
+ }
+
+ $mock = $this->generateMock(
+ $type,
+ $methods,
+ $mockClassName,
+ $callOriginalClone,
+ $callAutoload,
+ $cloneArguments,
+ $callOriginalMethods
+ );
+
+ if (isset($key)) {
+ self::$cache[$key] = $mock;
+ }
+
+ return $mock;
+ }
+
+ /**
+ * @param string $wsdlFile
+ * @param string $className
+ * @param array $methods
+ * @param array $options
+ *
+ * @return string
+ *
+ * @throws PHPUnit_Framework_MockObject_RuntimeException
+ */
+ public function generateClassFromWsdl($wsdlFile, $className, array $methods = [], array $options = [])
+ {
+ if (!extension_loaded('soap')) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ 'The SOAP extension is required to generate a mock object from WSDL.'
+ );
+ }
+
+ $options = array_merge($options, ['cache_wsdl' => WSDL_CACHE_NONE]);
+ $client = new SoapClient($wsdlFile, $options);
+ $_methods = array_unique($client->__getFunctions());
+ unset($client);
+
+ sort($_methods);
+
+ $templateDir = __DIR__ . DIRECTORY_SEPARATOR . 'Generator' . DIRECTORY_SEPARATOR;
+ $methodTemplate = $this->getTemplate($templateDir . 'wsdl_method.tpl');
+ $methodsBuffer = '';
+
+ foreach ($_methods as $method) {
+ $nameStart = strpos($method, ' ') + 1;
+ $nameEnd = strpos($method, '(');
+ $name = substr($method, $nameStart, $nameEnd - $nameStart);
+
+ if (empty($methods) || in_array($name, $methods)) {
+ $args = explode(
+ ',',
+ substr(
+ $method,
+ $nameEnd + 1,
+ strpos($method, ')') - $nameEnd - 1
+ )
+ );
+ $numArgs = count($args);
+
+ for ($i = 0; $i < $numArgs; $i++) {
+ $args[$i] = substr($args[$i], strpos($args[$i], '$'));
+ }
+
+ $methodTemplate->setVar(
+ [
+ 'method_name' => $name,
+ 'arguments' => implode(', ', $args)
+ ]
+ );
+
+ $methodsBuffer .= $methodTemplate->render();
+ }
+ }
+
+ $optionsBuffer = 'array(';
+
+ foreach ($options as $key => $value) {
+ $optionsBuffer .= $key . ' => ' . $value;
+ }
+
+ $optionsBuffer .= ')';
+
+ $classTemplate = $this->getTemplate($templateDir . 'wsdl_class.tpl');
+ $namespace = '';
+
+ if (strpos($className, '\\') !== false) {
+ $parts = explode('\\', $className);
+ $className = array_pop($parts);
+ $namespace = 'namespace ' . implode('\\', $parts) . ';' . "\n\n";
+ }
+
+ $classTemplate->setVar(
+ [
+ 'namespace' => $namespace,
+ 'class_name' => $className,
+ 'wsdl' => $wsdlFile,
+ 'options' => $optionsBuffer,
+ 'methods' => $methodsBuffer
+ ]
+ );
+
+ return $classTemplate->render();
+ }
+
+ /**
+ * @param array|string $type
+ * @param array|null $methods
+ * @param string $mockClassName
+ * @param bool $callOriginalClone
+ * @param bool $callAutoload
+ * @param bool $cloneArguments
+ * @param bool $callOriginalMethods
+ *
+ * @return array
+ *
+ * @throws PHPUnit_Framework_MockObject_RuntimeException
+ */
+ private function generateMock($type, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods)
+ {
+ $methodReflections = [];
+ $templateDir = __DIR__ . DIRECTORY_SEPARATOR . 'Generator' . DIRECTORY_SEPARATOR;
+ $classTemplate = $this->getTemplate($templateDir . 'mocked_class.tpl');
+
+ $additionalInterfaces = [];
+ $cloneTemplate = '';
+ $isClass = false;
+ $isInterface = false;
+ $isMultipleInterfaces = false;
+
+ if (is_array($type)) {
+ foreach ($type as $_type) {
+ if (!interface_exists($_type, $callAutoload)) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ sprintf(
+ 'Interface "%s" does not exist.',
+ $_type
+ )
+ );
+ }
+
+ $isMultipleInterfaces = true;
+
+ $additionalInterfaces[] = $_type;
+ $typeClass = new ReflectionClass($this->generateClassName(
+ $_type,
+ $mockClassName,
+ 'Mock_'
+ )['fullClassName']
+ );
+
+ foreach ($this->getClassMethods($_type) as $method) {
+ if (in_array($method, $methods)) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ sprintf(
+ 'Duplicate method "%s" not allowed.',
+ $method
+ )
+ );
+ }
+
+ $methodReflections[$method] = $typeClass->getMethod($method);
+ $methods[] = $method;
+ }
+ }
+ }
+
+ $mockClassName = $this->generateClassName(
+ $type,
+ $mockClassName,
+ 'Mock_'
+ );
+
+ if (class_exists($mockClassName['fullClassName'], $callAutoload)) {
+ $isClass = true;
+ } elseif (interface_exists($mockClassName['fullClassName'], $callAutoload)) {
+ $isInterface = true;
+ }
+
+ if (!$isClass && !$isInterface) {
+ $prologue = 'class ' . $mockClassName['originalClassName'] . "\n{\n}\n\n";
+
+ if (!empty($mockClassName['namespaceName'])) {
+ $prologue = 'namespace ' . $mockClassName['namespaceName'] .
+ " {\n\n" . $prologue . "}\n\n" .
+ "namespace {\n\n";
+
+ $epilogue = "\n\n}";
+ }
+
+ $cloneTemplate = $this->getTemplate($templateDir . 'mocked_clone.tpl');
+ } else {
+ $class = new ReflectionClass($mockClassName['fullClassName']);
+
+ if ($class->isFinal()) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ sprintf(
+ 'Class "%s" is declared "final" and cannot be mocked.',
+ $mockClassName['fullClassName']
+ )
+ );
+ }
+
+ if ($class->hasMethod('__clone')) {
+ $cloneMethod = $class->getMethod('__clone');
+
+ if (!$cloneMethod->isFinal()) {
+ if ($callOriginalClone && !$isInterface) {
+ $cloneTemplate = $this->getTemplate($templateDir . 'unmocked_clone.tpl');
+ } else {
+ $cloneTemplate = $this->getTemplate($templateDir . 'mocked_clone.tpl');
+ }
+ }
+ } else {
+ $cloneTemplate = $this->getTemplate($templateDir . 'mocked_clone.tpl');
+ }
+ }
+
+ if (is_object($cloneTemplate)) {
+ $cloneTemplate = $cloneTemplate->render();
+ }
+
+ if (is_array($methods) && empty($methods) &&
+ ($isClass || $isInterface)) {
+ $methods = $this->getClassMethods($mockClassName['fullClassName']);
+ }
+
+ if (!is_array($methods)) {
+ $methods = [];
+ }
+
+ $mockedMethods = '';
+ $configurable = [];
+
+ foreach ($methods as $methodName) {
+ if ($methodName != '__construct' && $methodName != '__clone') {
+ $configurable[] = strtolower($methodName);
+ }
+ }
+
+ if (isset($class)) {
+ // https://github.com/sebastianbergmann/phpunit-mock-objects/issues/103
+ if ($isInterface && $class->implementsInterface('Traversable') &&
+ !$class->implementsInterface('Iterator') &&
+ !$class->implementsInterface('IteratorAggregate')) {
+ $additionalInterfaces[] = 'Iterator';
+ $methods = array_merge($methods, $this->getClassMethods('Iterator'));
+ }
+
+ foreach ($methods as $methodName) {
+ try {
+ $method = $class->getMethod($methodName);
+
+ if ($this->canMockMethod($method)) {
+ $mockedMethods .= $this->generateMockedMethodDefinitionFromExisting(
+ $templateDir,
+ $method,
+ $cloneArguments,
+ $callOriginalMethods
+ );
+ }
+ } catch (ReflectionException $e) {
+ $mockedMethods .= $this->generateMockedMethodDefinition(
+ $templateDir,
+ $mockClassName['fullClassName'],
+ $methodName,
+ $cloneArguments
+ );
+ }
+ }
+ } elseif ($isMultipleInterfaces) {
+ foreach ($methods as $methodName) {
+ if ($this->canMockMethod($methodReflections[$methodName])) {
+ $mockedMethods .= $this->generateMockedMethodDefinitionFromExisting(
+ $templateDir,
+ $methodReflections[$methodName],
+ $cloneArguments,
+ $callOriginalMethods
+ );
+ }
+ }
+ } else {
+ foreach ($methods as $methodName) {
+ $mockedMethods .= $this->generateMockedMethodDefinition(
+ $templateDir,
+ $mockClassName['fullClassName'],
+ $methodName,
+ $cloneArguments
+ );
+ }
+ }
+
+ $method = '';
+
+ if (!in_array('method', $methods) && (!isset($class) || !$class->hasMethod('method'))) {
+ $methodTemplate = $this->getTemplate($templateDir . 'mocked_class_method.tpl');
+
+ $method = $methodTemplate->render();
+ }
+
+ $classTemplate->setVar(
+ [
+ 'prologue' => isset($prologue) ? $prologue : '',
+ 'epilogue' => isset($epilogue) ? $epilogue : '',
+ 'class_declaration' => $this->generateMockClassDeclaration(
+ $mockClassName,
+ $isInterface,
+ $additionalInterfaces
+ ),
+ 'clone' => $cloneTemplate,
+ 'mock_class_name' => $mockClassName['className'],
+ 'mocked_methods' => $mockedMethods,
+ 'method' => $method,
+ 'configurable' => '[' . implode(', ', array_map(function ($m) { return '\'' . $m . '\'';}, $configurable)) . ']'
+ ]
+ );
+
+ return [
+ 'code' => $classTemplate->render(),
+ 'mockClassName' => $mockClassName['className']
+ ];
+ }
+
+ /**
+ * @param array|string $type
+ * @param string $className
+ * @param string $prefix
+ *
+ * @return array
+ */
+ private function generateClassName($type, $className, $prefix)
+ {
+ if (is_array($type)) {
+ $type = implode('_', $type);
+ }
+
+ if ($type[0] == '\\') {
+ $type = substr($type, 1);
+ }
+
+ $classNameParts = explode('\\', $type);
+
+ if (count($classNameParts) > 1) {
+ $type = array_pop($classNameParts);
+ $namespaceName = implode('\\', $classNameParts);
+ $fullClassName = $namespaceName . '\\' . $type;
+ } else {
+ $namespaceName = '';
+ $fullClassName = $type;
+ }
+
+ if ($className == '') {
+ do {
+ $className = $prefix . $type . '_' .
+ substr(md5(mt_rand()), 0, 8);
+ } while (class_exists($className, false));
+ }
+
+ return [
+ 'className' => $className,
+ 'originalClassName' => $type,
+ 'fullClassName' => $fullClassName,
+ 'namespaceName' => $namespaceName
+ ];
+ }
+
+ /**
+ * @param array $mockClassName
+ * @param bool $isInterface
+ * @param array $additionalInterfaces
+ *
+ * @return array
+ */
+ private function generateMockClassDeclaration(array $mockClassName, $isInterface, array $additionalInterfaces = [])
+ {
+ $buffer = 'class ';
+
+ $additionalInterfaces[] = 'PHPUnit_Framework_MockObject_MockObject';
+ $interfaces = implode(', ', $additionalInterfaces);
+
+ if ($isInterface) {
+ $buffer .= sprintf(
+ '%s implements %s',
+ $mockClassName['className'],
+ $interfaces
+ );
+
+ if (!in_array($mockClassName['originalClassName'], $additionalInterfaces)) {
+ $buffer .= ', ';
+
+ if (!empty($mockClassName['namespaceName'])) {
+ $buffer .= $mockClassName['namespaceName'] . '\\';
+ }
+
+ $buffer .= $mockClassName['originalClassName'];
+ }
+ } else {
+ $buffer .= sprintf(
+ '%s extends %s%s implements %s',
+ $mockClassName['className'],
+ !empty($mockClassName['namespaceName']) ? $mockClassName['namespaceName'] . '\\' : '',
+ $mockClassName['originalClassName'],
+ $interfaces
+ );
+ }
+
+ return $buffer;
+ }
+
+ /**
+ * @param string $templateDir
+ * @param ReflectionMethod $method
+ * @param bool $cloneArguments
+ * @param bool $callOriginalMethods
+ *
+ * @return string
+ */
+ private function generateMockedMethodDefinitionFromExisting($templateDir, ReflectionMethod $method, $cloneArguments, $callOriginalMethods)
+ {
+ if ($method->isPrivate()) {
+ $modifier = 'private';
+ } elseif ($method->isProtected()) {
+ $modifier = 'protected';
+ } else {
+ $modifier = 'public';
+ }
+
+ if ($method->isStatic()) {
+ $modifier .= ' static';
+ }
+
+ if ($method->returnsReference()) {
+ $reference = '&';
+ } else {
+ $reference = '';
+ }
+
+ if ($this->hasReturnType($method)) {
+ $returnType = (string) $method->getReturnType();
+ } else {
+ $returnType = '';
+ }
+
+ if (preg_match('#\*[ \t]*+@deprecated[ \t]*+(.*?)\r?+\n[ \t]*+\*(?:[ \t]*+@|/$)#s', $method->getDocComment(), $deprecation)) {
+ $deprecation = trim(preg_replace('#[ \t]*\r?\n[ \t]*+\*[ \t]*+#', ' ', $deprecation[1]));
+ } else {
+ $deprecation = false;
+ }
+
+ return $this->generateMockedMethodDefinition(
+ $templateDir,
+ $method->getDeclaringClass()->getName(),
+ $method->getName(),
+ $cloneArguments,
+ $modifier,
+ $this->getMethodParameters($method),
+ $this->getMethodParameters($method, true),
+ $returnType,
+ $reference,
+ $callOriginalMethods,
+ $method->isStatic(),
+ $deprecation,
+ $this->allowsReturnNull($method)
+ );
+ }
+
+ /**
+ * @param string $templateDir
+ * @param string $className
+ * @param string $methodName
+ * @param bool $cloneArguments
+ * @param string $modifier
+ * @param string $arguments_decl
+ * @param string $arguments_call
+ * @param string $return_type
+ * @param string $reference
+ * @param bool $callOriginalMethods
+ * @param bool $static
+ * @param string|false $deprecation
+ * @param bool $allowsReturnNull
+ *
+ * @return string
+ */
+ private function generateMockedMethodDefinition($templateDir, $className, $methodName, $cloneArguments = true, $modifier = 'public', $arguments_decl = '', $arguments_call = '', $return_type = '', $reference = '', $callOriginalMethods = false, $static = false, $deprecation = false, $allowsReturnNull = false)
+ {
+ if ($static) {
+ $templateFile = 'mocked_static_method.tpl';
+ } else {
+ if ($return_type === 'void') {
+ $templateFile = sprintf(
+ '%s_method_void.tpl',
+ $callOriginalMethods ? 'proxied' : 'mocked'
+ );
+ } else {
+ $templateFile = sprintf(
+ '%s_method.tpl',
+ $callOriginalMethods ? 'proxied' : 'mocked'
+ );
+ }
+ }
+
+ // Mocked interfaces returning 'self' must explicitly declare the
+ // interface name as the return type. See
+ // https://bugs.php.net/bug.php?id=70722
+ if ($return_type === 'self') {
+ $return_type = $className;
+ }
+
+ if (false !== $deprecation) {
+ $deprecation = "The $className::$methodName method is deprecated ($deprecation).";
+ $deprecationTemplate = $this->getTemplate($templateDir . 'deprecation.tpl');
+
+ $deprecationTemplate->setVar(
+ [
+ 'deprecation' => var_export($deprecation, true),
+ ]
+ );
+
+ $deprecation = $deprecationTemplate->render();
+ }
+
+ $template = $this->getTemplate($templateDir . $templateFile);
+
+ $template->setVar(
+ [
+ 'arguments_decl' => $arguments_decl,
+ 'arguments_call' => $arguments_call,
+ 'return_delim' => $return_type ? ': ' : '',
+ 'return_type' => $allowsReturnNull ? '?' . $return_type : $return_type,
+ 'arguments_count' => !empty($arguments_call) ? count(explode(',', $arguments_call)) : 0,
+ 'class_name' => $className,
+ 'method_name' => $methodName,
+ 'modifier' => $modifier,
+ 'reference' => $reference,
+ 'clone_arguments' => $cloneArguments ? 'true' : 'false',
+ 'deprecation' => $deprecation
+ ]
+ );
+
+ return $template->render();
+ }
+
+ /**
+ * @param ReflectionMethod $method
+ *
+ * @return bool
+ */
+ private function canMockMethod(ReflectionMethod $method)
+ {
+ if ($method->isConstructor() ||
+ $method->isFinal() ||
+ $method->isPrivate() ||
+ $this->isMethodNameBlacklisted($method->getName())) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns whether i method name is blacklisted
+ *
+ * Since PHP 7 the only names that are still reserved for method names are the ones that start with an underscore
+ *
+ * @param string $name
+ *
+ * @return bool
+ */
+ private function isMethodNameBlacklisted($name)
+ {
+ if (PHP_MAJOR_VERSION < 7 && isset($this->legacyBlacklistedMethodNames[$name])) {
+ return true;
+ }
+
+ if (PHP_MAJOR_VERSION >= 7 && isset($this->blacklistedMethodNames[$name])) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the parameters of a function or method.
+ *
+ * @param ReflectionMethod $method
+ * @param bool $forCall
+ *
+ * @return string
+ *
+ * @throws PHPUnit_Framework_MockObject_RuntimeException
+ *
+ * @since Method available since Release 2.0.0
+ */
+ private function getMethodParameters(ReflectionMethod $method, $forCall = false)
+ {
+ $parameters = [];
+
+ foreach ($method->getParameters() as $i => $parameter) {
+ $name = '$' . $parameter->getName();
+
+ /* Note: PHP extensions may use empty names for reference arguments
+ * or "..." for methods taking a variable number of arguments.
+ */
+ if ($name === '$' || $name === '$...') {
+ $name = '$arg' . $i;
+ }
+
+ if ($this->isVariadic($parameter)) {
+ if ($forCall) {
+ continue;
+ } else {
+ $name = '...' . $name;
+ }
+ }
+
+ $nullable = '';
+ $default = '';
+ $reference = '';
+ $typeDeclaration = '';
+
+ if (!$forCall) {
+ if ($this->hasType($parameter) && (string) $parameter->getType() !== 'self') {
+ if (version_compare(PHP_VERSION, '7.1', '>=') && $parameter->allowsNull() && !$parameter->isVariadic()) {
+ $nullable = '?';
+ }
+
+ $typeDeclaration = (string) $parameter->getType() . ' ';
+ } elseif ($parameter->isArray()) {
+ $typeDeclaration = 'array ';
+ } elseif ($parameter->isCallable()) {
+ $typeDeclaration = 'callable ';
+ } else {
+ try {
+ $class = $parameter->getClass();
+ } catch (ReflectionException $e) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ sprintf(
+ 'Cannot mock %s::%s() because a class or ' .
+ 'interface used in the signature is not loaded',
+ $method->getDeclaringClass()->getName(),
+ $method->getName()
+ ),
+ 0,
+ $e
+ );
+ }
+
+ if ($class !== null) {
+ $typeDeclaration = $class->getName() . ' ';
+ }
+ }
+
+ if (!$this->isVariadic($parameter)) {
+ if ($parameter->isDefaultValueAvailable()) {
+ $value = $parameter->getDefaultValue();
+ $default = ' = ' . var_export($value, true);
+ } elseif ($parameter->isOptional()) {
+ $default = ' = null';
+ }
+ }
+ }
+
+ if ($parameter->isPassedByReference()) {
+ $reference = '&';
+ }
+
+ $parameters[] = $nullable . $typeDeclaration . $reference . $name . $default;
+ }
+
+ return implode(', ', $parameters);
+ }
+
+ /**
+ * @param ReflectionParameter $parameter
+ *
+ * @return bool
+ *
+ * @since Method available since Release 2.2.1
+ */
+ private function isVariadic(ReflectionParameter $parameter)
+ {
+ return method_exists(ReflectionParameter::class, 'isVariadic') && $parameter->isVariadic();
+ }
+
+ /**
+ * @param ReflectionParameter $parameter
+ *
+ * @return bool
+ *
+ * @since Method available since Release 2.3.4
+ */
+ private function hasType(ReflectionParameter $parameter)
+ {
+ return method_exists(ReflectionParameter::class, 'hasType') && $parameter->hasType();
+ }
+
+ /**
+ * @param ReflectionMethod $method
+ *
+ * @return bool
+ */
+ private function hasReturnType(ReflectionMethod $method)
+ {
+ return method_exists(ReflectionMethod::class, 'hasReturnType') && $method->hasReturnType();
+ }
+
+ /**
+ * @param ReflectionMethod $method
+ *
+ * @return bool
+ */
+ private function allowsReturnNull(ReflectionMethod $method)
+ {
+ return method_exists(ReflectionMethod::class, 'getReturnType')
+ && method_exists(ReflectionType::class, 'allowsNull')
+ && $method->hasReturnType()
+ && $method->getReturnType()->allowsNull();
+ }
+
+ /**
+ * @param string $className
+ *
+ * @return array
+ *
+ * @since Method available since Release 2.3.2
+ */
+ public function getClassMethods($className)
+ {
+ $class = new ReflectionClass($className);
+ $methods = [];
+
+ foreach ($class->getMethods() as $method) {
+ if ($method->isPublic() || $method->isAbstract()) {
+ $methods[] = $method->getName();
+ }
+ }
+
+ return $methods;
+ }
+
+ /**
+ * @param string $filename
+ *
+ * @return Text_Template
+ *
+ * @since Method available since Release 3.2.4
+ */
+ private function getTemplate($filename)
+ {
+ if (!isset(self::$templates[$filename])) {
+ self::$templates[$filename] = new Text_Template($filename);
+ }
+
+ return self::$templates[$filename];
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/deprecation.tpl.dist b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/deprecation.tpl.dist
new file mode 100644
index 0000000..5bf06f5
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/deprecation.tpl.dist
@@ -0,0 +1,2 @@
+
+ @trigger_error({deprecation}, E_USER_DEPRECATED);
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_class.tpl.dist b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_class.tpl.dist
new file mode 100644
index 0000000..30ec490
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_class.tpl.dist
@@ -0,0 +1,40 @@
+{prologue}{class_declaration}
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = {configurable};
+
+{clone}{mocked_methods}
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+{method}
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}{epilogue}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_class_method.tpl.dist b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_class_method.tpl.dist
new file mode 100644
index 0000000..9e29c0d
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_class_method.tpl.dist
@@ -0,0 +1,7 @@
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_clone.tpl.dist b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_clone.tpl.dist
new file mode 100644
index 0000000..bd846de
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_clone.tpl.dist
@@ -0,0 +1,4 @@
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_method.tpl.dist b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_method.tpl.dist
new file mode 100644
index 0000000..c1e7a0d
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_method.tpl.dist
@@ -0,0 +1,22 @@
+
+ {modifier} function {reference}{method_name}({arguments_decl}){return_delim}{return_type}
+ {{deprecation}
+ $arguments = array({arguments_call});
+ $count = func_num_args();
+
+ if ($count > {arguments_count}) {
+ $_arguments = func_get_args();
+
+ for ($i = {arguments_count}; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ '{class_name}', '{method_name}', $arguments, '{return_type}', $this, {clone_arguments}
+ )
+ );
+
+ return $result;
+ }
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_method_void.tpl.dist b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_method_void.tpl.dist
new file mode 100644
index 0000000..03197aa
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_method_void.tpl.dist
@@ -0,0 +1,20 @@
+
+ {modifier} function {reference}{method_name}({arguments_decl}){return_delim}{return_type}
+ {{deprecation}
+ $arguments = array({arguments_call});
+ $count = func_num_args();
+
+ if ($count > {arguments_count}) {
+ $_arguments = func_get_args();
+
+ for ($i = {arguments_count}; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ '{class_name}', '{method_name}', $arguments, '{return_type}', $this, {clone_arguments}
+ )
+ );
+ }
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_static_method.tpl.dist b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_static_method.tpl.dist
new file mode 100644
index 0000000..45fa9bb
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/mocked_static_method.tpl.dist
@@ -0,0 +1,5 @@
+
+ {modifier} function {reference}{method_name}({arguments_decl}){return_delim}{return_type}
+ {
+ throw new PHPUnit_Framework_MockObject_BadMethodCallException('Static method "{method_name}" cannot be invoked on mock object');
+ }
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/proxied_method.tpl.dist b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/proxied_method.tpl.dist
new file mode 100644
index 0000000..4b9cce8
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/proxied_method.tpl.dist
@@ -0,0 +1,22 @@
+
+ {modifier} function {reference}{method_name}({arguments_decl}){return_delim}{return_type}
+ {
+ $arguments = array({arguments_call});
+ $count = func_num_args();
+
+ if ($count > {arguments_count}) {
+ $_arguments = func_get_args();
+
+ for ($i = {arguments_count}; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ '{class_name}', '{method_name}', $arguments, '{return_type}', $this, {clone_arguments}
+ )
+ );
+
+ return call_user_func_array(array($this->__phpunit_originalObject, "{method_name}"), $arguments);
+ }
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/proxied_method_void.tpl.dist b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/proxied_method_void.tpl.dist
new file mode 100644
index 0000000..e350436
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/proxied_method_void.tpl.dist
@@ -0,0 +1,22 @@
+
+ {modifier} function {reference}{method_name}({arguments_decl}){return_delim}{return_type}
+ {
+ $arguments = array({arguments_call});
+ $count = func_num_args();
+
+ if ($count > {arguments_count}) {
+ $_arguments = func_get_args();
+
+ for ($i = {arguments_count}; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ '{class_name}', '{method_name}', $arguments, '{return_type}', $this, {clone_arguments}
+ )
+ );
+
+ call_user_func_array(array($this->__phpunit_originalObject, "{method_name}"), $arguments);
+ }
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/trait_class.tpl.dist b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/trait_class.tpl.dist
new file mode 100644
index 0000000..4143b0f
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/trait_class.tpl.dist
@@ -0,0 +1,4 @@
+{prologue}class {class_name}
+{
+ use {trait_name};
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/unmocked_clone.tpl.dist b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/unmocked_clone.tpl.dist
new file mode 100644
index 0000000..fa0e70a
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/unmocked_clone.tpl.dist
@@ -0,0 +1,5 @@
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ parent::__clone();
+ }
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/wsdl_class.tpl.dist b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/wsdl_class.tpl.dist
new file mode 100644
index 0000000..cc69fd3
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/wsdl_class.tpl.dist
@@ -0,0 +1,7 @@
+{namespace}class {class_name} extends \SoapClient
+{
+ public function __construct($wsdl, array $options)
+ {
+ parent::__construct('{wsdl}', $options);
+ }
+{methods}}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/wsdl_method.tpl.dist b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/wsdl_method.tpl.dist
new file mode 100644
index 0000000..bb16e76
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator/wsdl_method.tpl.dist
@@ -0,0 +1,4 @@
+
+ public function {method_name}({arguments})
+ {
+ }
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation.php
new file mode 100644
index 0000000..34da11a
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation.php
@@ -0,0 +1,22 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface for invocations.
+ *
+ * @since Interface available since Release 1.0.0
+ */
+interface PHPUnit_Framework_MockObject_Invocation
+{
+ /**
+ * @return mixed Mocked return value.
+ */
+ public function generateReturnValue();
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Object.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Object.php
new file mode 100644
index 0000000..3361966
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Object.php
@@ -0,0 +1,37 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a non-static invocation.
+ *
+ * @since Class available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_Invocation_Object extends PHPUnit_Framework_MockObject_Invocation_Static
+{
+ /**
+ * @var object
+ */
+ public $object;
+
+ /**
+ * @param string $className
+ * @param string $methodName
+ * @param array $parameters
+ * @param string $returnType
+ * @param object $object
+ * @param bool $cloneObjects
+ */
+ public function __construct($className, $methodName, array $parameters, $returnType, $object, $cloneObjects = false)
+ {
+ parent::__construct($className, $methodName, $parameters, $returnType, $cloneObjects);
+
+ $this->object = $object;
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Static.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Static.php
new file mode 100644
index 0000000..d580002
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Static.php
@@ -0,0 +1,207 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use SebastianBergmann\Exporter\Exporter;
+
+/**
+ * Represents a static invocation.
+ *
+ * @since Class available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_Invocation_Static implements PHPUnit_Framework_MockObject_Invocation, PHPUnit_Framework_SelfDescribing
+{
+ /**
+ * @var array
+ */
+ protected static $uncloneableExtensions = [
+ 'mysqli' => true,
+ 'SQLite' => true,
+ 'sqlite3' => true,
+ 'tidy' => true,
+ 'xmlwriter' => true,
+ 'xsl' => true
+ ];
+
+ /**
+ * @var array
+ */
+ protected static $uncloneableClasses = [
+ 'Closure',
+ 'COMPersistHelper',
+ 'IteratorIterator',
+ 'RecursiveIteratorIterator',
+ 'SplFileObject',
+ 'PDORow',
+ 'ZipArchive'
+ ];
+
+ /**
+ * @var string
+ */
+ public $className;
+
+ /**
+ * @var string
+ */
+ public $methodName;
+
+ /**
+ * @var array
+ */
+ public $parameters;
+
+ /**
+ * @var string
+ */
+ public $returnType;
+
+ /**
+ * @var bool
+ */
+ public $returnTypeNullable = false;
+
+ /**
+ * @param string $className
+ * @param string $methodName
+ * @param array $parameters
+ * @param string $returnType
+ * @param bool $cloneObjects
+ */
+ public function __construct($className, $methodName, array $parameters, $returnType, $cloneObjects = false)
+ {
+ $this->className = $className;
+ $this->methodName = $methodName;
+ $this->parameters = $parameters;
+
+ if (strpos($returnType, '?') === 0) {
+ $returnType = substr($returnType, 1);
+ $this->returnTypeNullable = true;
+ }
+
+ $this->returnType = $returnType;
+
+ if (!$cloneObjects) {
+ return;
+ }
+
+ foreach ($this->parameters as $key => $value) {
+ if (is_object($value)) {
+ $this->parameters[$key] = $this->cloneObject($value);
+ }
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function toString()
+ {
+ $exporter = new Exporter;
+
+ return sprintf(
+ '%s::%s(%s)%s',
+ $this->className,
+ $this->methodName,
+ implode(
+ ', ',
+ array_map(
+ [$exporter, 'shortenedExport'],
+ $this->parameters
+ )
+ ),
+ $this->returnType ? sprintf(': %s', $this->returnType) : ''
+ );
+ }
+
+ /**
+ * @return mixed Mocked return value.
+ */
+ public function generateReturnValue()
+ {
+ switch ($this->returnType) {
+ case '': return;
+ case 'string': return $this->returnTypeNullable ? null : '';
+ case 'float': return $this->returnTypeNullable ? null : 0.0;
+ case 'int': return $this->returnTypeNullable ? null : 0;
+ case 'bool': return $this->returnTypeNullable ? null : false;
+ case 'array': return $this->returnTypeNullable ? null : [];
+ case 'void': return;
+
+ case 'callable':
+ case 'Closure':
+ return function () {};
+
+ case 'Traversable':
+ case 'Generator':
+ $generator = function () { yield; };
+
+ return $generator();
+
+ default:
+ if ($this->returnTypeNullable) {
+ return null;
+ }
+
+ $generator = new PHPUnit_Framework_MockObject_Generator;
+
+ return $generator->getMock($this->returnType, [], [], '', false);
+ }
+ }
+
+ /**
+ * @param object $original
+ *
+ * @return object
+ */
+ protected function cloneObject($original)
+ {
+ $cloneable = null;
+ $object = new ReflectionObject($original);
+
+ // Check the blacklist before asking PHP reflection to work around
+ // https://bugs.php.net/bug.php?id=53967
+ if ($object->isInternal() &&
+ isset(self::$uncloneableExtensions[$object->getExtensionName()])) {
+ $cloneable = false;
+ }
+
+ if ($cloneable === null) {
+ foreach (self::$uncloneableClasses as $class) {
+ if ($original instanceof $class) {
+ $cloneable = false;
+ break;
+ }
+ }
+ }
+
+ if ($cloneable === null && method_exists($object, 'isCloneable')) {
+ $cloneable = $object->isCloneable();
+ }
+
+ if ($cloneable === null && $object->hasMethod('__clone')) {
+ $method = $object->getMethod('__clone');
+ $cloneable = $method->isPublic();
+ }
+
+ if ($cloneable === null) {
+ $cloneable = true;
+ }
+
+ if ($cloneable) {
+ try {
+ return clone $original;
+ } catch (Exception $e) {
+ return $original;
+ }
+ } else {
+ return $original;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/InvocationMocker.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/InvocationMocker.php
new file mode 100644
index 0000000..88e5330
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/InvocationMocker.php
@@ -0,0 +1,178 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Mocker for invocations which are sent from
+ * PHPUnit_Framework_MockObject_MockObject objects.
+ *
+ * Keeps track of all expectations and stubs as well as registering
+ * identifications for builders.
+ *
+ * @since Class available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_InvocationMocker implements PHPUnit_Framework_MockObject_Stub_MatcherCollection, PHPUnit_Framework_MockObject_Invokable, PHPUnit_Framework_MockObject_Builder_Namespace
+{
+ /**
+ * @var PHPUnit_Framework_MockObject_Matcher_Invocation[]
+ */
+ protected $matchers = [];
+
+ /**
+ * @var PHPUnit_Framework_MockObject_Builder_Match[]
+ */
+ protected $builderMap = [];
+
+ /**
+ * @var string[]
+ */
+ private $configurableMethods = [];
+
+ /**
+ * @param array $configurableMethods
+ */
+ public function __construct(array $configurableMethods)
+ {
+ $this->configurableMethods = $configurableMethods;
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher
+ */
+ public function addMatcher(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ $this->matchers[] = $matcher;
+ }
+
+ /**
+ * @since Method available since Release 1.1.0
+ */
+ public function hasMatchers()
+ {
+ foreach ($this->matchers as $matcher) {
+ if ($matcher->hasMatchers()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @param mixed $id
+ *
+ * @return bool|null
+ */
+ public function lookupId($id)
+ {
+ if (isset($this->builderMap[$id])) {
+ return $this->builderMap[$id];
+ }
+
+ return;
+ }
+
+ /**
+ * @param mixed $id
+ * @param PHPUnit_Framework_MockObject_Builder_Match $builder
+ *
+ * @throws PHPUnit_Framework_MockObject_RuntimeException
+ */
+ public function registerId($id, PHPUnit_Framework_MockObject_Builder_Match $builder)
+ {
+ if (isset($this->builderMap[$id])) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ 'Match builder with id <' . $id . '> is already registered.'
+ );
+ }
+
+ $this->builderMap[$id] = $builder;
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
+ */
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return new PHPUnit_Framework_MockObject_Builder_InvocationMocker(
+ $this,
+ $matcher,
+ $this->configurableMethods
+ );
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation
+ *
+ * @return mixed
+ *
+ * @throws Exception
+ */
+ public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ $exception = null;
+ $hasReturnValue = false;
+ $returnValue = null;
+
+ foreach ($this->matchers as $match) {
+ try {
+ if ($match->matches($invocation)) {
+ $value = $match->invoked($invocation);
+
+ if (!$hasReturnValue) {
+ $returnValue = $value;
+ $hasReturnValue = true;
+ }
+ }
+ } catch (Exception $e) {
+ $exception = $e;
+ }
+ }
+
+ if ($exception !== null) {
+ throw $exception;
+ }
+
+ if ($hasReturnValue) {
+ return $returnValue;
+ } elseif (strtolower($invocation->methodName) == '__tostring') {
+ return '';
+ }
+
+ return $invocation->generateReturnValue();
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation
+ *
+ * @return bool
+ */
+ public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ foreach ($this->matchers as $matcher) {
+ if (!$matcher->matches($invocation)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * @return bool
+ */
+ public function verify()
+ {
+ foreach ($this->matchers as $matcher) {
+ $matcher->verify();
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invokable.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invokable.php
new file mode 100644
index 0000000..6f5ffda
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invokable.php
@@ -0,0 +1,39 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface for classes which can be invoked.
+ *
+ * The invocation will be taken from a mock object and passed to an object
+ * of this class.
+ *
+ * @since Interface available since Release 1.0.0
+ */
+interface PHPUnit_Framework_MockObject_Invokable extends PHPUnit_Framework_MockObject_Verifiable
+{
+ /**
+ * Invokes the invocation object $invocation so that it can be checked for
+ * expectations or matched against stubs.
+ *
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation The invocation object passed from mock object
+ *
+ * @return object
+ */
+ public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation);
+
+ /**
+ * Checks if the invocation matches.
+ *
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation The invocation object passed from mock object
+ *
+ * @return bool
+ */
+ public function matches(PHPUnit_Framework_MockObject_Invocation $invocation);
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher.php
new file mode 100644
index 0000000..ff57bf9
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher.php
@@ -0,0 +1,274 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Main matcher which defines a full expectation using method, parameter and
+ * invocation matchers.
+ * This matcher encapsulates all the other matchers and allows the builder to
+ * set the specific matchers when the appropriate methods are called (once(),
+ * where() etc.).
+ *
+ * All properties are public so that they can easily be accessed by the builder.
+ *
+ * @since Class available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_Matcher implements PHPUnit_Framework_MockObject_Matcher_Invocation
+{
+ /**
+ * @var PHPUnit_Framework_MockObject_Matcher_Invocation
+ */
+ public $invocationMatcher;
+
+ /**
+ * @var mixed
+ */
+ public $afterMatchBuilderId = null;
+
+ /**
+ * @var bool
+ */
+ public $afterMatchBuilderIsInvoked = false;
+
+ /**
+ * @var PHPUnit_Framework_MockObject_Matcher_MethodName
+ */
+ public $methodNameMatcher = null;
+
+ /**
+ * @var PHPUnit_Framework_MockObject_Matcher_Parameters
+ */
+ public $parametersMatcher = null;
+
+ /**
+ * @var PHPUnit_Framework_MockObject_Stub
+ */
+ public $stub = null;
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher
+ */
+ public function __construct(PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher)
+ {
+ $this->invocationMatcher = $invocationMatcher;
+ }
+
+ /**
+ * @return string
+ */
+ public function toString()
+ {
+ $list = [];
+
+ if ($this->invocationMatcher !== null) {
+ $list[] = $this->invocationMatcher->toString();
+ }
+
+ if ($this->methodNameMatcher !== null) {
+ $list[] = 'where ' . $this->methodNameMatcher->toString();
+ }
+
+ if ($this->parametersMatcher !== null) {
+ $list[] = 'and ' . $this->parametersMatcher->toString();
+ }
+
+ if ($this->afterMatchBuilderId !== null) {
+ $list[] = 'after ' . $this->afterMatchBuilderId;
+ }
+
+ if ($this->stub !== null) {
+ $list[] = 'will ' . $this->stub->toString();
+ }
+
+ return implode(' ', $list);
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation
+ *
+ * @return mixed
+ */
+ public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ if ($this->invocationMatcher === null) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ 'No invocation matcher is set'
+ );
+ }
+
+ if ($this->methodNameMatcher === null) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException('No method matcher is set');
+ }
+
+ if ($this->afterMatchBuilderId !== null) {
+ $builder = $invocation->object
+ ->__phpunit_getInvocationMocker()
+ ->lookupId($this->afterMatchBuilderId);
+
+ if (!$builder) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ sprintf(
+ 'No builder found for match builder identification <%s>',
+ $this->afterMatchBuilderId
+ )
+ );
+ }
+
+ $matcher = $builder->getMatcher();
+
+ if ($matcher && $matcher->invocationMatcher->hasBeenInvoked()) {
+ $this->afterMatchBuilderIsInvoked = true;
+ }
+ }
+
+ $this->invocationMatcher->invoked($invocation);
+
+ try {
+ if ($this->parametersMatcher !== null &&
+ !$this->parametersMatcher->matches($invocation)) {
+ $this->parametersMatcher->verify();
+ }
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ throw new PHPUnit_Framework_ExpectationFailedException(
+ sprintf(
+ "Expectation failed for %s when %s\n%s",
+ $this->methodNameMatcher->toString(),
+ $this->invocationMatcher->toString(),
+ $e->getMessage()
+ ),
+ $e->getComparisonFailure()
+ );
+ }
+
+ if ($this->stub) {
+ return $this->stub->invoke($invocation);
+ }
+
+ return $invocation->generateReturnValue();
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation
+ *
+ * @return bool
+ */
+ public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ if ($this->afterMatchBuilderId !== null) {
+ $builder = $invocation->object
+ ->__phpunit_getInvocationMocker()
+ ->lookupId($this->afterMatchBuilderId);
+
+ if (!$builder) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ sprintf(
+ 'No builder found for match builder identification <%s>',
+ $this->afterMatchBuilderId
+ )
+ );
+ }
+
+ $matcher = $builder->getMatcher();
+
+ if (!$matcher) {
+ return false;
+ }
+
+ if (!$matcher->invocationMatcher->hasBeenInvoked()) {
+ return false;
+ }
+ }
+
+ if ($this->invocationMatcher === null) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ 'No invocation matcher is set'
+ );
+ }
+
+ if ($this->methodNameMatcher === null) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException('No method matcher is set');
+ }
+
+ if (!$this->invocationMatcher->matches($invocation)) {
+ return false;
+ }
+
+ try {
+ if (!$this->methodNameMatcher->matches($invocation)) {
+ return false;
+ }
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ throw new PHPUnit_Framework_ExpectationFailedException(
+ sprintf(
+ "Expectation failed for %s when %s\n%s",
+ $this->methodNameMatcher->toString(),
+ $this->invocationMatcher->toString(),
+ $e->getMessage()
+ ),
+ $e->getComparisonFailure()
+ );
+ }
+
+ return true;
+ }
+
+ /**
+ * @throws PHPUnit_Framework_MockObject_RuntimeException
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function verify()
+ {
+ if ($this->invocationMatcher === null) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ 'No invocation matcher is set'
+ );
+ }
+
+ if ($this->methodNameMatcher === null) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException('No method matcher is set');
+ }
+
+ try {
+ $this->invocationMatcher->verify();
+
+ if ($this->parametersMatcher === null) {
+ $this->parametersMatcher = new PHPUnit_Framework_MockObject_Matcher_AnyParameters;
+ }
+
+ $invocationIsAny = $this->invocationMatcher instanceof PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $invocationIsNever = $this->invocationMatcher instanceof PHPUnit_Framework_MockObject_Matcher_InvokedCount && $this->invocationMatcher->isNever();
+
+ if (!$invocationIsAny && !$invocationIsNever) {
+ $this->parametersMatcher->verify();
+ }
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ throw new PHPUnit_Framework_ExpectationFailedException(
+ sprintf(
+ "Expectation failed for %s when %s.\n%s",
+ $this->methodNameMatcher->toString(),
+ $this->invocationMatcher->toString(),
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ )
+ );
+ }
+ }
+
+ /**
+ * @since Method available since Release 1.2.4
+ */
+ public function hasMatchers()
+ {
+ if ($this->invocationMatcher !== null &&
+ !$this->invocationMatcher instanceof PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyInvokedCount.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyInvokedCount.php
new file mode 100644
index 0000000..480f1fd
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyInvokedCount.php
@@ -0,0 +1,32 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Invocation matcher which checks if a method has been invoked zero or more
+ * times. This matcher will always match.
+ *
+ * @since Class available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder
+{
+ /**
+ * @return string
+ */
+ public function toString()
+ {
+ return 'invoked zero or more times';
+ }
+
+ /**
+ */
+ public function verify()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyParameters.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyParameters.php
new file mode 100644
index 0000000..02de976
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyParameters.php
@@ -0,0 +1,35 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Invocation matcher which allows any parameters to a method.
+ *
+ * @since Class available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_Matcher_AnyParameters extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation
+{
+ /**
+ * @return string
+ */
+ public function toString()
+ {
+ return 'with any parameters';
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation
+ *
+ * @return bool
+ */
+ public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ return true;
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/ConsecutiveParameters.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/ConsecutiveParameters.php
new file mode 100644
index 0000000..553498e
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/ConsecutiveParameters.php
@@ -0,0 +1,126 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Invocation matcher which looks for sets of specific parameters in the invocations.
+ *
+ * Checks the parameters of the incoming invocations, the parameter list is
+ * checked against the defined constraints in $parameters. If the constraint
+ * is met it will return true in matches().
+ *
+ * It takes a list of match groups and and increases a call index after each invocation.
+ * So the first invocation uses the first group of constraints, the second the next and so on.
+ */
+class PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation
+{
+ /**
+ * @var array
+ */
+ private $parameterGroups = [];
+
+ /**
+ * @var array
+ */
+ private $invocations = [];
+
+ /**
+ * @param array $parameterGroups
+ */
+ public function __construct(array $parameterGroups)
+ {
+ foreach ($parameterGroups as $index => $parameters) {
+ foreach ($parameters as $parameter) {
+ if (!$parameter instanceof PHPUnit_Framework_Constraint) {
+ $parameter = new PHPUnit_Framework_Constraint_IsEqual($parameter);
+ }
+
+ $this->parameterGroups[$index][] = $parameter;
+ }
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function toString()
+ {
+ $text = 'with consecutive parameters';
+
+ return $text;
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation
+ *
+ * @return bool
+ */
+ public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ $this->invocations[] = $invocation;
+ $callIndex = count($this->invocations) - 1;
+
+ $this->verifyInvocation($invocation, $callIndex);
+
+ return false;
+ }
+
+ public function verify()
+ {
+ foreach ($this->invocations as $callIndex => $invocation) {
+ $this->verifyInvocation($invocation, $callIndex);
+ }
+ }
+
+ /**
+ * Verify a single invocation
+ *
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation
+ * @param int $callIndex
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ private function verifyInvocation(PHPUnit_Framework_MockObject_Invocation $invocation, $callIndex)
+ {
+ if (isset($this->parameterGroups[$callIndex])) {
+ $parameters = $this->parameterGroups[$callIndex];
+ } else {
+ // no parameter assertion for this call index
+ return;
+ }
+
+ if ($invocation === null) {
+ throw new PHPUnit_Framework_ExpectationFailedException(
+ 'Mocked method does not exist.'
+ );
+ }
+
+ if (count($invocation->parameters) < count($parameters)) {
+ throw new PHPUnit_Framework_ExpectationFailedException(
+ sprintf(
+ 'Parameter count for invocation %s is too low.',
+ $invocation->toString()
+ )
+ );
+ }
+
+ foreach ($parameters as $i => $parameter) {
+ $parameter->evaluate(
+ $invocation->parameters[$i],
+ sprintf(
+ 'Parameter %s for invocation #%d %s does not match expected ' .
+ 'value.',
+ $i,
+ $callIndex,
+ $invocation->toString()
+ )
+ );
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Invocation.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Invocation.php
new file mode 100644
index 0000000..befaa9c
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Invocation.php
@@ -0,0 +1,46 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface for classes which matches an invocation based on its
+ * method name, argument, order or call count.
+ *
+ * @since Interface available since Release 1.0.0
+ */
+interface PHPUnit_Framework_MockObject_Matcher_Invocation extends PHPUnit_Framework_SelfDescribing, PHPUnit_Framework_MockObject_Verifiable
+{
+ /**
+ * Registers the invocation $invocation in the object as being invoked.
+ * This will only occur after matches() returns true which means the
+ * current invocation is the correct one.
+ *
+ * The matcher can store information from the invocation which can later
+ * be checked in verify(), or it can check the values directly and throw
+ * and exception if an expectation is not met.
+ *
+ * If the matcher is a stub it will also have a return value.
+ *
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation Object containing information on a mocked or stubbed method which was invoked
+ *
+ * @return mixed
+ */
+ public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation);
+
+ /**
+ * Checks if the invocation $invocation matches the current rules. If it does
+ * the matcher will get the invoked() method called which should check if an
+ * expectation is met.
+ *
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation Object containing information on a mocked or stubbed method which was invoked
+ *
+ * @return bool
+ */
+ public function matches(PHPUnit_Framework_MockObject_Invocation $invocation);
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtIndex.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtIndex.php
new file mode 100644
index 0000000..9301543
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtIndex.php
@@ -0,0 +1,87 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Invocation matcher which checks if a method was invoked at a certain index.
+ *
+ * If the expected index number does not match the current invocation index it
+ * will not match which means it skips all method and parameter matching. Only
+ * once the index is reached will the method and parameter start matching and
+ * verifying.
+ *
+ * If the index is never reached it will throw an exception in index.
+ *
+ * @since Class available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex implements PHPUnit_Framework_MockObject_Matcher_Invocation
+{
+ /**
+ * @var int
+ */
+ protected $sequenceIndex;
+
+ /**
+ * @var int
+ */
+ protected $currentIndex = -1;
+
+ /**
+ * @param int $sequenceIndex
+ */
+ public function __construct($sequenceIndex)
+ {
+ $this->sequenceIndex = $sequenceIndex;
+ }
+
+ /**
+ * @return string
+ */
+ public function toString()
+ {
+ return 'invoked at sequence index ' . $this->sequenceIndex;
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation
+ *
+ * @return bool
+ */
+ public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ $this->currentIndex++;
+
+ return $this->currentIndex == $this->sequenceIndex;
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation
+ */
+ public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ }
+
+ /**
+ * Verifies that the current expectation is valid. If everything is OK the
+ * code should just return, if not it must throw an exception.
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function verify()
+ {
+ if ($this->currentIndex < $this->sequenceIndex) {
+ throw new PHPUnit_Framework_ExpectationFailedException(
+ sprintf(
+ 'The expected invocation at index %s was never reached.',
+ $this->sequenceIndex
+ )
+ );
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php
new file mode 100644
index 0000000..dc5e804
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php
@@ -0,0 +1,57 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Invocation matcher which checks if a method has been invoked at least
+ * N times.
+ *
+ * @since Class available since Release 2.2.0
+ */
+class PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder
+{
+ /**
+ * @var int
+ */
+ private $requiredInvocations;
+
+ /**
+ * @param int $requiredInvocations
+ */
+ public function __construct($requiredInvocations)
+ {
+ $this->requiredInvocations = $requiredInvocations;
+ }
+
+ /**
+ * @return string
+ */
+ public function toString()
+ {
+ return 'invoked at least ' . $this->requiredInvocations . ' times';
+ }
+
+ /**
+ * Verifies that the current expectation is valid. If everything is OK the
+ * code should just return, if not it must throw an exception.
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function verify()
+ {
+ $count = $this->getInvocationCount();
+
+ if ($count < $this->requiredInvocations) {
+ throw new PHPUnit_Framework_ExpectationFailedException(
+ 'Expected invocation at least ' . $this->requiredInvocations .
+ ' times but it occurred ' . $count . ' time(s).'
+ );
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php
new file mode 100644
index 0000000..006e908
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php
@@ -0,0 +1,45 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Invocation matcher which checks if a method has been invoked at least one
+ * time.
+ *
+ * If the number of invocations is 0 it will throw an exception in verify.
+ *
+ * @since Class available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder
+{
+ /**
+ * @return string
+ */
+ public function toString()
+ {
+ return 'invoked at least once';
+ }
+
+ /**
+ * Verifies that the current expectation is valid. If everything is OK the
+ * code should just return, if not it must throw an exception.
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function verify()
+ {
+ $count = $this->getInvocationCount();
+
+ if ($count < 1) {
+ throw new PHPUnit_Framework_ExpectationFailedException(
+ 'Expected invocation at least once but it never occurred.'
+ );
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtMostCount.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtMostCount.php
new file mode 100644
index 0000000..592af93
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtMostCount.php
@@ -0,0 +1,57 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Invocation matcher which checks if a method has been invoked at least
+ * N times.
+ *
+ * @since Class available since Release 2.2.0
+ */
+class PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder
+{
+ /**
+ * @var int
+ */
+ private $allowedInvocations;
+
+ /**
+ * @param int $allowedInvocations
+ */
+ public function __construct($allowedInvocations)
+ {
+ $this->allowedInvocations = $allowedInvocations;
+ }
+
+ /**
+ * @return string
+ */
+ public function toString()
+ {
+ return 'invoked at most ' . $this->allowedInvocations . ' times';
+ }
+
+ /**
+ * Verifies that the current expectation is valid. If everything is OK the
+ * code should just return, if not it must throw an exception.
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function verify()
+ {
+ $count = $this->getInvocationCount();
+
+ if ($count > $this->allowedInvocations) {
+ throw new PHPUnit_Framework_ExpectationFailedException(
+ 'Expected invocation at most ' . $this->allowedInvocations .
+ ' times but it occurred ' . $count . ' time(s).'
+ );
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedCount.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedCount.php
new file mode 100644
index 0000000..fc5b15b
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedCount.php
@@ -0,0 +1,110 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Invocation matcher which checks if a method has been invoked a certain amount
+ * of times.
+ * If the number of invocations exceeds the value it will immediately throw an
+ * exception,
+ * If the number is less it will later be checked in verify() and also throw an
+ * exception.
+ *
+ * @since Class available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_Matcher_InvokedCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder
+{
+ /**
+ * @var int
+ */
+ protected $expectedCount;
+
+ /**
+ * @param int $expectedCount
+ */
+ public function __construct($expectedCount)
+ {
+ $this->expectedCount = $expectedCount;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isNever()
+ {
+ return $this->expectedCount == 0;
+ }
+
+ /**
+ * @return string
+ */
+ public function toString()
+ {
+ return 'invoked ' . $this->expectedCount . ' time(s)';
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ parent::invoked($invocation);
+
+ $count = $this->getInvocationCount();
+
+ if ($count > $this->expectedCount) {
+ $message = $invocation->toString() . ' ';
+
+ switch ($this->expectedCount) {
+ case 0: {
+ $message .= 'was not expected to be called.';
+ }
+ break;
+
+ case 1: {
+ $message .= 'was not expected to be called more than once.';
+ }
+ break;
+
+ default: {
+ $message .= sprintf(
+ 'was not expected to be called more than %d times.',
+ $this->expectedCount
+ );
+ }
+ }
+
+ throw new PHPUnit_Framework_ExpectationFailedException($message);
+ }
+ }
+
+ /**
+ * Verifies that the current expectation is valid. If everything is OK the
+ * code should just return, if not it must throw an exception.
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function verify()
+ {
+ $count = $this->getInvocationCount();
+
+ if ($count !== $this->expectedCount) {
+ throw new PHPUnit_Framework_ExpectationFailedException(
+ sprintf(
+ 'Method was expected to be called %d times, ' .
+ 'actually called %d times.',
+ $this->expectedCount,
+ $count
+ )
+ );
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedRecorder.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedRecorder.php
new file mode 100644
index 0000000..7762d7e
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedRecorder.php
@@ -0,0 +1,68 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Records invocations and provides convenience methods for checking them later
+ * on.
+ * This abstract class can be implemented by matchers which needs to check the
+ * number of times an invocation has occurred.
+ *
+ * @since Class available since Release 1.0.0
+ * @abstract
+ */
+abstract class PHPUnit_Framework_MockObject_Matcher_InvokedRecorder implements PHPUnit_Framework_MockObject_Matcher_Invocation
+{
+ /**
+ * @var PHPUnit_Framework_MockObject_Invocation[]
+ */
+ protected $invocations = [];
+
+ /**
+ * @return int
+ */
+ public function getInvocationCount()
+ {
+ return count($this->invocations);
+ }
+
+ /**
+ * @return PHPUnit_Framework_MockObject_Invocation[]
+ */
+ public function getInvocations()
+ {
+ return $this->invocations;
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasBeenInvoked()
+ {
+ return count($this->invocations) > 0;
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation
+ */
+ public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ $this->invocations[] = $invocation;
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation
+ *
+ * @return bool
+ */
+ public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ return true;
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/MethodName.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/MethodName.php
new file mode 100644
index 0000000..ff44c84
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/MethodName.php
@@ -0,0 +1,68 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Invocation matcher which looks for a specific method name in the invocations.
+ *
+ * Checks the method name all incoming invocations, the name is checked against
+ * the defined constraint $constraint. If the constraint is met it will return
+ * true in matches().
+ *
+ * @since Class available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_Matcher_MethodName extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation
+{
+ /**
+ * @var PHPUnit_Framework_Constraint
+ */
+ protected $constraint;
+
+ /**
+ * @param PHPUnit_Framework_Constraint|string
+ *
+ * @throws PHPUnit_Framework_Constraint
+ */
+ public function __construct($constraint)
+ {
+ if (!$constraint instanceof PHPUnit_Framework_Constraint) {
+ if (!is_string($constraint)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_IsEqual(
+ $constraint,
+ 0,
+ 10,
+ false,
+ true
+ );
+ }
+
+ $this->constraint = $constraint;
+ }
+
+ /**
+ * @return string
+ */
+ public function toString()
+ {
+ return 'method name ' . $this->constraint->toString();
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation
+ *
+ * @return bool
+ */
+ public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ return $this->constraint->evaluate($invocation->methodName, '', true);
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Parameters.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Parameters.php
new file mode 100644
index 0000000..9cd50fc
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Parameters.php
@@ -0,0 +1,158 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Invocation matcher which looks for specific parameters in the invocations.
+ *
+ * Checks the parameters of all incoming invocations, the parameter list is
+ * checked against the defined constraints in $parameters. If the constraint
+ * is met it will return true in matches().
+ *
+ * @since Class available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_Matcher_Parameters extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation
+{
+ /**
+ * @var PHPUnit_Framework_Constraint[]
+ */
+ protected $parameters = [];
+
+ /**
+ * @var PHPUnit_Framework_MockObject_Invocation
+ */
+ protected $invocation;
+
+ /**
+ * @var PHPUnit_Framework_ExpectationFailedException
+ */
+ private $parameterVerificationResult;
+
+ /**
+ * @param array $parameters
+ */
+ public function __construct(array $parameters)
+ {
+ foreach ($parameters as $parameter) {
+ if (!($parameter instanceof PHPUnit_Framework_Constraint)) {
+ $parameter = new PHPUnit_Framework_Constraint_IsEqual(
+ $parameter
+ );
+ }
+
+ $this->parameters[] = $parameter;
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function toString()
+ {
+ $text = 'with parameter';
+
+ foreach ($this->parameters as $index => $parameter) {
+ if ($index > 0) {
+ $text .= ' and';
+ }
+
+ $text .= ' ' . $index . ' ' . $parameter->toString();
+ }
+
+ return $text;
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation
+ *
+ * @return bool
+ */
+ public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ $this->invocation = $invocation;
+ $this->parameterVerificationResult = null;
+
+ try {
+ $this->parameterVerificationResult = $this->verify();
+
+ return $this->parameterVerificationResult;
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->parameterVerificationResult = $e;
+
+ throw $this->parameterVerificationResult;
+ }
+ }
+
+ /**
+ * Checks if the invocation $invocation matches the current rules. If it
+ * does the matcher will get the invoked() method called which should check
+ * if an expectation is met.
+ *
+ * @return bool
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function verify()
+ {
+ if (isset($this->parameterVerificationResult)) {
+ return $this->guardAgainstDuplicateEvaluationOfParameterConstraints();
+ }
+
+ if ($this->invocation === null) {
+ throw new PHPUnit_Framework_ExpectationFailedException(
+ 'Mocked method does not exist.'
+ );
+ }
+
+ if (count($this->invocation->parameters) < count($this->parameters)) {
+ $message = 'Parameter count for invocation %s is too low.';
+
+ // The user called `->with($this->anything())`, but may have meant
+ // `->withAnyParameters()`.
+ //
+ // @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/199
+ if (count($this->parameters) === 1 &&
+ get_class($this->parameters[0]) === 'PHPUnit_Framework_Constraint_IsAnything') {
+ $message .= "\nTo allow 0 or more parameters with any value, omit ->with() or use ->withAnyParameters() instead.";
+ }
+
+ throw new PHPUnit_Framework_ExpectationFailedException(
+ sprintf($message, $this->invocation->toString())
+ );
+ }
+
+ foreach ($this->parameters as $i => $parameter) {
+ $parameter->evaluate(
+ $this->invocation->parameters[$i],
+ sprintf(
+ 'Parameter %s for invocation %s does not match expected ' .
+ 'value.',
+ $i,
+ $this->invocation->toString()
+ )
+ );
+ }
+
+ return true;
+ }
+
+ /**
+ * @return bool
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ private function guardAgainstDuplicateEvaluationOfParameterConstraints()
+ {
+ if ($this->parameterVerificationResult instanceof Exception) {
+ throw $this->parameterVerificationResult;
+ }
+
+ return (bool) $this->parameterVerificationResult;
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/StatelessInvocation.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/StatelessInvocation.php
new file mode 100644
index 0000000..33f3af0
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/StatelessInvocation.php
@@ -0,0 +1,54 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Invocation matcher which does not care about previous state from earlier
+ * invocations.
+ *
+ * This abstract class can be implemented by matchers which does not care about
+ * state but only the current run-time value of the invocation itself.
+ *
+ * @since Class available since Release 1.0.0
+ * @abstract
+ */
+abstract class PHPUnit_Framework_MockObject_Matcher_StatelessInvocation implements PHPUnit_Framework_MockObject_Matcher_Invocation
+{
+ /**
+ * Registers the invocation $invocation in the object as being invoked.
+ * This will only occur after matches() returns true which means the
+ * current invocation is the correct one.
+ *
+ * The matcher can store information from the invocation which can later
+ * be checked in verify(), or it can check the values directly and throw
+ * and exception if an expectation is not met.
+ *
+ * If the matcher is a stub it will also have a return value.
+ *
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation Object containing information on a mocked or stubbed method which was invoked
+ *
+ * @return mixed
+ */
+ public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ }
+
+ /**
+ * Checks if the invocation $invocation matches the current rules. If it does
+ * the matcher will get the invoked() method called which should check if an
+ * expectation is met.
+ *
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation Object containing information on a mocked or stubbed method which was invoked
+ *
+ * @return bool
+ */
+ public function verify()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockBuilder.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockBuilder.php
new file mode 100644
index 0000000..ea6804a
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockBuilder.php
@@ -0,0 +1,408 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Implementation of the Builder pattern for Mock objects.
+ *
+ * @since File available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_MockBuilder
+{
+ /**
+ * @var PHPUnit_Framework_TestCase
+ */
+ private $testCase;
+
+ /**
+ * @var string
+ */
+ private $type;
+
+ /**
+ * @var array
+ */
+ private $methods = [];
+
+ /**
+ * @var array
+ */
+ private $methodsExcept = [];
+
+ /**
+ * @var string
+ */
+ private $mockClassName = '';
+
+ /**
+ * @var array
+ */
+ private $constructorArgs = [];
+
+ /**
+ * @var bool
+ */
+ private $originalConstructor = true;
+
+ /**
+ * @var bool
+ */
+ private $originalClone = true;
+
+ /**
+ * @var bool
+ */
+ private $autoload = true;
+
+ /**
+ * @var bool
+ */
+ private $cloneArguments = false;
+
+ /**
+ * @var bool
+ */
+ private $callOriginalMethods = false;
+
+ /**
+ * @var object
+ */
+ private $proxyTarget = null;
+
+ /**
+ * @var bool
+ */
+ private $allowMockingUnknownTypes = true;
+
+ /**
+ * @var PHPUnit_Framework_MockObject_Generator
+ */
+ private $generator;
+
+ /**
+ * @param PHPUnit_Framework_TestCase $testCase
+ * @param array|string $type
+ */
+ public function __construct(PHPUnit_Framework_TestCase $testCase, $type)
+ {
+ $this->testCase = $testCase;
+ $this->type = $type;
+ $this->generator = new PHPUnit_Framework_MockObject_Generator;
+ }
+
+ /**
+ * Creates a mock object using a fluent interface.
+ *
+ * @return PHPUnit_Framework_MockObject_MockObject
+ */
+ public function getMock()
+ {
+ $object = $this->generator->getMock(
+ $this->type,
+ $this->methods,
+ $this->constructorArgs,
+ $this->mockClassName,
+ $this->originalConstructor,
+ $this->originalClone,
+ $this->autoload,
+ $this->cloneArguments,
+ $this->callOriginalMethods,
+ $this->proxyTarget,
+ $this->allowMockingUnknownTypes
+ );
+
+ $this->testCase->registerMockObject($object);
+
+ return $object;
+ }
+
+ /**
+ * Creates a mock object for an abstract class using a fluent interface.
+ *
+ * @return PHPUnit_Framework_MockObject_MockObject
+ */
+ public function getMockForAbstractClass()
+ {
+ $object = $this->generator->getMockForAbstractClass(
+ $this->type,
+ $this->constructorArgs,
+ $this->mockClassName,
+ $this->originalConstructor,
+ $this->originalClone,
+ $this->autoload,
+ $this->methods,
+ $this->cloneArguments
+ );
+
+ $this->testCase->registerMockObject($object);
+
+ return $object;
+ }
+
+ /**
+ * Creates a mock object for a trait using a fluent interface.
+ *
+ * @return PHPUnit_Framework_MockObject_MockObject
+ */
+ public function getMockForTrait()
+ {
+ $object = $this->generator->getMockForTrait(
+ $this->type,
+ $this->constructorArgs,
+ $this->mockClassName,
+ $this->originalConstructor,
+ $this->originalClone,
+ $this->autoload,
+ $this->methods,
+ $this->cloneArguments
+ );
+
+ $this->testCase->registerMockObject($object);
+
+ return $object;
+ }
+
+ /**
+ * Specifies the subset of methods to mock. Default is to mock all of them.
+ *
+ * @param array|null $methods
+ *
+ * @return PHPUnit_Framework_MockObject_MockBuilder
+ */
+ public function setMethods(array $methods = null)
+ {
+ $this->methods = $methods;
+
+ return $this;
+ }
+
+ /**
+ * Specifies the subset of methods to not mock. Default is to mock all of them.
+ *
+ * @param array $methods
+ *
+ * @return PHPUnit_Framework_MockObject_MockBuilder
+ */
+ public function setMethodsExcept(array $methods = [])
+ {
+ $this->methodsExcept = $methods;
+
+ $this->setMethods(
+ array_diff(
+ $this->generator->getClassMethods($this->type),
+ $this->methodsExcept
+ )
+ );
+
+ return $this;
+ }
+
+ /**
+ * Specifies the arguments for the constructor.
+ *
+ * @param array $args
+ *
+ * @return PHPUnit_Framework_MockObject_MockBuilder
+ */
+ public function setConstructorArgs(array $args)
+ {
+ $this->constructorArgs = $args;
+
+ return $this;
+ }
+
+ /**
+ * Specifies the name for the mock class.
+ *
+ * @param string $name
+ *
+ * @return PHPUnit_Framework_MockObject_MockBuilder
+ */
+ public function setMockClassName($name)
+ {
+ $this->mockClassName = $name;
+
+ return $this;
+ }
+
+ /**
+ * Disables the invocation of the original constructor.
+ *
+ * @return PHPUnit_Framework_MockObject_MockBuilder
+ */
+ public function disableOriginalConstructor()
+ {
+ $this->originalConstructor = false;
+
+ return $this;
+ }
+
+ /**
+ * Enables the invocation of the original constructor.
+ *
+ * @return PHPUnit_Framework_MockObject_MockBuilder
+ *
+ * @since Method available since Release 1.2.0
+ */
+ public function enableOriginalConstructor()
+ {
+ $this->originalConstructor = true;
+
+ return $this;
+ }
+
+ /**
+ * Disables the invocation of the original clone constructor.
+ *
+ * @return PHPUnit_Framework_MockObject_MockBuilder
+ */
+ public function disableOriginalClone()
+ {
+ $this->originalClone = false;
+
+ return $this;
+ }
+
+ /**
+ * Enables the invocation of the original clone constructor.
+ *
+ * @return PHPUnit_Framework_MockObject_MockBuilder
+ *
+ * @since Method available since Release 1.2.0
+ */
+ public function enableOriginalClone()
+ {
+ $this->originalClone = true;
+
+ return $this;
+ }
+
+ /**
+ * Disables the use of class autoloading while creating the mock object.
+ *
+ * @return PHPUnit_Framework_MockObject_MockBuilder
+ */
+ public function disableAutoload()
+ {
+ $this->autoload = false;
+
+ return $this;
+ }
+
+ /**
+ * Enables the use of class autoloading while creating the mock object.
+ *
+ * @return PHPUnit_Framework_MockObject_MockBuilder
+ *
+ * @since Method available since Release 1.2.0
+ */
+ public function enableAutoload()
+ {
+ $this->autoload = true;
+
+ return $this;
+ }
+
+ /**
+ * Disables the cloning of arguments passed to mocked methods.
+ *
+ * @return PHPUnit_Framework_MockObject_MockBuilder
+ *
+ * @since Method available since Release 1.2.0
+ */
+ public function disableArgumentCloning()
+ {
+ $this->cloneArguments = false;
+
+ return $this;
+ }
+
+ /**
+ * Enables the cloning of arguments passed to mocked methods.
+ *
+ * @return PHPUnit_Framework_MockObject_MockBuilder
+ *
+ * @since Method available since Release 1.2.0
+ */
+ public function enableArgumentCloning()
+ {
+ $this->cloneArguments = true;
+
+ return $this;
+ }
+
+ /**
+ * Enables the invocation of the original methods.
+ *
+ * @return PHPUnit_Framework_MockObject_MockBuilder
+ *
+ * @since Method available since Release 2.0.0
+ */
+ public function enableProxyingToOriginalMethods()
+ {
+ $this->callOriginalMethods = true;
+
+ return $this;
+ }
+
+ /**
+ * Disables the invocation of the original methods.
+ *
+ * @return PHPUnit_Framework_MockObject_MockBuilder
+ *
+ * @since Method available since Release 2.0.0
+ */
+ public function disableProxyingToOriginalMethods()
+ {
+ $this->callOriginalMethods = false;
+ $this->proxyTarget = null;
+
+ return $this;
+ }
+
+ /**
+ * Sets the proxy target.
+ *
+ * @param object $object
+ *
+ * @return PHPUnit_Framework_MockObject_MockBuilder
+ *
+ * @since Method available since Release 2.0.0
+ */
+ public function setProxyTarget($object)
+ {
+ $this->proxyTarget = $object;
+
+ return $this;
+ }
+
+ /**
+ * @return PHPUnit_Framework_MockObject_MockBuilder
+ *
+ * @since Method available since Release 3.2.0
+ */
+ public function allowMockingUnknownTypes()
+ {
+ $this->allowMockingUnknownTypes = true;
+
+ return $this;
+ }
+
+ /**
+ * @return PHPUnit_Framework_MockObject_MockBuilder
+ *
+ * @since Method available since Release 3.2.0
+ */
+ public function disallowMockingUnknownTypes()
+ {
+ $this->allowMockingUnknownTypes = false;
+
+ return $this;
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockObject.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockObject.php
new file mode 100644
index 0000000..e1a2e4e
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockObject.php
@@ -0,0 +1,55 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface for all mock objects which are generated by
+ * PHPUnit_Framework_MockObject_MockBuilder.
+ *
+ * @method PHPUnit_Framework_MockObject_Builder_InvocationMocker method($constraint)
+ *
+ * @since Interface available since Release 1.0.0
+ */
+interface PHPUnit_Framework_MockObject_MockObject /*extends PHPUnit_Framework_MockObject_Verifiable*/
+{
+ /**
+ * Registers a new expectation in the mock object and returns the match
+ * object which can be infused with further details.
+ *
+ * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher
+ *
+ * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
+ */
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher);
+
+ /**
+ * @return PHPUnit_Framework_MockObject_InvocationMocker
+ *
+ * @since Method available since Release 2.0.0
+ */
+ public function __phpunit_setOriginalObject($originalObject);
+
+ /**
+ * @return PHPUnit_Framework_MockObject_InvocationMocker
+ */
+ public function __phpunit_getInvocationMocker();
+
+ /**
+ * Verifies that the current expectation is valid. If everything is OK the
+ * code should just return, if not it must throw an exception.
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function __phpunit_verify();
+
+ /**
+ * @return bool
+ */
+ public function __phpunit_hasMatchers();
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub.php
new file mode 100644
index 0000000..558d49e
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub.php
@@ -0,0 +1,30 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * An object that stubs the process of a normal method for a mock object.
+ *
+ * The stub object will replace the code for the stubbed method and return a
+ * specific value instead of the original value.
+ *
+ * @since Interface available since Release 1.0.0
+ */
+interface PHPUnit_Framework_MockObject_Stub extends PHPUnit_Framework_SelfDescribing
+{
+ /**
+ * Fakes the processing of the invocation $invocation by returning a
+ * specific value.
+ *
+ * @param PHPUnit_Framework_MockObject_Invocation $invocation The invocation which was mocked and matched by the current method and argument matchers
+ *
+ * @return mixed
+ */
+ public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation);
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ConsecutiveCalls.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ConsecutiveCalls.php
new file mode 100644
index 0000000..afc353d
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ConsecutiveCalls.php
@@ -0,0 +1,48 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use SebastianBergmann\Exporter\Exporter;
+
+/**
+ * Stubs a method by returning a user-defined stack of values.
+ *
+ * @since Class available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls implements PHPUnit_Framework_MockObject_Stub
+{
+ protected $stack;
+ protected $value;
+
+ public function __construct($stack)
+ {
+ $this->stack = $stack;
+ }
+
+ public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ $this->value = array_shift($this->stack);
+
+ if ($this->value instanceof PHPUnit_Framework_MockObject_Stub) {
+ $this->value = $this->value->invoke($invocation);
+ }
+
+ return $this->value;
+ }
+
+ public function toString()
+ {
+ $exporter = new Exporter;
+
+ return sprintf(
+ 'return user-specified value %s',
+ $exporter->export($this->value)
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Exception.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Exception.php
new file mode 100644
index 0000000..3c1b922
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Exception.php
@@ -0,0 +1,48 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use SebastianBergmann\Exporter\Exporter;
+
+/**
+ * Stubs a method by raising a user-defined exception.
+ *
+ * @since Class available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_Stub_Exception implements PHPUnit_Framework_MockObject_Stub
+{
+ protected $exception;
+
+ public function __construct($exception)
+ {
+ // TODO Replace check with type declaration when support for PHP 5 is dropped
+ if (!$exception instanceof Throwable && !$exception instanceof Exception) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ 'Exception must be an instance of Throwable (PHP 7) or Exception (PHP 5)'
+ );
+ }
+
+ $this->exception = $exception;
+ }
+
+ public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ throw $this->exception;
+ }
+
+ public function toString()
+ {
+ $exporter = new Exporter;
+
+ return sprintf(
+ 'raise user-specified exception %s',
+ $exporter->export($this->exception)
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/MatcherCollection.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/MatcherCollection.php
new file mode 100644
index 0000000..fdc5728
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/MatcherCollection.php
@@ -0,0 +1,25 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Stubs a method by returning a user-defined value.
+ *
+ * @since Interface available since Release 1.0.0
+ */
+interface PHPUnit_Framework_MockObject_Stub_MatcherCollection
+{
+ /**
+ * Adds a new matcher to the collection which can be used as an expectation
+ * or a stub.
+ *
+ * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher Matcher for invocations to mock objects
+ */
+ public function addMatcher(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher);
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Return.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Return.php
new file mode 100644
index 0000000..630504f
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Return.php
@@ -0,0 +1,41 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use SebastianBergmann\Exporter\Exporter;
+
+/**
+ * Stubs a method by returning a user-defined value.
+ *
+ * @since Class available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_Stub_Return implements PHPUnit_Framework_MockObject_Stub
+{
+ protected $value;
+
+ public function __construct($value)
+ {
+ $this->value = $value;
+ }
+
+ public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ return $this->value;
+ }
+
+ public function toString()
+ {
+ $exporter = new Exporter;
+
+ return sprintf(
+ 'return user-specified value %s',
+ $exporter->export($this->value)
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnArgument.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnArgument.php
new file mode 100644
index 0000000..fb79f4e
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnArgument.php
@@ -0,0 +1,38 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Stubs a method by returning an argument that was passed to the mocked method.
+ *
+ * @since Class available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_Stub_ReturnArgument extends PHPUnit_Framework_MockObject_Stub_Return
+{
+ protected $argumentIndex;
+
+ public function __construct($argumentIndex)
+ {
+ $this->argumentIndex = $argumentIndex;
+ }
+
+ public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ if (isset($invocation->parameters[$this->argumentIndex])) {
+ return $invocation->parameters[$this->argumentIndex];
+ } else {
+ return;
+ }
+ }
+
+ public function toString()
+ {
+ return sprintf('return argument #%d', $this->argumentIndex);
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnCallback.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnCallback.php
new file mode 100644
index 0000000..601b354
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnCallback.php
@@ -0,0 +1,51 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @since Class available since Release 1.0.0
+ */
+class PHPUnit_Framework_MockObject_Stub_ReturnCallback implements PHPUnit_Framework_MockObject_Stub
+{
+ protected $callback;
+
+ public function __construct($callback)
+ {
+ $this->callback = $callback;
+ }
+
+ public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ return call_user_func_array($this->callback, $invocation->parameters);
+ }
+
+ public function toString()
+ {
+ if (is_array($this->callback)) {
+ if (is_object($this->callback[0])) {
+ $class = get_class($this->callback[0]);
+ $type = '->';
+ } else {
+ $class = $this->callback[0];
+ $type = '::';
+ }
+
+ return sprintf(
+ 'return result of user defined callback %s%s%s() with the ' .
+ 'passed arguments',
+ $class,
+ $type,
+ $this->callback[1]
+ );
+ } else {
+ return 'return result of user defined callback ' . $this->callback .
+ ' with the passed arguments';
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnReference.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnReference.php
new file mode 100644
index 0000000..91dde3b
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnReference.php
@@ -0,0 +1,22 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Stubs a method by returning a user-defined reference to a value.
+ *
+ * @since Class available since Release 3.0.7
+ */
+class PHPUnit_Framework_MockObject_Stub_ReturnReference extends PHPUnit_Framework_MockObject_Stub_Return
+{
+ public function __construct(&$value)
+ {
+ $this->value = &$value;
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnSelf.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnSelf.php
new file mode 100644
index 0000000..dbb9a6d
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnSelf.php
@@ -0,0 +1,34 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Stubs a method by returning the current object.
+ *
+ * @since Class available since Release 1.1.0
+ */
+class PHPUnit_Framework_MockObject_Stub_ReturnSelf implements PHPUnit_Framework_MockObject_Stub
+{
+ public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ if (!$invocation instanceof PHPUnit_Framework_MockObject_Invocation_Object) {
+ throw new PHPUnit_Framework_MockObject_RuntimeException(
+ 'The current object can only be returned when mocking an ' .
+ 'object, not a static class.'
+ );
+ }
+
+ return $invocation->object;
+ }
+
+ public function toString()
+ {
+ return 'return the current object';
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnValueMap.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnValueMap.php
new file mode 100644
index 0000000..25ba4d1
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnValueMap.php
@@ -0,0 +1,47 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Stubs a method by returning a value from a map.
+ *
+ * @since Class available since Release 1.1.0
+ */
+class PHPUnit_Framework_MockObject_Stub_ReturnValueMap implements PHPUnit_Framework_MockObject_Stub
+{
+ protected $valueMap;
+
+ public function __construct(array $valueMap)
+ {
+ $this->valueMap = $valueMap;
+ }
+
+ public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
+ {
+ $parameterCount = count($invocation->parameters);
+
+ foreach ($this->valueMap as $map) {
+ if (!is_array($map) || $parameterCount != count($map) - 1) {
+ continue;
+ }
+
+ $return = array_pop($map);
+ if ($invocation->parameters === $map) {
+ return $return;
+ }
+ }
+
+ return;
+ }
+
+ public function toString()
+ {
+ return 'return value from a map';
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Verifiable.php b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Verifiable.php
new file mode 100644
index 0000000..c19dfb3
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/src/Framework/MockObject/Verifiable.php
@@ -0,0 +1,25 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface for classes which must verify a given expectation.
+ *
+ * @since Interface available since Release 1.0.0
+ */
+interface PHPUnit_Framework_MockObject_Verifiable
+{
+ /**
+ * Verifies that the current expectation is valid. If everything is OK the
+ * code should just return, if not it must throw an exception.
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function verify();
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/GeneratorTest.php b/vendor/phpunit/phpunit-mock-objects/tests/GeneratorTest.php
new file mode 100644
index 0000000..72f32c2
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/GeneratorTest.php
@@ -0,0 +1,200 @@
+<?php
+/**
+ * @covers PHPUnit_Framework_MockObject_Generator
+ *
+ * @uses PHPUnit_Framework_MockObject_InvocationMocker
+ * @uses PHPUnit_Framework_MockObject_Builder_InvocationMocker
+ * @uses PHPUnit_Framework_MockObject_Invocation_Object
+ * @uses PHPUnit_Framework_MockObject_Invocation_Static
+ * @uses PHPUnit_Framework_MockObject_Matcher
+ * @uses PHPUnit_Framework_MockObject_Matcher_InvokedRecorder
+ * @uses PHPUnit_Framework_MockObject_Matcher_MethodName
+ * @uses PHPUnit_Framework_MockObject_Stub_Return
+ * @uses PHPUnit_Framework_MockObject_Matcher_InvokedCount
+ */
+class Framework_MockObject_GeneratorTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @var PHPUnit_Framework_MockObject_Generator
+ */
+ private $generator;
+
+ protected function setUp()
+ {
+ $this->generator = new PHPUnit_Framework_MockObject_Generator;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_MockObject_RuntimeException
+ */
+ public function testGetMockFailsWhenInvalidFunctionNameIsPassedInAsAFunctionToMock()
+ {
+ $this->generator->getMock(stdClass::class, [0]);
+ }
+
+ public function testGetMockCanCreateNonExistingFunctions()
+ {
+ $mock = $this->generator->getMock(stdClass::class, ['testFunction']);
+
+ $this->assertTrue(method_exists($mock, 'testFunction'));
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_MockObject_RuntimeException
+ * @expectedExceptionMessage duplicates: "foo, bar, foo" (duplicate: "foo")
+ */
+ public function testGetMockGeneratorFails()
+ {
+ $this->generator->getMock(stdClass::class, ['foo', 'bar', 'foo']);
+ }
+
+ /**
+ * @requires PHP 7
+ */
+ public function testGetMockBlacklistedMethodNamesPhp7()
+ {
+ $mock = $this->generator->getMock(InterfaceWithSemiReservedMethodName::class);
+
+ $this->assertTrue(method_exists($mock, 'unset'));
+ $this->assertInstanceOf(InterfaceWithSemiReservedMethodName::class, $mock);
+ }
+
+ public function testGetMockForAbstractClassDoesNotFailWhenFakingInterfaces()
+ {
+ $mock = $this->generator->getMockForAbstractClass(Countable::class);
+
+ $this->assertTrue(method_exists($mock, 'count'));
+ }
+
+ public function testGetMockForAbstractClassStubbingAbstractClass()
+ {
+ $mock = $this->generator->getMockForAbstractClass(AbstractMockTestClass::class);
+
+ $this->assertTrue(method_exists($mock, 'doSomething'));
+ }
+
+ public function testGetMockForAbstractClassWithNonExistentMethods()
+ {
+ $mock = $this->generator->getMockForAbstractClass(
+ AbstractMockTestClass::class,
+ [],
+ '',
+ true,
+ true,
+ true,
+ ['nonexistentMethod']
+ );
+
+ $this->assertTrue(method_exists($mock, 'nonexistentMethod'));
+ $this->assertTrue(method_exists($mock, 'doSomething'));
+ }
+
+ public function testGetMockForAbstractClassShouldCreateStubsOnlyForAbstractMethodWhenNoMethodsWereInformed()
+ {
+ $mock = $this->generator->getMockForAbstractClass(AbstractMockTestClass::class);
+
+ $mock->expects($this->any())
+ ->method('doSomething')
+ ->willReturn('testing');
+
+ $this->assertEquals('testing', $mock->doSomething());
+ $this->assertEquals(1, $mock->returnAnything());
+ }
+
+ /**
+ * @dataProvider getMockForAbstractClassExpectsInvalidArgumentExceptionDataprovider
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testGetMockForAbstractClassExpectingInvalidArgumentException($className, $mockClassName)
+ {
+ $this->generator->getMockForAbstractClass($className, [], $mockClassName);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_MockObject_RuntimeException
+ */
+ public function testGetMockForAbstractClassAbstractClassDoesNotExist()
+ {
+ $this->generator->getMockForAbstractClass('Tux');
+ }
+
+ public function getMockForAbstractClassExpectsInvalidArgumentExceptionDataprovider()
+ {
+ return [
+ 'className not a string' => [[], ''],
+ 'mockClassName not a string' => [Countable::class, new stdClass],
+ ];
+ }
+
+ public function testGetMockForTraitWithNonExistentMethodsAndNonAbstractMethods()
+ {
+ $mock = $this->generator->getMockForTrait(
+ AbstractTrait::class,
+ [],
+ '',
+ true,
+ true,
+ true,
+ ['nonexistentMethod']
+ );
+
+ $this->assertTrue(method_exists($mock, 'nonexistentMethod'));
+ $this->assertTrue(method_exists($mock, 'doSomething'));
+ $this->assertTrue($mock->mockableMethod());
+ $this->assertTrue($mock->anotherMockableMethod());
+ }
+
+ public function testGetMockForTraitStubbingAbstractMethod()
+ {
+ $mock = $this->generator->getMockForTrait(AbstractTrait::class);
+
+ $this->assertTrue(method_exists($mock, 'doSomething'));
+ }
+
+ public function testGetMockForSingletonWithReflectionSuccess()
+ {
+ $mock = $this->generator->getMock(SingletonClass::class, ['doSomething'], [], '', false);
+
+ $this->assertInstanceOf('SingletonClass', $mock);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_MockObject_RuntimeException
+ */
+ public function testExceptionIsRaisedForMutuallyExclusiveOptions()
+ {
+ $this->generator->getMock(stdClass::class, [], [], '', false, true, true, true, true);
+ }
+
+ /**
+ * @requires PHP 7
+ */
+ public function testCanImplementInterfacesThatHaveMethodsWithReturnTypes()
+ {
+ $stub = $this->generator->getMock([AnInterfaceWithReturnType::class, AnInterface::class]);
+
+ $this->assertInstanceOf(AnInterfaceWithReturnType::class, $stub);
+ $this->assertInstanceOf(AnInterface::class, $stub);
+ $this->assertInstanceOf(PHPUnit_Framework_MockObject_MockObject::class, $stub);
+ }
+
+ public function testCanConfigureMethodsForDoubleOfNonExistentClass()
+ {
+ $className = 'X' . md5(microtime());
+
+ $mock = $this->generator->getMock($className, ['someMethod']);
+
+ $this->assertInstanceOf($className, $mock);
+ }
+
+ public function testCanInvokeMethodsOfNonExistentClass()
+ {
+ $className = 'X' . md5(microtime());
+
+ $mock = $this->generator->getMock($className, ['someMethod']);
+
+ $mock->expects($this->once())->method('someMethod');
+
+ $this->assertNull($mock->someMethod());
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockBuilderTest.php b/vendor/phpunit/phpunit-mock-objects/tests/MockBuilderTest.php
new file mode 100644
index 0000000..e495b6c
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockBuilderTest.php
@@ -0,0 +1,126 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Framework_MockBuilderTest extends PHPUnit_Framework_TestCase
+{
+ public function testMockBuilderRequiresClassName()
+ {
+ $mock = $this->getMockBuilder(Mockable::class)->getMock();
+
+ $this->assertTrue($mock instanceof Mockable);
+ }
+
+ public function testByDefaultMocksAllMethods()
+ {
+ $mock = $this->getMockBuilder(Mockable::class)->getMock();
+
+ $this->assertNull($mock->mockableMethod());
+ $this->assertNull($mock->anotherMockableMethod());
+ }
+
+ public function testMethodsToMockCanBeSpecified()
+ {
+ $mock = $this->getMockBuilder(Mockable::class)
+ ->setMethods(['mockableMethod'])
+ ->getMock();
+
+ $this->assertNull($mock->mockableMethod());
+ $this->assertTrue($mock->anotherMockableMethod());
+ }
+
+ public function testMethodExceptionsToMockCanBeSpecified()
+ {
+ $mock = $this->getMockBuilder(Mockable::class)
+ ->setMethodsExcept(['mockableMethod'])
+ ->getMock();
+
+ $this->assertTrue($mock->mockableMethod());
+ $this->assertNull($mock->anotherMockableMethod());
+ }
+
+ public function testEmptyMethodExceptionsToMockCanBeSpecified()
+ {
+ $mock = $this->getMockBuilder(Mockable::class)
+ ->setMethodsExcept()
+ ->getMock();
+
+ $this->assertNull($mock->mockableMethod());
+ $this->assertNull($mock->anotherMockableMethod());
+ }
+
+ public function testByDefaultDoesNotPassArgumentsToTheConstructor()
+ {
+ $mock = $this->getMockBuilder(Mockable::class)->getMock();
+
+ $this->assertEquals([null, null], $mock->constructorArgs);
+ }
+
+ public function testMockClassNameCanBeSpecified()
+ {
+ $mock = $this->getMockBuilder(Mockable::class)
+ ->setMockClassName('ACustomClassName')
+ ->getMock();
+
+ $this->assertTrue($mock instanceof ACustomClassName);
+ }
+
+ public function testConstructorArgumentsCanBeSpecified()
+ {
+ $mock = $this->getMockBuilder(Mockable::class)
+ ->setConstructorArgs([23, 42])
+ ->getMock();
+
+ $this->assertEquals([23, 42], $mock->constructorArgs);
+ }
+
+ public function testOriginalConstructorCanBeDisabled()
+ {
+ $mock = $this->getMockBuilder(Mockable::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->assertNull($mock->constructorArgs);
+ }
+
+ public function testByDefaultOriginalCloneIsPreserved()
+ {
+ $mock = $this->getMockBuilder(Mockable::class)
+ ->getMock();
+
+ $cloned = clone $mock;
+
+ $this->assertTrue($cloned->cloned);
+ }
+
+ public function testOriginalCloneCanBeDisabled()
+ {
+ $mock = $this->getMockBuilder(Mockable::class)
+ ->disableOriginalClone()
+ ->getMock();
+
+ $mock->cloned = false;
+ $cloned = clone $mock;
+
+ $this->assertFalse($cloned->cloned);
+ }
+
+ public function testProvidesAFluentInterface()
+ {
+ $spec = $this->getMockBuilder(Mockable::class)
+ ->setMethods(['mockableMethod'])
+ ->setConstructorArgs([])
+ ->setMockClassName('DummyClassName')
+ ->disableOriginalConstructor()
+ ->disableOriginalClone()
+ ->disableAutoload();
+
+ $this->assertTrue($spec instanceof PHPUnit_Framework_MockObject_MockBuilder);
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Builder/InvocationMockerTest.php b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Builder/InvocationMockerTest.php
new file mode 100644
index 0000000..17e034d
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Builder/InvocationMockerTest.php
@@ -0,0 +1,63 @@
+<?php
+class Framework_MockObject_Builder_InvocationMockerTest extends PHPUnit_Framework_TestCase
+{
+ public function testWillReturnWithOneValue()
+ {
+ $mock = $this->getMockBuilder(stdClass::class)
+ ->setMethods(['foo'])
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('foo')
+ ->willReturn(1);
+
+ $this->assertEquals(1, $mock->foo());
+ }
+
+ public function testWillReturnWithMultipleValues()
+ {
+ $mock = $this->getMockBuilder(stdClass::class)
+ ->setMethods(['foo'])
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('foo')
+ ->willReturn(1, 2, 3);
+
+ $this->assertEquals(1, $mock->foo());
+ $this->assertEquals(2, $mock->foo());
+ $this->assertEquals(3, $mock->foo());
+ }
+
+ public function testWillReturnOnConsecutiveCalls()
+ {
+ $mock = $this->getMockBuilder(stdClass::class)
+ ->setMethods(['foo'])
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('foo')
+ ->willReturnOnConsecutiveCalls(1, 2, 3);
+
+ $this->assertEquals(1, $mock->foo());
+ $this->assertEquals(2, $mock->foo());
+ $this->assertEquals(3, $mock->foo());
+ }
+
+ public function testWillReturnByReference()
+ {
+ $mock = $this->getMockBuilder(stdClass::class)
+ ->setMethods(['foo'])
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('foo')
+ ->willReturnReference($value);
+
+ $this->assertSame(null, $mock->foo());
+ $value = 'foo';
+ $this->assertSame('foo', $mock->foo());
+ $value = 'bar';
+ $this->assertSame('bar', $mock->foo());
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/232.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/232.phpt
new file mode 100644
index 0000000..7251057
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/232.phpt
@@ -0,0 +1,129 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true, true)
+--FILE--
+<?php
+trait BaseTrait
+{
+ protected function hello()
+ {
+ return 'hello';
+ }
+}
+
+trait ChildTrait
+{
+ use BaseTrait
+ {
+ hello as private hi;
+ }
+
+ protected function hello()
+ {
+ return 'hi';
+ }
+
+ protected function world()
+ {
+ return $this->hi();
+ }
+}
+
+class Foo
+{
+ use ChildTrait;
+
+ public function speak()
+ {
+ return $this->world();
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['speak'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function speak()
+ {
+ $arguments = array();
+ $count = func_num_args();
+
+ if ($count > 0) {
+ $_arguments = func_get_args();
+
+ for ($i = 0; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'speak', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
+
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/abstract_class.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/abstract_class.phpt
new file mode 100644
index 0000000..d8ae879
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/abstract_class.phpt
@@ -0,0 +1,147 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true, true)
+--FILE--
+<?php
+abstract class Foo
+{
+ public function one()
+ {
+ }
+
+ abstract public function two();
+
+ abstract protected function three();
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['one', 'two', 'three'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function one()
+ {
+ $arguments = array();
+ $count = func_num_args();
+
+ if ($count > 0) {
+ $_arguments = func_get_args();
+
+ for ($i = 0; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'one', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function two()
+ {
+ $arguments = array();
+ $count = func_num_args();
+
+ if ($count > 0) {
+ $_arguments = func_get_args();
+
+ for ($i = 0; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'two', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ protected function three()
+ {
+ $arguments = array();
+ $count = func_num_args();
+
+ if ($count > 0) {
+ $_arguments = func_get_args();
+
+ for ($i = 0; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'three', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class.phpt
new file mode 100644
index 0000000..a496f30
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class.phpt
@@ -0,0 +1,125 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true, true)
+--FILE--
+<?php
+class Foo
+{
+ public function bar(Foo $foo)
+ {
+ }
+
+ public function baz(Foo $foo)
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['bar', 'baz'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function bar(Foo $foo)
+ {
+ $arguments = array($foo);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'bar', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function baz(Foo $foo)
+ {
+ $arguments = array($foo);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'baz', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_call_parent_clone.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_call_parent_clone.phpt
new file mode 100644
index 0000000..0cb79bc
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_call_parent_clone.phpt
@@ -0,0 +1,77 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true)
+--FILE--
+<?php
+class Foo
+{
+ public function __clone()
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = [];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ parent::__clone();
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_call_parent_constructor.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_call_parent_constructor.phpt
new file mode 100644
index 0000000..53994c2
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_call_parent_constructor.phpt
@@ -0,0 +1,76 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true)
+--FILE--
+<?php
+class Foo
+{
+ public function __construct()
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = [];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_dont_call_parent_clone.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_dont_call_parent_clone.phpt
new file mode 100644
index 0000000..9725764
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_dont_call_parent_clone.phpt
@@ -0,0 +1,76 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', false)
+--FILE--
+<?php
+class Foo
+{
+ public function __clone()
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ false
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = [];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_dont_call_parent_constructor.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_dont_call_parent_constructor.phpt
new file mode 100644
index 0000000..53994c2
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_dont_call_parent_constructor.phpt
@@ -0,0 +1,76 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true)
+--FILE--
+<?php
+class Foo
+{
+ public function __construct()
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = [];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_implementing_interface_call_parent_constructor.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_implementing_interface_call_parent_constructor.phpt
new file mode 100644
index 0000000..e0eb795
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_implementing_interface_call_parent_constructor.phpt
@@ -0,0 +1,81 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true)
+--FILE--
+<?php
+interface IFoo
+{
+ public function __construct($bar);
+}
+
+class Foo implements IFoo
+{
+ public function __construct($bar)
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = [];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_implementing_interface_dont_call_parent_constructor.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_implementing_interface_dont_call_parent_constructor.phpt
new file mode 100644
index 0000000..e0eb795
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_implementing_interface_dont_call_parent_constructor.phpt
@@ -0,0 +1,81 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true)
+--FILE--
+<?php
+interface IFoo
+{
+ public function __construct($bar);
+}
+
+class Foo implements IFoo
+{
+ public function __construct($bar)
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = [];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_partial.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_partial.phpt
new file mode 100644
index 0000000..73ce059
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_partial.phpt
@@ -0,0 +1,103 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array('bar'), 'MockFoo', true, true)
+--FILE--
+<?php
+class Foo
+{
+ public function bar(Foo $foo)
+ {
+ }
+
+ public function baz(Foo $foo)
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array('bar'),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['bar'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function bar(Foo $foo)
+ {
+ $arguments = array($foo);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'bar', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_with_method_named_method.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_with_method_named_method.phpt
new file mode 100644
index 0000000..cadc16b
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_with_method_named_method.phpt
@@ -0,0 +1,92 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true, true)
+--FILE--
+<?php
+class Foo
+{
+ public function method()
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['method'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function method()
+ {
+ $arguments = array();
+ $count = func_num_args();
+
+ if ($count > 0) {
+ $_arguments = func_get_args();
+
+ for ($i = 0; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'method', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_with_method_with_variadic_arguments.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_with_method_with_variadic_arguments.phpt
new file mode 100644
index 0000000..2b467ed
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/class_with_method_with_variadic_arguments.phpt
@@ -0,0 +1,99 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('ClassWithMethodWithVariadicArguments', array(), 'MockFoo', true, true)
+--FILE--
+<?php
+class ClassWithMethodWithVariadicArguments
+{
+ public function methodWithVariadicArguments($a, ...$parameters)
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'ClassWithMethodWithVariadicArguments',
+ array(),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends ClassWithMethodWithVariadicArguments implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['methodwithvariadicarguments'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function methodWithVariadicArguments($a, ...$parameters)
+ {
+ $arguments = array($a);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'ClassWithMethodWithVariadicArguments', 'methodWithVariadicArguments', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/interface.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/interface.phpt
new file mode 100644
index 0000000..4924c09
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/interface.phpt
@@ -0,0 +1,97 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true, true)
+--FILE--
+<?php
+interface Foo
+{
+ public function bar(Foo $foo);
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo implements PHPUnit_Framework_MockObject_MockObject, Foo
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['bar'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function bar(Foo $foo)
+ {
+ $arguments = array($foo);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'bar', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/invocation_object_clone_object.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/invocation_object_clone_object.phpt
new file mode 100644
index 0000000..732440d
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/invocation_object_clone_object.phpt
@@ -0,0 +1,126 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true, true, true)
+--FILE--
+<?php
+class Foo
+{
+ public function bar(Foo $foo)
+ {
+ }
+
+ public function baz(Foo $foo)
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ true,
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['bar', 'baz'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function bar(Foo $foo)
+ {
+ $arguments = array($foo);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'bar', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function baz(Foo $foo)
+ {
+ $arguments = array($foo);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'baz', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class.phpt
new file mode 100644
index 0000000..d23d229
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class.phpt
@@ -0,0 +1,127 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('NS\Foo', array(), 'MockFoo', true, true)
+--FILE--
+<?php
+namespace NS;
+
+class Foo
+{
+ public function bar(Foo $foo)
+ {
+ }
+
+ public function baz(Foo $foo)
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new \PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'NS\Foo',
+ array(),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends NS\Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['bar', 'baz'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function bar(NS\Foo $foo)
+ {
+ $arguments = array($foo);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'NS\Foo', 'bar', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function baz(NS\Foo $foo)
+ {
+ $arguments = array($foo);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'NS\Foo', 'baz', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_call_parent_clone.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_call_parent_clone.phpt
new file mode 100644
index 0000000..70695e1
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_call_parent_clone.phpt
@@ -0,0 +1,79 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('NS\Foo', array(), 'MockFoo', true)
+--FILE--
+<?php
+namespace NS;
+
+class Foo
+{
+ public function __clone()
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new \PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'NS\Foo',
+ array(),
+ 'MockFoo',
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends NS\Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = [];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ parent::__clone();
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_call_parent_constructor.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_call_parent_constructor.phpt
new file mode 100644
index 0000000..a272945
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_call_parent_constructor.phpt
@@ -0,0 +1,78 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('NS\Foo', array(), 'MockFoo', true)
+--FILE--
+<?php
+namespace NS;
+
+class Foo
+{
+ public function __construct()
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new \PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'NS\Foo',
+ array(),
+ 'MockFoo',
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends NS\Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = [];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_dont_call_parent_clone.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_dont_call_parent_clone.phpt
new file mode 100644
index 0000000..4b69b31
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_dont_call_parent_clone.phpt
@@ -0,0 +1,78 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('NS\Foo', array(), 'MockFoo', false)
+--FILE--
+<?php
+namespace NS;
+
+class Foo
+{
+ public function __clone()
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new \PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'NS\Foo',
+ array(),
+ 'MockFoo',
+ false
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends NS\Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = [];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_dont_call_parent_constructor.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_dont_call_parent_constructor.phpt
new file mode 100644
index 0000000..a272945
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_dont_call_parent_constructor.phpt
@@ -0,0 +1,78 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('NS\Foo', array(), 'MockFoo', true)
+--FILE--
+<?php
+namespace NS;
+
+class Foo
+{
+ public function __construct()
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new \PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'NS\Foo',
+ array(),
+ 'MockFoo',
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends NS\Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = [];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_implementing_interface_call_parent_constructor.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_implementing_interface_call_parent_constructor.phpt
new file mode 100644
index 0000000..4c22eb9
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_implementing_interface_call_parent_constructor.phpt
@@ -0,0 +1,83 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('NS\Foo', array(), 'MockFoo', true)
+--FILE--
+<?php
+namespace NS;
+
+interface IFoo
+{
+ public function __construct($bar);
+}
+
+class Foo implements IFoo
+{
+ public function __construct($bar)
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new \PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'NS\Foo',
+ array(),
+ 'MockFoo',
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends NS\Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = [];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_implementing_interface_dont_call_parent_constructor.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_implementing_interface_dont_call_parent_constructor.phpt
new file mode 100644
index 0000000..4c22eb9
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_implementing_interface_dont_call_parent_constructor.phpt
@@ -0,0 +1,83 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('NS\Foo', array(), 'MockFoo', true)
+--FILE--
+<?php
+namespace NS;
+
+interface IFoo
+{
+ public function __construct($bar);
+}
+
+class Foo implements IFoo
+{
+ public function __construct($bar)
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new \PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'NS\Foo',
+ array(),
+ 'MockFoo',
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends NS\Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = [];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_partial.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_partial.phpt
new file mode 100644
index 0000000..2aed3b7
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_class_partial.phpt
@@ -0,0 +1,105 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('NS\Foo', array('bar'), 'MockFoo', true, true)
+--FILE--
+<?php
+namespace NS;
+
+class Foo
+{
+ public function bar(Foo $foo)
+ {
+ }
+
+ public function baz(Foo $foo)
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new \PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'NS\Foo',
+ array('bar'),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends NS\Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['bar'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function bar(NS\Foo $foo)
+ {
+ $arguments = array($foo);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'NS\Foo', 'bar', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_interface.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_interface.phpt
new file mode 100644
index 0000000..1e65fb0
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/namespaced_interface.phpt
@@ -0,0 +1,99 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('NS\Foo', array(), 'MockFoo', true, true)
+--FILE--
+<?php
+namespace NS;
+
+interface Foo
+{
+ public function bar(Foo $foo);
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new \PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'NS\Foo',
+ array(),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo implements PHPUnit_Framework_MockObject_MockObject, NS\Foo
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['bar'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function bar(NS\Foo $foo)
+ {
+ $arguments = array($foo);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'NS\Foo', 'bar', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nonexistent_class.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nonexistent_class.phpt
new file mode 100644
index 0000000..c0a3cb5
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nonexistent_class.phpt
@@ -0,0 +1,74 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('NonExistentClass', array(), 'MockFoo', true, true)
+--FILE--
+<?php
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'NonExistentClass',
+ array(),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class NonExistentClass
+{
+}
+
+class MockFoo extends NonExistentClass implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = [];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nonexistent_class_with_namespace.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nonexistent_class_with_namespace.phpt
new file mode 100644
index 0000000..fc700d1
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nonexistent_class_with_namespace.phpt
@@ -0,0 +1,82 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true, true)
+--FILE--
+<?php
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'NS\Foo',
+ array(),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+namespace NS {
+
+class Foo
+{
+}
+
+}
+
+namespace {
+
+class MockFoo extends NS\Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = [];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
+
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nonexistent_class_with_namespace_starting_with_separator.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nonexistent_class_with_namespace_starting_with_separator.phpt
new file mode 100644
index 0000000..51670e7
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nonexistent_class_with_namespace_starting_with_separator.phpt
@@ -0,0 +1,82 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true, true)
+--FILE--
+<?php
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ '\NS\Foo',
+ array(),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+namespace NS {
+
+class Foo
+{
+}
+
+}
+
+namespace {
+
+class MockFoo extends NS\Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = [];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
+
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nullable_types.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nullable_types.phpt
new file mode 100644
index 0000000..837d7ed
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/nullable_types.phpt
@@ -0,0 +1,103 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true, true)
+--SKIPIF--
+<?php
+if (!version_compare(PHP_VERSION, '7.1', '>=')) print 'skip: PHP >= 7.1 required';
+?>
+--FILE--
+<?php
+class Foo
+{
+ public function bar(?int $x)
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['bar'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function bar(?int $x)
+ {
+ $arguments = array($x);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'bar', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/proxy.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/proxy.phpt
new file mode 100644
index 0000000..559142a
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/proxy.phpt
@@ -0,0 +1,121 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', null, 'ProxyFoo', true, true, true, true)
+--FILE--
+<?php
+class Foo
+{
+ public function bar(Foo $foo)
+ {
+ }
+
+ public function baz(Foo $foo)
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo', array(), 'ProxyFoo', true, true, true, true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class ProxyFoo extends Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['bar', 'baz'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function bar(Foo $foo)
+ {
+ $arguments = array($foo);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'bar', $arguments, '', $this, true
+ )
+ );
+
+ return call_user_func_array(array($this->__phpunit_originalObject, "bar"), $arguments);
+ }
+
+ public function baz(Foo $foo)
+ {
+ $arguments = array($foo);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'baz', $arguments, '', $this, true
+ )
+ );
+
+ return call_user_func_array(array($this->__phpunit_originalObject, "baz"), $arguments);
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_nullable.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_nullable.phpt
new file mode 100644
index 0000000..76232bb
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_nullable.phpt
@@ -0,0 +1,101 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true, true)
+--SKIPIF--
+<?php
+if (!version_compare(PHP_VERSION, '7.1', '>=')) print 'skip: PHP >= 7.1 required';
+?>
+--FILE--
+<?php
+interface Foo
+{
+ public function bar(string $baz): ?string;
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo implements PHPUnit_Framework_MockObject_MockObject, Foo
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['bar'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function bar(string $baz): ?string
+ {
+ $arguments = array($baz);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'bar', $arguments, '?string', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_object_method.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_object_method.phpt
new file mode 100644
index 0000000..fb265bf
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_object_method.phpt
@@ -0,0 +1,104 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true, true)
+--SKIPIF--
+<?php
+if (!version_compare(PHP_VERSION, '7.0', '>=')) print 'skip: PHP >= 7.0 required';
+?>
+--FILE--
+<?php
+class Foo
+{
+ public function bar(string $baz): Bar
+ {
+ return 'test';
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['bar'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function bar(string $baz): Bar
+ {
+ $arguments = array($baz);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'bar', $arguments, 'Bar', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_self.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_self.phpt
new file mode 100644
index 0000000..4107d76
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_self.phpt
@@ -0,0 +1,101 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true, true)
+--SKIPIF--
+<?php
+if (!version_compare(PHP_VERSION, '7.0', '>=')) print 'skip: PHP >= 7.0 required';
+?>
+--FILE--
+<?php
+interface Foo
+{
+ public function bar(string $baz): self;
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo implements PHPUnit_Framework_MockObject_MockObject, Foo
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['bar'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function bar(string $baz): Foo
+ {
+ $arguments = array($baz);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'bar', $arguments, 'Foo', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_static_method.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_static_method.phpt
new file mode 100644
index 0000000..8b60e9b
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_static_method.phpt
@@ -0,0 +1,87 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true, true)
+--SKIPIF--
+<?php
+if (!version_compare(PHP_VERSION, '7.0', '>=')) print 'skip: PHP >= 7.0 required';
+?>
+--FILE--
+<?php
+class Foo
+{
+ public static function bar(string $baz): Bar
+ {
+ return 'test';
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['bar'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public static function bar(string $baz): Bar
+ {
+ throw new PHPUnit_Framework_MockObject_BadMethodCallException('Static method "bar" cannot be invoked on mock object');
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_void.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_void.phpt
new file mode 100644
index 0000000..99100ee
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/return_type_declarations_void.phpt
@@ -0,0 +1,99 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true, true)
+--SKIPIF--
+<?php
+if (!version_compare(PHP_VERSION, '7.1', '>=')) print 'skip: PHP >= 7.1 required';
+?>
+--FILE--
+<?php
+interface Foo
+{
+ public function bar(string $baz): void;
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo implements PHPUnit_Framework_MockObject_MockObject, Foo
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['bar'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function bar(string $baz): void
+ {
+ $arguments = array($baz);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'bar', $arguments, 'void', $this, true
+ )
+ );
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/scalar_type_declarations.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/scalar_type_declarations.phpt
new file mode 100644
index 0000000..5058b07
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/scalar_type_declarations.phpt
@@ -0,0 +1,103 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('Foo', array(), 'MockFoo', true, true)
+--SKIPIF--
+<?php
+if (!version_compare(PHP_VERSION, '7.0', '>=')) print 'skip: PHP >= 7.0 required';
+?>
+--FILE--
+<?php
+class Foo
+{
+ public function bar(string $baz)
+ {
+ }
+}
+
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'Foo',
+ array(),
+ 'MockFoo',
+ true,
+ true
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends Foo implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['bar'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function bar(string $baz)
+ {
+ $arguments = array($baz);
+ $count = func_num_args();
+
+ if ($count > 1) {
+ $_arguments = func_get_args();
+
+ for ($i = 1; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'Foo', 'bar', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/wsdl_class.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/wsdl_class.phpt
new file mode 100644
index 0000000..84dca20
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/wsdl_class.phpt
@@ -0,0 +1,37 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generateClassFromWsdl('GoogleSearch.wsdl', 'GoogleSearch')
+--SKIPIF--
+<?php
+if (!extension_loaded('soap')) echo 'skip: SOAP extension is required';
+?>
+--FILE--
+<?php
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+print $generator->generateClassFromWsdl(
+ __DIR__ . '/../../_fixture/GoogleSearch.wsdl',
+ 'GoogleSearch'
+);
+?>
+--EXPECTF--
+class GoogleSearch extends \SoapClient
+{
+ public function __construct($wsdl, array $options)
+ {
+ parent::__construct('%s/GoogleSearch.wsdl', $options);
+ }
+
+ public function doGoogleSearch($key, $q, $start, $maxResults, $filter, $restrict, $safeSearch, $lr, $ie, $oe)
+ {
+ }
+
+ public function doGetCachedPage($key, $url)
+ {
+ }
+
+ public function doSpellingSuggestion($key, $phrase)
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/wsdl_class_namespace.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/wsdl_class_namespace.phpt
new file mode 100644
index 0000000..bb672ae
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/wsdl_class_namespace.phpt
@@ -0,0 +1,39 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generateClassFromWsdl('GoogleSearch.wsdl', 'GoogleSearch')
+--SKIPIF--
+<?php
+if (!extension_loaded('soap')) echo 'skip: SOAP extension is required';
+?>
+--FILE--
+<?php
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+print $generator->generateClassFromWsdl(
+ __DIR__ . '/../../_fixture/GoogleSearch.wsdl',
+ 'My\\Space\\GoogleSearch'
+);
+?>
+--EXPECTF--
+namespace My\Space;
+
+class GoogleSearch extends \SoapClient
+{
+ public function __construct($wsdl, array $options)
+ {
+ parent::__construct('%s/GoogleSearch.wsdl', $options);
+ }
+
+ public function doGoogleSearch($key, $q, $start, $maxResults, $filter, $restrict, $safeSearch, $lr, $ie, $oe)
+ {
+ }
+
+ public function doGetCachedPage($key, $url)
+ {
+ }
+
+ public function doSpellingSuggestion($key, $phrase)
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/wsdl_class_partial.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/wsdl_class_partial.phpt
new file mode 100644
index 0000000..f3fff26
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Generator/wsdl_class_partial.phpt
@@ -0,0 +1,30 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generateClassFromWsdl('GoogleSearch.wsdl', 'GoogleSearch', array('doGoogleSearch'))
+--SKIPIF--
+<?php
+if (!extension_loaded('soap')) echo 'skip: SOAP extension is required';
+?>
+--FILE--
+<?php
+require __DIR__ . '/../../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+print $generator->generateClassFromWsdl(
+ __DIR__ . '/../../_fixture/GoogleSearch.wsdl',
+ 'GoogleSearch',
+ array('doGoogleSearch')
+);
+?>
+--EXPECTF--
+class GoogleSearch extends \SoapClient
+{
+ public function __construct($wsdl, array $options)
+ {
+ parent::__construct('%s/GoogleSearch.wsdl', $options);
+ }
+
+ public function doGoogleSearch($key, $q, $start, $maxResults, $filter, $restrict, $safeSearch, $lr, $ie, $oe)
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Invocation/ObjectTest.php b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Invocation/ObjectTest.php
new file mode 100644
index 0000000..0a93ef5
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Invocation/ObjectTest.php
@@ -0,0 +1,108 @@
+<?php
+class Framework_MockObject_Invocation_ObjectTest extends PHPUnit_Framework_TestCase
+{
+ public function testConstructorRequiresClassAndMethodAndParametersAndObject()
+ {
+ $this->assertInstanceOf(
+ PHPUnit_Framework_MockObject_Invocation_Object::class,
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'FooClass',
+ 'FooMethod',
+ ['an_argument'],
+ 'ReturnType',
+ new stdClass
+ )
+ );
+ }
+
+ public function testAllowToGetClassNameSetInConstructor()
+ {
+ $invocation = new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'FooClass',
+ 'FooMethod',
+ ['an_argument'],
+ 'ReturnType',
+ new stdClass
+ );
+
+ $this->assertSame('FooClass', $invocation->className);
+ }
+
+ public function testAllowToGetMethodNameSetInConstructor()
+ {
+ $invocation = new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'FooClass',
+ 'FooMethod',
+ ['an_argument'],
+ 'ReturnType',
+ new stdClass
+ );
+
+ $this->assertSame('FooMethod', $invocation->methodName);
+ }
+
+ public function testAllowToGetObjectSetInConstructor()
+ {
+ $expectedObject = new stdClass;
+
+ $invocation = new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'FooClass',
+ 'FooMethod',
+ ['an_argument'],
+ 'ReturnType',
+ $expectedObject
+ );
+
+ $this->assertSame($expectedObject, $invocation->object);
+ }
+
+ public function testAllowToGetMethodParametersSetInConstructor()
+ {
+ $expectedParameters = [
+ 'foo', 5, ['a', 'b'], new stdClass, null, false
+ ];
+
+ $invocation = new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'FooClass',
+ 'FooMethod',
+ $expectedParameters,
+ 'ReturnType',
+ new stdClass
+ );
+
+ $this->assertSame($expectedParameters, $invocation->parameters);
+ }
+
+ public function testConstructorAllowToSetFlagCloneObjectsInParameters()
+ {
+ $parameters = [new stdClass];
+ $cloneObjects = true;
+
+ $invocation = new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'FooClass',
+ 'FooMethod',
+ $parameters,
+ 'ReturnType',
+ new stdClass,
+ $cloneObjects
+ );
+
+ $this->assertEquals($parameters, $invocation->parameters);
+ $this->assertNotSame($parameters, $invocation->parameters);
+ }
+
+ public function testAllowToGetReturnTypeSetInConstructor()
+ {
+ $expectedReturnType = 'string';
+
+ $invocation = new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'FooClass',
+ 'FooMethod',
+ ['an_argument'],
+ $expectedReturnType,
+ new stdClass
+ );
+
+ $this->assertSame($expectedReturnType, $invocation->returnType);
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Invocation/StaticTest.php b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Invocation/StaticTest.php
new file mode 100644
index 0000000..8f5ff31
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Invocation/StaticTest.php
@@ -0,0 +1,87 @@
+<?php
+class Framework_MockObject_Invocation_StaticTest extends PHPUnit_Framework_TestCase
+{
+ public function testConstructorRequiresClassAndMethodAndParameters()
+ {
+ $this->assertInstanceOf(
+ PHPUnit_Framework_MockObject_Invocation_Static::class,
+ new PHPUnit_Framework_MockObject_Invocation_Static(
+ 'FooClass',
+ 'FooMethod',
+ ['an_argument'],
+ 'ReturnType'
+ )
+ );
+ }
+
+ public function testAllowToGetClassNameSetInConstructor()
+ {
+ $invocation = new PHPUnit_Framework_MockObject_Invocation_Static(
+ 'FooClass',
+ 'FooMethod',
+ ['an_argument'],
+ 'ReturnType'
+ );
+
+ $this->assertSame('FooClass', $invocation->className);
+ }
+
+ public function testAllowToGetMethodNameSetInConstructor()
+ {
+ $invocation = new PHPUnit_Framework_MockObject_Invocation_Static(
+ 'FooClass',
+ 'FooMethod',
+ ['an_argument'],
+ 'ReturnType'
+ );
+
+ $this->assertSame('FooMethod', $invocation->methodName);
+ }
+
+ public function testAllowToGetMethodParametersSetInConstructor()
+ {
+ $expectedParameters = [
+ 'foo', 5, ['a', 'b'], new stdClass, null, false
+ ];
+
+ $invocation = new PHPUnit_Framework_MockObject_Invocation_Static(
+ 'FooClass',
+ 'FooMethod',
+ $expectedParameters,
+ 'ReturnType'
+ );
+
+ $this->assertSame($expectedParameters, $invocation->parameters);
+ }
+
+ public function testConstructorAllowToSetFlagCloneObjectsInParameters()
+ {
+ $parameters = [new stdClass];
+ $cloneObjects = true;
+
+ $invocation = new PHPUnit_Framework_MockObject_Invocation_Static(
+ 'FooClass',
+ 'FooMethod',
+ $parameters,
+ 'ReturnType',
+ $cloneObjects
+ );
+
+ $this->assertEquals($parameters, $invocation->parameters);
+ $this->assertNotSame($parameters, $invocation->parameters);
+ }
+
+ public function testAllowToGetReturnTypeSetInConstructor()
+ {
+ $expectedReturnType = 'string';
+
+ $invocation = new PHPUnit_Framework_MockObject_Invocation_Static(
+ 'FooClass',
+ 'FooMethod',
+ ['an_argument'],
+ $expectedReturnType
+ );
+
+ $this->assertSame($expectedReturnType, $invocation->returnType);
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Matcher/ConsecutiveParametersTest.php b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Matcher/ConsecutiveParametersTest.php
new file mode 100644
index 0000000..06ef46c
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/Matcher/ConsecutiveParametersTest.php
@@ -0,0 +1,56 @@
+<?php
+class Framework_MockObject_Matcher_ConsecutiveParametersTest extends PHPUnit_Framework_TestCase
+{
+ public function testIntegration()
+ {
+ $mock = $this->getMockBuilder(stdClass::class)
+ ->setMethods(['foo'])
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('foo')
+ ->withConsecutive(
+ ['bar'],
+ [21, 42]
+ );
+
+ $this->assertNull($mock->foo('bar'));
+ $this->assertNull($mock->foo(21, 42));
+ }
+
+ public function testIntegrationWithLessAssertionsThanMethodCalls()
+ {
+ $mock = $this->getMockBuilder(stdClass::class)
+ ->setMethods(['foo'])
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('foo')
+ ->withConsecutive(
+ ['bar']
+ );
+
+ $this->assertNull($mock->foo('bar'));
+ $this->assertNull($mock->foo(21, 42));
+ }
+
+ public function testIntegrationExpectingException()
+ {
+ $mock = $this->getMockBuilder(stdClass::class)
+ ->setMethods(['foo'])
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('foo')
+ ->withConsecutive(
+ ['bar'],
+ [21, 42]
+ );
+
+ $mock->foo('bar');
+
+ $this->expectException(PHPUnit_Framework_ExpectationFailedException::class);
+
+ $mock->foo('invalid');
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObject/class_with_deprecated_method.phpt b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/class_with_deprecated_method.phpt
new file mode 100644
index 0000000..4f7ffb6
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObject/class_with_deprecated_method.phpt
@@ -0,0 +1,105 @@
+--TEST--
+PHPUnit_Framework_MockObject_Generator::generate('ClassWithDeprecatedMethod', array(), 'MockFoo', TRUE, TRUE)
+--FILE--
+<?php
+class ClassWithDeprecatedMethod
+{
+ /**
+ * @deprecated this method
+ * is deprecated
+ */
+ public function deprecatedMethod()
+ {
+ }
+}
+
+require __DIR__ . '/../../vendor/autoload.php';
+
+$generator = new PHPUnit_Framework_MockObject_Generator;
+
+$mock = $generator->generate(
+ 'ClassWithDeprecatedMethod',
+ array(),
+ 'MockFoo',
+ TRUE,
+ TRUE
+);
+
+print $mock['code'];
+?>
+--EXPECTF--
+class MockFoo extends ClassWithDeprecatedMethod implements PHPUnit_Framework_MockObject_MockObject
+{
+ private $__phpunit_invocationMocker;
+ private $__phpunit_originalObject;
+ private $__phpunit_configurable = ['deprecatedmethod'];
+
+ public function __clone()
+ {
+ $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
+ }
+
+ public function deprecatedMethod()
+ {
+ @trigger_error('The ClassWithDeprecatedMethod::deprecatedMethod method is deprecated (this method is deprecated).', E_USER_DEPRECATED);
+
+ $arguments = array();
+ $count = func_num_args();
+
+ if ($count > 0) {
+ $_arguments = func_get_args();
+
+ for ($i = 0; $i < $count; $i++) {
+ $arguments[] = $_arguments[$i];
+ }
+ }
+
+ $result = $this->__phpunit_getInvocationMocker()->invoke(
+ new PHPUnit_Framework_MockObject_Invocation_Object(
+ 'ClassWithDeprecatedMethod', 'deprecatedMethod', $arguments, '', $this, true
+ )
+ );
+
+ return $result;
+ }
+
+ public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
+ {
+ return $this->__phpunit_getInvocationMocker()->expects($matcher);
+ }
+
+ public function method()
+ {
+ $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ $expects = $this->expects($any);
+ return call_user_func_array(array($expects, 'method'), func_get_args());
+ }
+
+ public function __phpunit_setOriginalObject($originalObject)
+ {
+ $this->__phpunit_originalObject = $originalObject;
+ }
+
+ public function __phpunit_getInvocationMocker()
+ {
+ if ($this->__phpunit_invocationMocker === null) {
+ $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker($this->__phpunit_configurable);
+ }
+
+ return $this->__phpunit_invocationMocker;
+ }
+
+ public function __phpunit_hasMatchers()
+ {
+ return $this->__phpunit_getInvocationMocker()->hasMatchers();
+ }
+
+ public function __phpunit_verify($unsetInvocationMocker = true)
+ {
+ $this->__phpunit_getInvocationMocker()->verify();
+
+ if ($unsetInvocationMocker) {
+ $this->__phpunit_invocationMocker = null;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/MockObjectTest.php b/vendor/phpunit/phpunit-mock-objects/tests/MockObjectTest.php
new file mode 100644
index 0000000..302dae7
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/MockObjectTest.php
@@ -0,0 +1,1034 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Framework_MockObjectTest extends PHPUnit_Framework_TestCase
+{
+ public function testMockedMethodIsNeverCalled()
+ {
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->never())
+ ->method('doSomething');
+ }
+
+ public function testMockedMethodIsNeverCalledWithParameter()
+ {
+ $mock = $this->getMockBuilder(SomeClass::class)
+ ->getMock();
+
+ $mock->expects($this->never())
+ ->method('doSomething')
+ ->with('someArg');
+ }
+
+ /**
+ * @doesNotPerformAssertions
+ */
+ public function testMockedMethodIsNotCalledWhenExpectsAnyWithParameter()
+ {
+ $mock = $this->getMockBuilder(SomeClass::class)
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('doSomethingElse')
+ ->with('someArg');
+ }
+
+ /**
+ * @doesNotPerformAssertions
+ */
+ public function testMockedMethodIsNotCalledWhenMethodSpecifiedDirectlyWithParameter()
+ {
+ $mock = $this->getMockBuilder(SomeClass::class)
+ ->getMock();
+
+ $mock->method('doSomethingElse')
+ ->with('someArg');
+ }
+
+ public function testMockedMethodIsCalledAtLeastOnce()
+ {
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->atLeastOnce())
+ ->method('doSomething');
+
+ $mock->doSomething();
+ }
+
+ public function testMockedMethodIsCalledAtLeastOnce2()
+ {
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->atLeastOnce())
+ ->method('doSomething');
+
+ $mock->doSomething();
+ $mock->doSomething();
+ }
+
+ public function testMockedMethodIsCalledAtLeastTwice()
+ {
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->atLeast(2))
+ ->method('doSomething');
+
+ $mock->doSomething();
+ $mock->doSomething();
+ }
+
+ public function testMockedMethodIsCalledAtLeastTwice2()
+ {
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->atLeast(2))
+ ->method('doSomething');
+
+ $mock->doSomething();
+ $mock->doSomething();
+ $mock->doSomething();
+ }
+
+ public function testMockedMethodIsCalledAtMostTwice()
+ {
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->atMost(2))
+ ->method('doSomething');
+
+ $mock->doSomething();
+ $mock->doSomething();
+ }
+
+ public function testMockedMethodIsCalledAtMosttTwice2()
+ {
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->atMost(2))
+ ->method('doSomething');
+
+ $mock->doSomething();
+ }
+
+ public function testMockedMethodIsCalledOnce()
+ {
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->once())
+ ->method('doSomething');
+
+ $mock->doSomething();
+ }
+
+ public function testMockedMethodIsCalledOnceWithParameter()
+ {
+ $mock = $this->getMockBuilder(SomeClass::class)
+ ->getMock();
+
+ $mock->expects($this->once())
+ ->method('doSomethingElse')
+ ->with($this->equalTo('something'));
+
+ $mock->doSomethingElse('something');
+ }
+
+ public function testMockedMethodIsCalledExactly()
+ {
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->exactly(2))
+ ->method('doSomething');
+
+ $mock->doSomething();
+ $mock->doSomething();
+ }
+
+ public function testStubbedException()
+ {
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('doSomething')
+ ->will($this->throwException(new Exception));
+
+ $this->expectException(Exception::class);
+
+ $mock->doSomething();
+ }
+
+ public function testStubbedWillThrowException()
+ {
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('doSomething')
+ ->willThrowException(new Exception);
+
+ $this->expectException(Exception::class);
+
+ $mock->doSomething();
+ }
+
+ public function testStubbedReturnValue()
+ {
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('doSomething')
+ ->will($this->returnValue('something'));
+
+ $this->assertEquals('something', $mock->doSomething());
+
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('doSomething')
+ ->willReturn('something');
+
+ $this->assertEquals('something', $mock->doSomething());
+ }
+
+ public function testStubbedReturnValueMap()
+ {
+ $map = [
+ ['a', 'b', 'c', 'd'],
+ ['e', 'f', 'g', 'h']
+ ];
+
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('doSomething')
+ ->will($this->returnValueMap($map));
+
+ $this->assertEquals('d', $mock->doSomething('a', 'b', 'c'));
+ $this->assertEquals('h', $mock->doSomething('e', 'f', 'g'));
+ $this->assertEquals(null, $mock->doSomething('foo', 'bar'));
+
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('doSomething')
+ ->willReturnMap($map);
+
+ $this->assertEquals('d', $mock->doSomething('a', 'b', 'c'));
+ $this->assertEquals('h', $mock->doSomething('e', 'f', 'g'));
+ $this->assertEquals(null, $mock->doSomething('foo', 'bar'));
+ }
+
+ public function testStubbedReturnArgument()
+ {
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('doSomething')
+ ->will($this->returnArgument(1));
+
+ $this->assertEquals('b', $mock->doSomething('a', 'b'));
+
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('doSomething')
+ ->willReturnArgument(1);
+
+ $this->assertEquals('b', $mock->doSomething('a', 'b'));
+ }
+
+ public function testFunctionCallback()
+ {
+ $mock = $this->getMockBuilder(SomeClass::class)
+ ->setMethods(['doSomething'])
+ ->getMock();
+
+ $mock->expects($this->once())
+ ->method('doSomething')
+ ->will($this->returnCallback('functionCallback'));
+
+ $this->assertEquals('pass', $mock->doSomething('foo', 'bar'));
+
+ $mock = $this->getMockBuilder(SomeClass::class)
+ ->setMethods(['doSomething'])
+ ->getMock();
+
+ $mock->expects($this->once())
+ ->method('doSomething')
+ ->willReturnCallback('functionCallback');
+
+ $this->assertEquals('pass', $mock->doSomething('foo', 'bar'));
+ }
+
+ public function testStubbedReturnSelf()
+ {
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('doSomething')
+ ->will($this->returnSelf());
+
+ $this->assertEquals($mock, $mock->doSomething());
+
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('doSomething')
+ ->willReturnSelf();
+
+ $this->assertEquals($mock, $mock->doSomething());
+ }
+
+ public function testStubbedReturnOnConsecutiveCalls()
+ {
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('doSomething')
+ ->will($this->onConsecutiveCalls('a', 'b', 'c'));
+
+ $this->assertEquals('a', $mock->doSomething());
+ $this->assertEquals('b', $mock->doSomething());
+ $this->assertEquals('c', $mock->doSomething());
+
+ $mock = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock->expects($this->any())
+ ->method('doSomething')
+ ->willReturnOnConsecutiveCalls('a', 'b', 'c');
+
+ $this->assertEquals('a', $mock->doSomething());
+ $this->assertEquals('b', $mock->doSomething());
+ $this->assertEquals('c', $mock->doSomething());
+ }
+
+ public function testStaticMethodCallback()
+ {
+ $mock = $this->getMockBuilder(SomeClass::class)
+ ->setMethods(['doSomething'])
+ ->getMock();
+
+ $mock->expects($this->once())
+ ->method('doSomething')
+ ->will($this->returnCallback(['MethodCallback', 'staticCallback']));
+
+ $this->assertEquals('pass', $mock->doSomething('foo', 'bar'));
+ }
+
+ public function testPublicMethodCallback()
+ {
+ $mock = $this->getMockBuilder(SomeClass::class)
+ ->setMethods(['doSomething'])
+ ->getMock();
+
+ $mock->expects($this->once())
+ ->method('doSomething')
+ ->will($this->returnCallback([new MethodCallback, 'nonStaticCallback']));
+
+ $this->assertEquals('pass', $mock->doSomething('foo', 'bar'));
+ }
+
+ public function testMockClassOnlyGeneratedOnce()
+ {
+ $mock1 = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $mock2 = $this->getMockBuilder(AnInterface::class)
+ ->getMock();
+
+ $this->assertEquals(get_class($mock1), get_class($mock2));
+ }
+
+ public function testMockClassDifferentForPartialMocks()
+ {
+ $mock1 = $this->getMockBuilder(PartialMockTestClass::class)
+ ->getMock();
+
+ $mock2 = $this->getMockBuilder(PartialMockTestClass::class)
+ ->setMethods(['doSomething'])
+ ->getMock();
+
+ $mock3 = $this->getMockBuilder(PartialMockTestClass::class)
+ ->setMethods(['doSomething'])
+ ->getMock();
+
+ $mock4 = $this->getMockBuilder(PartialMockTestClass::class)
+ ->setMethods(['doAnotherThing'])
+ ->getMock();
+
+ $mock5 = $this->getMockBuilder(PartialMockTestClass::class)
+ ->setMethods(['doAnotherThing'])
+ ->getMock();
+
+ $this->assertNotEquals(get_class($mock1), get_class($mock2));
+ $this->assertNotEquals(get_class($mock1), get_class($mock3));
+ $this->assertNotEquals(get_class($mock1), get_class($mock4));
+ $this->assertNotEquals(get_class($mock1), get_class($mock5));
+ $this->assertEquals(get_class($mock2), get_class($mock3));
+ $this->assertNotEquals(get_class($mock2), get_class($mock4));
+ $this->assertNotEquals(get_class($mock2), get_class($mock5));
+ $this->assertEquals(get_class($mock4), get_class($mock5));
+ }
+
+ public function testMockClassStoreOverrulable()
+ {
+ $mock1 = $this->getMockBuilder(PartialMockTestClass::class)
+ ->getMock();
+
+ $mock2 = $this->getMockBuilder(PartialMockTestClass::class)
+ ->setMockClassName('MyMockClassNameForPartialMockTestClass1')
+ ->getMock();
+
+ $mock3 = $this->getMockBuilder(PartialMockTestClass::class)
+ ->getMock();
+
+ $mock4 = $this->getMockBuilder(PartialMockTestClass::class)
+ ->setMethods(['doSomething'])
+ ->setMockClassName('AnotherMockClassNameForPartialMockTestClass')
+ ->getMock();
+
+ $mock5 = $this->getMockBuilder(PartialMockTestClass::class)
+ ->setMockClassName('MyMockClassNameForPartialMockTestClass2')
+ ->getMock();
+
+ $this->assertNotEquals(get_class($mock1), get_class($mock2));
+ $this->assertEquals(get_class($mock1), get_class($mock3));
+ $this->assertNotEquals(get_class($mock1), get_class($mock4));
+ $this->assertNotEquals(get_class($mock2), get_class($mock3));
+ $this->assertNotEquals(get_class($mock2), get_class($mock4));
+ $this->assertNotEquals(get_class($mock2), get_class($mock5));
+ $this->assertNotEquals(get_class($mock3), get_class($mock4));
+ $this->assertNotEquals(get_class($mock3), get_class($mock5));
+ $this->assertNotEquals(get_class($mock4), get_class($mock5));
+ }
+
+ public function testGetMockWithFixedClassNameCanProduceTheSameMockTwice()
+ {
+ $mock = $this->getMockBuilder(stdClass::class)->setMockClassName('FixedName')->getMock();
+ $mock = $this->getMockBuilder(stdClass::class)->setMockClassName('FixedName')->getMock();
+ $this->assertInstanceOf(stdClass::class, $mock);
+ }
+
+ public function testOriginalConstructorSettingConsidered()
+ {
+ $mock1 = $this->getMockBuilder(PartialMockTestClass::class)
+ ->getMock();
+
+ $mock2 = $this->getMockBuilder(PartialMockTestClass::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->assertTrue($mock1->constructorCalled);
+ $this->assertFalse($mock2->constructorCalled);
+ }
+
+ public function testOriginalCloneSettingConsidered()
+ {
+ $mock1 = $this->getMockBuilder(PartialMockTestClass::class)
+ ->getMock();
+
+ $mock2 = $this->getMockBuilder(PartialMockTestClass::class)
+ ->disableOriginalClone()
+ ->getMock();
+
+ $this->assertNotEquals(get_class($mock1), get_class($mock2));
+ }
+
+ public function testGetMockForAbstractClass()
+ {
+ $mock = $this->getMockBuilder(AbstractMockTestClass::class)
+ ->getMock();
+
+ $mock->expects($this->never())
+ ->method('doSomething');
+ }
+
+ /**
+ * @dataProvider traversableProvider
+ */
+ public function testGetMockForTraversable($type)
+ {
+ $mock = $this->getMockBuilder($type)
+ ->getMock();
+
+ $this->assertInstanceOf(Traversable::class, $mock);
+ }
+
+ public function testMultipleInterfacesCanBeMockedInSingleObject()
+ {
+ $mock = $this->getMockBuilder([AnInterface::class, AnotherInterface::class])
+ ->getMock();
+
+ $this->assertInstanceOf(AnInterface::class, $mock);
+ $this->assertInstanceOf(AnotherInterface::class, $mock);
+ }
+
+ public function testGetMockForTrait()
+ {
+ $mock = $this->getMockForTrait(AbstractTrait::class);
+
+ $mock->expects($this->never())
+ ->method('doSomething');
+
+ $parent = get_parent_class($mock);
+ $traits = class_uses($parent, false);
+
+ $this->assertContains(AbstractTrait::class, $traits);
+ }
+
+ public function testClonedMockObjectShouldStillEqualTheOriginal()
+ {
+ $a = $this->getMockBuilder(stdClass::class)
+ ->getMock();
+
+ $b = clone $a;
+
+ $this->assertEquals($a, $b);
+ }
+
+ public function testMockObjectsConstructedIndepentantlyShouldBeEqual()
+ {
+ $a = $this->getMockBuilder(stdClass::class)
+ ->getMock();
+
+ $b = $this->getMockBuilder(stdClass::class)
+ ->getMock();
+
+ $this->assertEquals($a, $b);
+ }
+
+ public function testMockObjectsConstructedIndepentantlyShouldNotBeTheSame()
+ {
+ $a = $this->getMockBuilder(stdClass::class)
+ ->getMock();
+
+ $b = $this->getMockBuilder(stdClass::class)
+ ->getMock();
+
+ $this->assertNotSame($a, $b);
+ }
+
+ public function testClonedMockObjectCanBeUsedInPlaceOfOriginalOne()
+ {
+ $x = $this->getMockBuilder(stdClass::class)
+ ->getMock();
+
+ $y = clone $x;
+
+ $mock = $this->getMockBuilder(stdClass::class)
+ ->setMethods(['foo'])
+ ->getMock();
+
+ $mock->expects($this->once())
+ ->method('foo')
+ ->with($this->equalTo($x));
+
+ $mock->foo($y);
+ }
+
+ public function testClonedMockObjectIsNotIdenticalToOriginalOne()
+ {
+ $x = $this->getMockBuilder(stdClass::class)
+ ->getMock();
+
+ $y = clone $x;
+
+ $mock = $this->getMockBuilder(stdClass::class)
+ ->setMethods(['foo'])
+ ->getMock();
+
+ $mock->expects($this->once())
+ ->method('foo')
+ ->with($this->logicalNot($this->identicalTo($x)));
+
+ $mock->foo($y);
+ }
+
+ public function testObjectMethodCallWithArgumentCloningEnabled()
+ {
+ $expectedObject = new stdClass;
+
+ $mock = $this->getMockBuilder('SomeClass')
+ ->setMethods(['doSomethingElse'])
+ ->enableArgumentCloning()
+ ->getMock();
+
+ $actualArguments = [];
+
+ $mock->expects($this->any())
+ ->method('doSomethingElse')
+ ->will(
+ $this->returnCallback(
+ function () use (&$actualArguments) {
+ $actualArguments = func_get_args();
+ }
+ )
+ );
+
+ $mock->doSomethingElse($expectedObject);
+
+ $this->assertEquals(1, count($actualArguments));
+ $this->assertEquals($expectedObject, $actualArguments[0]);
+ $this->assertNotSame($expectedObject, $actualArguments[0]);
+ }
+
+ public function testObjectMethodCallWithArgumentCloningDisabled()
+ {
+ $expectedObject = new stdClass;
+
+ $mock = $this->getMockBuilder('SomeClass')
+ ->setMethods(['doSomethingElse'])
+ ->disableArgumentCloning()
+ ->getMock();
+
+ $actualArguments = [];
+
+ $mock->expects($this->any())
+ ->method('doSomethingElse')
+ ->will(
+ $this->returnCallback(
+ function () use (&$actualArguments) {
+ $actualArguments = func_get_args();
+ }
+ )
+ );
+
+ $mock->doSomethingElse($expectedObject);
+
+ $this->assertEquals(1, count($actualArguments));
+ $this->assertSame($expectedObject, $actualArguments[0]);
+ }
+
+ public function testArgumentCloningOptionGeneratesUniqueMock()
+ {
+ $mockWithCloning = $this->getMockBuilder('SomeClass')
+ ->setMethods(['doSomethingElse'])
+ ->enableArgumentCloning()
+ ->getMock();
+
+ $mockWithoutCloning = $this->getMockBuilder('SomeClass')
+ ->setMethods(['doSomethingElse'])
+ ->disableArgumentCloning()
+ ->getMock();
+
+ $this->assertNotEquals($mockWithCloning, $mockWithoutCloning);
+ }
+
+ public function testVerificationOfMethodNameFailsWithoutParameters()
+ {
+ $mock = $this->getMockBuilder(SomeClass::class)
+ ->setMethods(['right', 'wrong'])
+ ->getMock();
+
+ $mock->expects($this->once())
+ ->method('right');
+
+ $mock->wrong();
+
+ try {
+ $mock->__phpunit_verify();
+ $this->fail('Expected exception');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertSame(
+ "Expectation failed for method name is equal to <string:right> when invoked 1 time(s).\n"
+ . "Method was expected to be called 1 times, actually called 0 times.\n",
+ $e->getMessage()
+ );
+ }
+
+ $this->resetMockObjects();
+ }
+
+ public function testVerificationOfMethodNameFailsWithParameters()
+ {
+ $mock = $this->getMockBuilder(SomeClass::class)
+ ->setMethods(['right', 'wrong'])
+ ->getMock();
+
+ $mock->expects($this->once())
+ ->method('right');
+
+ $mock->wrong();
+
+ try {
+ $mock->__phpunit_verify();
+ $this->fail('Expected exception');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertSame(
+ "Expectation failed for method name is equal to <string:right> when invoked 1 time(s).\n"
+ . "Method was expected to be called 1 times, actually called 0 times.\n",
+ $e->getMessage()
+ );
+ }
+
+ $this->resetMockObjects();
+ }
+
+ public function testVerificationOfMethodNameFailsWithWrongParameters()
+ {
+ $mock = $this->getMockBuilder(SomeClass::class)
+ ->setMethods(['right', 'wrong'])
+ ->getMock();
+
+ $mock->expects($this->once())
+ ->method('right')
+ ->with(['first', 'second']);
+
+ try {
+ $mock->right(['second']);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertSame(
+ "Expectation failed for method name is equal to <string:right> when invoked 1 time(s)\n"
+ . "Parameter 0 for invocation SomeClass::right(Array (...)) does not match expected value.\n"
+ . 'Failed asserting that two arrays are equal.',
+ $e->getMessage()
+ );
+ }
+
+ try {
+ $mock->__phpunit_verify();
+ $this->fail('Expected exception');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertSame(
+ "Expectation failed for method name is equal to <string:right> when invoked 1 time(s).\n"
+ . "Parameter 0 for invocation SomeClass::right(Array (...)) does not match expected value.\n"
+ . "Failed asserting that two arrays are equal.\n"
+ . "--- Expected\n"
+ . "+++ Actual\n"
+ . "@@ @@\n"
+ . " Array (\n"
+ . "- 0 => 'first'\n"
+ . "- 1 => 'second'\n"
+ . "+ 0 => 'second'\n"
+ . " )\n",
+ $e->getMessage()
+ );
+ }
+
+ $this->resetMockObjects();
+ }
+
+ public function testVerificationOfNeverFailsWithEmptyParameters()
+ {
+ $mock = $this->getMockBuilder(SomeClass::class)
+ ->setMethods(['right', 'wrong'])
+ ->getMock();
+
+ $mock->expects($this->never())
+ ->method('right')
+ ->with();
+
+ try {
+ $mock->right();
+ $this->fail('Expected exception');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertSame(
+ 'SomeClass::right() was not expected to be called.',
+ $e->getMessage()
+ );
+ }
+
+ $this->resetMockObjects();
+ }
+
+ public function testVerificationOfNeverFailsWithAnyParameters()
+ {
+ $mock = $this->getMockBuilder(SomeClass::class)
+ ->setMethods(['right', 'wrong'])
+ ->getMock();
+
+ $mock->expects($this->never())
+ ->method('right')
+ ->withAnyParameters();
+
+ try {
+ $mock->right();
+ $this->fail('Expected exception');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertSame(
+ 'SomeClass::right() was not expected to be called.',
+ $e->getMessage()
+ );
+ }
+
+ $this->resetMockObjects();
+ }
+
+ public function testWithAnythingInsteadOfWithAnyParameters()
+ {
+ $mock = $this->getMockBuilder(SomeClass::class)
+ ->setMethods(['right', 'wrong'])
+ ->getMock();
+
+ $mock->expects($this->once())
+ ->method('right')
+ ->with($this->anything());
+
+ try {
+ $mock->right();
+ $this->fail('Expected exception');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertSame(
+ "Expectation failed for method name is equal to <string:right> when invoked 1 time(s)\n" .
+ "Parameter count for invocation SomeClass::right() is too low.\n" .
+ 'To allow 0 or more parameters with any value, omit ->with() or use ->withAnyParameters() instead.',
+ $e->getMessage()
+ );
+ }
+
+ $this->resetMockObjects();
+ }
+
+ /**
+ * See https://github.com/sebastianbergmann/phpunit-mock-objects/issues/81
+ */
+ public function testMockArgumentsPassedByReference()
+ {
+ $foo = $this->getMockBuilder('MethodCallbackByReference')
+ ->setMethods(['bar'])
+ ->disableOriginalConstructor()
+ ->disableArgumentCloning()
+ ->getMock();
+
+ $foo->expects($this->any())
+ ->method('bar')
+ ->will($this->returnCallback([$foo, 'callback']));
+
+ $a = $b = $c = 0;
+
+ $foo->bar($a, $b, $c);
+
+ $this->assertEquals(1, $b);
+ }
+
+ /**
+ * See https://github.com/sebastianbergmann/phpunit-mock-objects/issues/81
+ */
+ public function testMockArgumentsPassedByReference2()
+ {
+ $foo = $this->getMockBuilder('MethodCallbackByReference')
+ ->disableOriginalConstructor()
+ ->disableArgumentCloning()
+ ->getMock();
+
+ $foo->expects($this->any())
+ ->method('bar')
+ ->will($this->returnCallback(
+ function (&$a, &$b, $c) {
+ $b = 1;
+ }
+ ));
+
+ $a = $b = $c = 0;
+
+ $foo->bar($a, $b, $c);
+
+ $this->assertEquals(1, $b);
+ }
+
+ /**
+ * @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/116
+ */
+ public function testMockArgumentsPassedByReference3()
+ {
+ $foo = $this->getMockBuilder('MethodCallbackByReference')
+ ->setMethods(['bar'])
+ ->disableOriginalConstructor()
+ ->disableArgumentCloning()
+ ->getMock();
+
+ $a = new stdClass;
+ $b = $c = 0;
+
+ $foo->expects($this->any())
+ ->method('bar')
+ ->with($a, $b, $c)
+ ->will($this->returnCallback([$foo, 'callback']));
+
+ $this->assertNull($foo->bar($a, $b, $c));
+ }
+
+ /**
+ * @see https://github.com/sebastianbergmann/phpunit/issues/796
+ */
+ public function testMockArgumentsPassedByReference4()
+ {
+ $foo = $this->getMockBuilder('MethodCallbackByReference')
+ ->setMethods(['bar'])
+ ->disableOriginalConstructor()
+ ->disableArgumentCloning()
+ ->getMock();
+
+ $a = new stdClass;
+ $b = $c = 0;
+
+ $foo->expects($this->any())
+ ->method('bar')
+ ->with($this->isInstanceOf(stdClass::class), $b, $c)
+ ->will($this->returnCallback([$foo, 'callback']));
+
+ $this->assertNull($foo->bar($a, $b, $c));
+ }
+
+ /**
+ * @requires extension soap
+ */
+ public function testCreateMockFromWsdl()
+ {
+ $mock = $this->getMockFromWsdl(__DIR__ . '/_fixture/GoogleSearch.wsdl', 'WsdlMock');
+
+ $this->assertStringStartsWith(
+ 'Mock_WsdlMock_',
+ get_class($mock)
+ );
+ }
+
+ /**
+ * @requires extension soap
+ */
+ public function testCreateNamespacedMockFromWsdl()
+ {
+ $mock = $this->getMockFromWsdl(__DIR__ . '/_fixture/GoogleSearch.wsdl', 'My\\Space\\WsdlMock');
+
+ $this->assertStringStartsWith(
+ 'Mock_WsdlMock_',
+ get_class($mock)
+ );
+ }
+
+ /**
+ * @requires extension soap
+ */
+ public function testCreateTwoMocksOfOneWsdlFile()
+ {
+ $a = $this->getMockFromWsdl(__DIR__ . '/_fixture/GoogleSearch.wsdl');
+ $b = $this->getMockFromWsdl(__DIR__ . '/_fixture/GoogleSearch.wsdl');
+
+ $this->assertStringStartsWith('Mock_GoogleSearch_', get_class($a));
+ $this->assertEquals(get_class($a), get_class($b));
+ }
+
+ /**
+ * @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/156
+ * @ticket 156
+ */
+ public function testInterfaceWithStaticMethodCanBeStubbed()
+ {
+ $this->assertInstanceOf(
+ InterfaceWithStaticMethod::class,
+ $this->getMockBuilder(InterfaceWithStaticMethod::class)->getMock()
+ );
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_MockObject_BadMethodCallException
+ */
+ public function testInvokingStubbedStaticMethodRaisesException()
+ {
+ $mock = $this->getMockBuilder(ClassWithStaticMethod::class)->getMock();
+
+ $mock->staticMethod();
+ }
+
+ /**
+ * @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/171
+ * @ticket 171
+ */
+ public function testStubForClassThatImplementsSerializableCanBeCreatedWithoutInvokingTheConstructor()
+ {
+ $this->assertInstanceOf(
+ ClassThatImplementsSerializable::class,
+ $this->getMockBuilder(ClassThatImplementsSerializable::class)
+ ->disableOriginalConstructor()
+ ->getMock()
+ );
+ }
+
+ public function testGetMockForClassWithSelfTypeHint()
+ {
+ $this->assertInstanceOf(
+ ClassWithSelfTypeHint::class,
+ $this->getMockBuilder(ClassWithSelfTypeHint::class)->getMock()
+ );
+ }
+
+ private function resetMockObjects()
+ {
+ $refl = new ReflectionObject($this);
+ $refl = $refl->getParentClass();
+ $prop = $refl->getProperty('mockObjects');
+ $prop->setAccessible(true);
+ $prop->setValue($this, []);
+ }
+
+ public function testStringableClassDoesNotThrow()
+ {
+ $mock = $this->getMockBuilder(StringableClass::class)->getMock();
+
+ $this->assertInternalType('string', (string) $mock);
+ }
+
+ public function testStringableClassCanBeMocked()
+ {
+ $mock = $this->getMockBuilder(StringableClass::class)->getMock();
+
+ $mock->method('__toString')->willReturn('foo');
+
+ $this->assertSame('foo', (string) $mock);
+ }
+
+ public function traversableProvider()
+ {
+ return [
+ ['Traversable'],
+ ['\Traversable'],
+ ['TraversableMockTestInterface'],
+ [['Traversable']],
+ [['Iterator','Traversable']],
+ [['\Iterator','\Traversable']]
+ ];
+ }
+
+ public function testParameterCallbackConstraintOnlyEvaluatedOnce()
+ {
+ $mock = $this->getMockBuilder(Foo::class)->setMethods(['bar'])->getMock();
+ $expectedNumberOfCalls = 1;
+ $callCount = 0;
+
+ $mock->expects($this->exactly($expectedNumberOfCalls))->method('bar')
+ ->with($this->callback(function ($argument) use (&$callCount) {
+ return $argument === 'call_' . $callCount++;
+ }));
+
+ for ($i = 0; $i < $expectedNumberOfCalls; $i++) {
+ $mock->bar('call_' . $i);
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/ProxyObjectTest.php b/vendor/phpunit/phpunit-mock-objects/tests/ProxyObjectTest.php
new file mode 100644
index 0000000..87a19fd
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/ProxyObjectTest.php
@@ -0,0 +1,39 @@
+<?php
+/*
+ * This file is part of the PHPUnit_MockObject package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Framework_ProxyObjectTest extends PHPUnit_Framework_TestCase
+{
+ public function testMockedMethodIsProxiedToOriginalMethod()
+ {
+ $proxy = $this->getMockBuilder(Bar::class)
+ ->enableProxyingToOriginalMethods()
+ ->getMock();
+
+ $proxy->expects($this->once())
+ ->method('doSomethingElse');
+
+ $foo = new Foo;
+
+ $this->assertEquals('result', $foo->doSomething($proxy));
+ }
+
+ public function testMockedMethodWithReferenceIsProxiedToOriginalMethod()
+ {
+ $proxy = $this->getMockBuilder(MethodCallbackByReference::class)
+ ->enableProxyingToOriginalMethods()
+ ->getMock();
+
+ $a = $b = $c = 0;
+
+ $proxy->callback($a, $b, $c);
+
+ $this->assertEquals(1, $b);
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AbstractMockTestClass.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AbstractMockTestClass.php
new file mode 100644
index 0000000..1f2640c
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AbstractMockTestClass.php
@@ -0,0 +1,10 @@
+<?php
+abstract class AbstractMockTestClass implements MockTestInterface
+{
+ abstract public function doSomething();
+
+ public function returnAnything()
+ {
+ return 1;
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AbstractTrait.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AbstractTrait.php
new file mode 100644
index 0000000..52aac64
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AbstractTrait.php
@@ -0,0 +1,15 @@
+<?php
+trait AbstractTrait
+{
+ abstract public function doSomething();
+
+ public function mockableMethod()
+ {
+ return true;
+ }
+
+ public function anotherMockableMethod()
+ {
+ return true;
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AnInterface.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AnInterface.php
new file mode 100644
index 0000000..5b7d4cc
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AnInterface.php
@@ -0,0 +1,5 @@
+<?php
+interface AnInterface
+{
+ public function doSomething();
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AnInterfaceWithReturnType.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AnInterfaceWithReturnType.php
new file mode 100644
index 0000000..150857d
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AnInterfaceWithReturnType.php
@@ -0,0 +1,5 @@
+<?php
+interface AnInterfaceWithReturnType
+{
+ public function returnAnArray(): array;
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AnotherInterface.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AnotherInterface.php
new file mode 100644
index 0000000..62bff0a
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/AnotherInterface.php
@@ -0,0 +1,5 @@
+<?php
+interface AnotherInterface
+{
+ public function doSomethingElse();
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/Bar.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/Bar.php
new file mode 100644
index 0000000..4a4d165
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/Bar.php
@@ -0,0 +1,8 @@
+<?php
+class Bar
+{
+ public function doSomethingElse()
+ {
+ return 'result';
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/ClassThatImplementsSerializable.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/ClassThatImplementsSerializable.php
new file mode 100644
index 0000000..87576ca
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/ClassThatImplementsSerializable.php
@@ -0,0 +1,15 @@
+<?php
+class ClassThatImplementsSerializable implements Serializable
+{
+ public function serialize()
+ {
+ return get_object_vars($this);
+ }
+
+ public function unserialize($serialized)
+ {
+ foreach (unserialize($serialized) as $key => $value) {
+ $this->{$key} = $value;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/ClassWithSelfTypeHint.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/ClassWithSelfTypeHint.php
new file mode 100644
index 0000000..931a13b
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/ClassWithSelfTypeHint.php
@@ -0,0 +1,7 @@
+<?php
+class ClassWithSelfTypeHint
+{
+ public function foo(self $foo)
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/ClassWithStaticMethod.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/ClassWithStaticMethod.php
new file mode 100644
index 0000000..0c13c12
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/ClassWithStaticMethod.php
@@ -0,0 +1,7 @@
+<?php
+class ClassWithStaticMethod
+{
+ public static function staticMethod()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/Foo.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/Foo.php
new file mode 100644
index 0000000..16a9ed7
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/Foo.php
@@ -0,0 +1,8 @@
+<?php
+class Foo
+{
+ public function doSomething(Bar $bar)
+ {
+ return $bar->doSomethingElse();
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/FunctionCallback.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/FunctionCallback.php
new file mode 100644
index 0000000..2353c81
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/FunctionCallback.php
@@ -0,0 +1,9 @@
+<?php
+function functionCallback()
+{
+ $args = func_get_args();
+
+ if ($args == ['foo', 'bar']) {
+ return 'pass';
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/GoogleSearch.wsdl b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/GoogleSearch.wsdl
new file mode 100644
index 0000000..e448501
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/GoogleSearch.wsdl
@@ -0,0 +1,198 @@
+<?xml version="1.0"?>
+
+<!-- WSDL description of the Google Web APIs.
+ The Google Web APIs are in beta release. All interfaces are subject to
+ change as we refine and extend our APIs. Please see the terms of use
+ for more information. -->
+
+<!-- Revision 2002-08-16 -->
+
+<definitions name="GoogleSearch"
+ targetNamespace="urn:GoogleSearch"
+ xmlns:typens="urn:GoogleSearch"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns="http://schemas.xmlsoap.org/wsdl/">
+
+ <!-- Types for search - result elements, directory categories -->
+
+ <types>
+ <xsd:schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="urn:GoogleSearch">
+
+ <xsd:complexType name="GoogleSearchResult">
+ <xsd:all>
+ <xsd:element name="documentFiltering" type="xsd:boolean"/>
+ <xsd:element name="searchComments" type="xsd:string"/>
+ <xsd:element name="estimatedTotalResultsCount" type="xsd:int"/>
+ <xsd:element name="estimateIsExact" type="xsd:boolean"/>
+ <xsd:element name="resultElements" type="typens:ResultElementArray"/>
+ <xsd:element name="searchQuery" type="xsd:string"/>
+ <xsd:element name="startIndex" type="xsd:int"/>
+ <xsd:element name="endIndex" type="xsd:int"/>
+ <xsd:element name="searchTips" type="xsd:string"/>
+ <xsd:element name="directoryCategories" type="typens:DirectoryCategoryArray"/>
+ <xsd:element name="searchTime" type="xsd:double"/>
+ </xsd:all>
+ </xsd:complexType>
+
+ <xsd:complexType name="ResultElement">
+ <xsd:all>
+ <xsd:element name="summary" type="xsd:string"/>
+ <xsd:element name="URL" type="xsd:string"/>
+ <xsd:element name="snippet" type="xsd:string"/>
+ <xsd:element name="title" type="xsd:string"/>
+ <xsd:element name="cachedSize" type="xsd:string"/>
+ <xsd:element name="relatedInformationPresent" type="xsd:boolean"/>
+ <xsd:element name="hostName" type="xsd:string"/>
+ <xsd:element name="directoryCategory" type="typens:DirectoryCategory"/>
+ <xsd:element name="directoryTitle" type="xsd:string"/>
+ </xsd:all>
+ </xsd:complexType>
+
+ <xsd:complexType name="ResultElementArray">
+ <xsd:complexContent>
+ <xsd:restriction base="soapenc:Array">
+ <xsd:attribute ref="soapenc:arrayType" wsdl:arrayType="typens:ResultElement[]"/>
+ </xsd:restriction>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="DirectoryCategoryArray">
+ <xsd:complexContent>
+ <xsd:restriction base="soapenc:Array">
+ <xsd:attribute ref="soapenc:arrayType" wsdl:arrayType="typens:DirectoryCategory[]"/>
+ </xsd:restriction>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="DirectoryCategory">
+ <xsd:all>
+ <xsd:element name="fullViewableName" type="xsd:string"/>
+ <xsd:element name="specialEncoding" type="xsd:string"/>
+ </xsd:all>
+ </xsd:complexType>
+
+ </xsd:schema>
+ </types>
+
+ <!-- Messages for Google Web APIs - cached page, search, spelling. -->
+
+ <message name="doGetCachedPage">
+ <part name="key" type="xsd:string"/>
+ <part name="url" type="xsd:string"/>
+ </message>
+
+ <message name="doGetCachedPageResponse">
+ <part name="return" type="xsd:base64Binary"/>
+ </message>
+
+ <message name="doSpellingSuggestion">
+ <part name="key" type="xsd:string"/>
+ <part name="phrase" type="xsd:string"/>
+ </message>
+
+ <message name="doSpellingSuggestionResponse">
+ <part name="return" type="xsd:string"/>
+ </message>
+
+ <!-- note, ie and oe are ignored by server; all traffic is UTF-8. -->
+
+ <message name="doGoogleSearch">
+ <part name="key" type="xsd:string"/>
+ <part name="q" type="xsd:string"/>
+ <part name="start" type="xsd:int"/>
+ <part name="maxResults" type="xsd:int"/>
+ <part name="filter" type="xsd:boolean"/>
+ <part name="restrict" type="xsd:string"/>
+ <part name="safeSearch" type="xsd:boolean"/>
+ <part name="lr" type="xsd:string"/>
+ <part name="ie" type="xsd:string"/>
+ <part name="oe" type="xsd:string"/>
+ </message>
+
+ <message name="doGoogleSearchResponse">
+ <part name="return" type="typens:GoogleSearchResult"/>
+ </message>
+
+ <!-- Port for Google Web APIs, "GoogleSearch" -->
+
+ <portType name="GoogleSearchPort">
+
+ <operation name="doGetCachedPage">
+ <input message="typens:doGetCachedPage"/>
+ <output message="typens:doGetCachedPageResponse"/>
+ </operation>
+
+ <operation name="doSpellingSuggestion">
+ <input message="typens:doSpellingSuggestion"/>
+ <output message="typens:doSpellingSuggestionResponse"/>
+ </operation>
+
+ <operation name="doGoogleSearch">
+ <input message="typens:doGoogleSearch"/>
+ <output message="typens:doGoogleSearchResponse"/>
+ </operation>
+
+ </portType>
+
+
+ <!-- Binding for Google Web APIs - RPC, SOAP over HTTP -->
+
+ <binding name="GoogleSearchBinding" type="typens:GoogleSearchPort">
+ <soap:binding style="rpc"
+ transport="http://schemas.xmlsoap.org/soap/http"/>
+
+ <operation name="doGetCachedPage">
+ <soap:operation soapAction="urn:GoogleSearchAction"/>
+ <input>
+ <soap:body use="encoded"
+ namespace="urn:GoogleSearch"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </input>
+ <output>
+ <soap:body use="encoded"
+ namespace="urn:GoogleSearch"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </output>
+ </operation>
+
+ <operation name="doSpellingSuggestion">
+ <soap:operation soapAction="urn:GoogleSearchAction"/>
+ <input>
+ <soap:body use="encoded"
+ namespace="urn:GoogleSearch"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </input>
+ <output>
+ <soap:body use="encoded"
+ namespace="urn:GoogleSearch"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </output>
+ </operation>
+
+ <operation name="doGoogleSearch">
+ <soap:operation soapAction="urn:GoogleSearchAction"/>
+ <input>
+ <soap:body use="encoded"
+ namespace="urn:GoogleSearch"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </input>
+ <output>
+ <soap:body use="encoded"
+ namespace="urn:GoogleSearch"
+ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </output>
+ </operation>
+ </binding>
+
+ <!-- Endpoint for Google Web APIs -->
+ <service name="GoogleSearchService">
+ <port name="GoogleSearchPort" binding="typens:GoogleSearchBinding">
+ <soap:address location="http://api.google.com/search/beta2"/>
+ </port>
+ </service>
+
+</definitions>
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/InterfaceWithSemiReservedMethodName.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/InterfaceWithSemiReservedMethodName.php
new file mode 100644
index 0000000..bcef294
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/InterfaceWithSemiReservedMethodName.php
@@ -0,0 +1,5 @@
+<?php
+interface InterfaceWithSemiReservedMethodName
+{
+ public function unset();
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/InterfaceWithStaticMethod.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/InterfaceWithStaticMethod.php
new file mode 100644
index 0000000..dee5f4f
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/InterfaceWithStaticMethod.php
@@ -0,0 +1,5 @@
+<?php
+interface InterfaceWithStaticMethod
+{
+ public static function staticMethod();
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/MethodCallback.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/MethodCallback.php
new file mode 100644
index 0000000..d8cba53
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/MethodCallback.php
@@ -0,0 +1,21 @@
+<?php
+class MethodCallback
+{
+ public static function staticCallback()
+ {
+ $args = func_get_args();
+
+ if ($args == ['foo', 'bar']) {
+ return 'pass';
+ }
+ }
+
+ public function nonStaticCallback()
+ {
+ $args = func_get_args();
+
+ if ($args == ['foo', 'bar']) {
+ return 'pass';
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/MethodCallbackByReference.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/MethodCallbackByReference.php
new file mode 100644
index 0000000..ef26f3e
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/MethodCallbackByReference.php
@@ -0,0 +1,13 @@
+<?php
+class MethodCallbackByReference
+{
+ public function bar(&$a, &$b, $c)
+ {
+ Legacy::bar($a, $b, $c);
+ }
+
+ public function callback(&$a, &$b, $c)
+ {
+ $b = 1;
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/MockTestInterface.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/MockTestInterface.php
new file mode 100644
index 0000000..a5f8f5f
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/MockTestInterface.php
@@ -0,0 +1,6 @@
+<?php
+interface MockTestInterface
+{
+ public function returnAnything();
+ public function returnAnythingElse();
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/Mockable.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/Mockable.php
new file mode 100644
index 0000000..a7b1825
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/Mockable.php
@@ -0,0 +1,28 @@
+<?php
+class Mockable
+{
+ public $constructorArgs;
+ public $cloned;
+
+ public function __construct($arg1 = null, $arg2 = null)
+ {
+ $this->constructorArgs = [$arg1, $arg2];
+ }
+
+ public function mockableMethod()
+ {
+ // something different from NULL
+ return true;
+ }
+
+ public function anotherMockableMethod()
+ {
+ // something different from NULL
+ return true;
+ }
+
+ public function __clone()
+ {
+ $this->cloned = true;
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/PartialMockTestClass.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/PartialMockTestClass.php
new file mode 100644
index 0000000..0609993
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/PartialMockTestClass.php
@@ -0,0 +1,18 @@
+<?php
+class PartialMockTestClass
+{
+ public $constructorCalled = false;
+
+ public function __construct()
+ {
+ $this->constructorCalled = true;
+ }
+
+ public function doSomething()
+ {
+ }
+
+ public function doAnotherThing()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/SingletonClass.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/SingletonClass.php
new file mode 100644
index 0000000..e000266
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/SingletonClass.php
@@ -0,0 +1,28 @@
+<?php
+
+class SingletonClass
+{
+ public static function getInstance()
+ {
+ }
+
+ public function doSomething()
+ {
+ }
+
+ protected function __construct()
+ {
+ }
+
+ final private function __sleep()
+ {
+ }
+
+ final private function __wakeup()
+ {
+ }
+
+ final private function __clone()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/SomeClass.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/SomeClass.php
new file mode 100644
index 0000000..a6e5f4c
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/SomeClass.php
@@ -0,0 +1,13 @@
+<?php
+class SomeClass
+{
+ public function doSomething($a, $b)
+ {
+ return;
+ }
+
+ public function doSomethingElse($c)
+ {
+ return;
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/StaticMockTestClass.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/StaticMockTestClass.php
new file mode 100644
index 0000000..ac467c9
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/StaticMockTestClass.php
@@ -0,0 +1,12 @@
+<?php
+class StaticMockTestClass
+{
+ public static function doSomething()
+ {
+ }
+
+ public static function doSomethingElse()
+ {
+ return static::doSomething();
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/StringableClass.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/StringableClass.php
new file mode 100644
index 0000000..0b6d62d
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/StringableClass.php
@@ -0,0 +1,8 @@
+<?php
+class StringableClass
+{
+ public function __toString()
+ {
+ return '12345';
+ }
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/_fixture/TraversableMockTestInterface.php b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/TraversableMockTestInterface.php
new file mode 100644
index 0000000..3467cce
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/_fixture/TraversableMockTestInterface.php
@@ -0,0 +1,4 @@
+<?php
+interface TraversableMockTestInterface extends Traversable
+{
+}
diff --git a/vendor/phpunit/phpunit-mock-objects/tests/bootstrap.php b/vendor/phpunit/phpunit-mock-objects/tests/bootstrap.php
new file mode 100644
index 0000000..6575b39
--- /dev/null
+++ b/vendor/phpunit/phpunit-mock-objects/tests/bootstrap.php
@@ -0,0 +1,3 @@
+<?php
+require __DIR__ . '/_fixture/FunctionCallback.php';
+require __DIR__ . '/../vendor/autoload.php';
diff --git a/vendor/phpunit/phpunit/.gitattributes b/vendor/phpunit/phpunit/.gitattributes
new file mode 100644
index 0000000..278ace4
--- /dev/null
+++ b/vendor/phpunit/phpunit/.gitattributes
@@ -0,0 +1,4 @@
+/build export-ignore
+
+*.php diff=php
+
diff --git a/vendor/phpunit/phpunit/.github/CODE_OF_CONDUCT.md b/vendor/phpunit/phpunit/.github/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..d39d536
--- /dev/null
+++ b/vendor/phpunit/phpunit/.github/CODE_OF_CONDUCT.md
@@ -0,0 +1,28 @@
+# Contributor Code of Conduct
+
+As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
+
+We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery
+* Personal attacks
+* Trolling or insulting/derogatory comments
+* Public or private harassment
+* Publishing other's private information, such as physical or electronic
+ addresses, without explicit permission
+* Other unethical or unprofessional conduct
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project maintainer at sebastian@phpunit.de. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. Maintainers are obligated to maintain confidentiality with regard to the reporter of an incident.
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.3.0, available at [http://contributor-covenant.org/version/1/3/0/][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/3/0/
diff --git a/vendor/phpunit/phpunit/.github/CONTRIBUTING.md b/vendor/phpunit/phpunit/.github/CONTRIBUTING.md
new file mode 100644
index 0000000..9010bc4
--- /dev/null
+++ b/vendor/phpunit/phpunit/.github/CONTRIBUTING.md
@@ -0,0 +1,72 @@
+# Contributing to PHPUnit
+
+## Contributor Code of Conduct
+
+Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms.
+
+## Workflow
+
+* Fork the project.
+* Make your bug fix or feature addition.
+* Add tests for it. This is important so we don't break it in a future version unintentionally.
+* Send a pull request. Bonus points for topic branches.
+
+Please make sure that you have [set up your user name and email address](http://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup) for use with Git. Strings such as `silly nick name <root@localhost>` look really stupid in the commit history of a project.
+
+Pull requests for bug fixes must be based on the current stable branch whereas pull requests for new features must be based on the `master` branch.
+
+We are trying to keep backwards compatibility breaks in PHPUnit to an absolute minimum. Please take this into account when proposing changes.
+
+Due to time constraints, we are not always able to respond as quickly as we would like. Please do not take delays personal and feel free to remind us if you feel that we forgot to respond.
+
+## Coding Guidelines
+
+This project comes with a configuration file for [php-cs-fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) (`.php_cs`) that you can use to (re)format your sourcecode for compliance with this project's coding guidelines:
+
+```bash
+$ wget http://cs.sensiolabs.org/download/php-cs-fixer-v2.phar -O php-cs-fixer.phar
+
+$ php php-cs-fixer.phar fix
+```
+
+## Using PHPUnit from a Git checkout
+
+The following commands can be used to perform the initial checkout of PHPUnit:
+
+```bash
+$ git clone git://github.com/sebastianbergmann/phpunit.git
+
+$ cd phpunit
+```
+
+Retrieve PHPUnit's dependencies using [Composer](https://getcomposer.org/):
+
+```bash
+$ composer install
+```
+
+The `phpunit` script can be used to invoke the PHPUnit test runner:
+
+```bash
+$ ./phpunit --version
+```
+
+## Running PHPUnit's own test suite
+
+After following the steps shown above, PHPUnit's own test suite is run like this:
+
+```bash
+$ ./phpunit
+```
+
+## Reporting issues
+
+Please use the most specific issue tracker to search for existing tickets and to open new tickets:
+
+* [General problems](https://github.com/sebastianbergmann/phpunit/issues)
+* [Code Coverage](https://github.com/sebastianbergmann/php-code-coverage/issues)
+* [Stub and Mock Objects](https://github.com/sebastianbergmann/phpunit-mock-objects/issues)
+* [DbUnit](https://github.com/sebastianbergmann/dbunit/issues)
+* [Documentation](https://github.com/sebastianbergmann/phpunit-documentation/issues)
+* [Website](https://github.com/sebastianbergmann/phpunit-website/issues)
+
diff --git a/vendor/phpunit/phpunit/.github/ISSUE_TEMPLATE.md b/vendor/phpunit/phpunit/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 0000000..ad1dc39
--- /dev/null
+++ b/vendor/phpunit/phpunit/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,15 @@
+| Q | A
+| --------------------| ---------------
+| PHPUnit version | x.y.z
+| PHP version | x.y.z
+| Installation Method | Composer / PHAR
+
+<!--
+- Please fill in this template according to your issue.
+- Please keep the table shown above at the top of your issue.
+- Please include the output of "composer info | sort" if you installed PHPUnit using Composer.
+- Please post code as text (using proper markup). Do not post screenshots of code.
+- Visit https://phpunit.de/support.html if you are looking for support.
+- Otherwise, replace this comment by the description of your issue.
+-->
+
diff --git a/vendor/phpunit/phpunit/.gitignore b/vendor/phpunit/phpunit/.gitignore
new file mode 100644
index 0000000..bf33323
--- /dev/null
+++ b/vendor/phpunit/phpunit/.gitignore
@@ -0,0 +1,20 @@
+/.ant_targets
+/.idea
+/.php_cs
+/.php_cs.cache
+/build/documentation
+/build/logfiles
+/build/phar
+/build/phpdox
+/build/*.phar
+/build/*.phar.asc
+/build/binary-phar-autoload.php
+/cache.properties
+/composer.lock
+/tests/TextUI/*.diff
+/tests/TextUI/*.exp
+/tests/TextUI/*.log
+/tests/TextUI/*.out
+/tests/TextUI/*.php
+/vendor
+
diff --git a/vendor/phpunit/phpunit/.php_cs.dist b/vendor/phpunit/phpunit/.php_cs.dist
new file mode 100644
index 0000000..7dbee6e
--- /dev/null
+++ b/vendor/phpunit/phpunit/.php_cs.dist
@@ -0,0 +1,81 @@
+<?php
+$header = <<<'EOF'
+This file is part of PHPUnit.
+
+(c) Sebastian Bergmann <sebastian@phpunit.de>
+
+For the full copyright and license information, please view the LICENSE
+file that was distributed with this source code.
+EOF;
+
+return PhpCsFixer\Config::create()
+ ->setRiskyAllowed(true)
+ ->setRules(
+ [
+ 'array_syntax' => ['syntax' => 'short'],
+ 'binary_operator_spaces' => [
+ 'align_double_arrow' => true,
+ 'align_equals' => true
+ ],
+ 'blank_line_after_namespace' => true,
+ 'blank_line_before_return' => true,
+ 'braces' => true,
+ 'cast_spaces' => true,
+ 'concat_space' => ['spacing' => 'one'],
+ 'elseif' => true,
+ 'encoding' => true,
+ 'full_opening_tag' => true,
+ 'function_declaration' => true,
+ 'header_comment' => ['header' => $header, 'separate' => 'none'],
+ 'indentation_type' => true,
+ 'line_ending' => true,
+ 'lowercase_constants' => true,
+ 'lowercase_keywords' => true,
+ 'method_argument_space' => true,
+ 'no_alias_functions' => true,
+ 'no_blank_lines_after_class_opening' => true,
+ 'no_blank_lines_after_phpdoc' => true,
+ 'no_closing_tag' => true,
+ 'no_empty_phpdoc' => true,
+ 'no_empty_statement' => true,
+ 'no_extra_consecutive_blank_lines' => true,
+ 'no_leading_namespace_whitespace' => true,
+ 'no_singleline_whitespace_before_semicolons' => true,
+ 'no_spaces_after_function_name' => true,
+ 'no_spaces_inside_parenthesis' => true,
+ 'no_trailing_comma_in_list_call' => true,
+ 'no_trailing_whitespace' => true,
+ 'no_unused_imports' => true,
+ 'no_whitespace_in_blank_line' => true,
+ 'phpdoc_align' => true,
+ 'phpdoc_indent' => true,
+ 'phpdoc_no_access' => true,
+ 'phpdoc_no_empty_return' => true,
+ 'phpdoc_no_package' => true,
+ 'phpdoc_scalar' => true,
+ 'phpdoc_separation' => true,
+ 'phpdoc_to_comment' => true,
+ 'phpdoc_trim' => true,
+ 'phpdoc_types' => true,
+ 'phpdoc_var_without_name' => true,
+ 'self_accessor' => true,
+ 'simplified_null_return' => true,
+ 'single_blank_line_at_eof' => true,
+ 'single_import_per_statement' => true,
+ 'single_line_after_imports' => true,
+ 'single_quote' => true,
+ 'ternary_operator_spaces' => true,
+ 'trim_array_spaces' => true,
+ 'visibility_required' => true,
+ ]
+ )
+ ->setFinder(
+ PhpCsFixer\Finder::create()
+ ->files()
+ ->in(__DIR__ . '/build')
+ ->in(__DIR__ . '/src')
+ ->in(__DIR__ . '/tests/Framework')
+ ->in(__DIR__ . '/tests/Runner')
+ ->in(__DIR__ . '/tests/Util')
+ ->name('*.php')
+ );
diff --git a/vendor/phpunit/phpunit/.stickler.yml b/vendor/phpunit/phpunit/.stickler.yml
new file mode 100644
index 0000000..f4afbc0
--- /dev/null
+++ b/vendor/phpunit/phpunit/.stickler.yml
@@ -0,0 +1,3 @@
+linters:
+ phpcs:
+ standard: 'build/phpcs.xml'
diff --git a/vendor/phpunit/phpunit/.travis.yml b/vendor/phpunit/phpunit/.travis.yml
new file mode 100644
index 0000000..29957e7
--- /dev/null
+++ b/vendor/phpunit/phpunit/.travis.yml
@@ -0,0 +1,55 @@
+language: php
+
+sudo: false
+
+addons:
+ apt:
+ packages:
+ - libxml2-utils
+
+php:
+ - 5.6
+ - 7.0
+ - 7.1
+ - 7.2
+ - master
+
+matrix:
+ allow_failures:
+ - php: 7.2
+ - php: master
+ fast_finish: true
+
+env:
+ matrix:
+ - DEPENDENCIES="high"
+ - DEPENDENCIES="low"
+ global:
+ - DEFAULT_COMPOSER_FLAGS="--no-interaction --no-ansi --no-progress --no-suggest"
+
+before_install:
+ - composer self-update
+ - composer clear-cache
+
+install:
+ - if [[ "$DEPENDENCIES" = 'high' ]]; then travis_retry composer update $DEFAULT_COMPOSER_FLAGS; fi
+ - if [[ "$DEPENDENCIES" = 'low' ]]; then travis_retry composer update $DEFAULT_COMPOSER_FLAGS --prefer-lowest; fi
+
+before_script:
+ - echo 'zend.assertions=1' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
+ - echo 'assert.exception=On' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
+
+script:
+ - ./phpunit --coverage-clover=coverage.xml
+ - ./phpunit --configuration ./build/travis-ci-fail.xml > /dev/null; if [ $? -eq 0 ]; then echo "SHOULD FAIL"; false; else echo "fail checked"; fi;
+ - xmllint --noout --schema phpunit.xsd phpunit.xml
+ - xmllint --noout --schema phpunit.xsd tests/_files/configuration.xml
+ - xmllint --noout --schema phpunit.xsd tests/_files/configuration_empty.xml
+ - xmllint --noout --schema phpunit.xsd tests/_files/configuration_xinclude.xml -xinclude
+
+after_success:
+ - bash <(curl -s https://codecov.io/bash)
+
+notifications:
+ email: false
+
diff --git a/vendor/phpunit/phpunit/ChangeLog-5.7.md b/vendor/phpunit/phpunit/ChangeLog-5.7.md
new file mode 100644
index 0000000..c8c7787
--- /dev/null
+++ b/vendor/phpunit/phpunit/ChangeLog-5.7.md
@@ -0,0 +1,242 @@
+# Changes in PHPUnit 5.7
+
+All notable changes of the PHPUnit 5.7 release series are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+
+## [5.7.27] - 2018-02-01
+
+### Fixed
+
+* Fixed [#2236](https://github.com/sebastianbergmann/phpunit/issues/2236): Exceptions in `tearDown()` do not affect `getStatus()`
+* Fixed [#2950](https://github.com/sebastianbergmann/phpunit/issues/2950): Class extending `PHPUnit\Framework\TestSuite` does not extend `PHPUnit\FrameworkTestCase`
+* Fixed [#2972](https://github.com/sebastianbergmann/phpunit/issues/2972): PHPUnit crashes when test suite contains both `.phpt` files and unconventionally named tests
+
+## [5.7.26] - 2017-12-17
+
+### Fixed
+
+* Fixed [#2472](https://github.com/sebastianbergmann/phpunit/issues/2472): `PHPUnit\Util\Getopt` uses deprecated `each()` function
+* Fixed [#2833](https://github.com/sebastianbergmann/phpunit/issues/2833): Test class loaded during data provider execution is not discovered
+* Fixed [#2922](https://github.com/sebastianbergmann/phpunit/issues/2922): Test class is not discovered when there is a test class with `@group` and provider throwing exception in it, tests are run with `--exclude-group` for that group, there is another class called later (after the class from above), and the name of that another class does not match its filename
+
+## [5.7.25] - 2017-11-14
+
+### Fixed
+
+* Fixed [#2859](https://github.com/sebastianbergmann/phpunit/issues/2859): Regression caused by fix for [#2833](https://github.com/sebastianbergmann/phpunit/issues/2833)
+
+## [5.7.24] - 2017-11-14
+
+### Fixed
+
+* Fixed [#2833](https://github.com/sebastianbergmann/phpunit/issues/2833): Test class loaded during data provider execution is not discovered
+
+## [5.7.23] - 2017-10-15
+
+### Fixed
+
+* Fixed [#2731](https://github.com/sebastianbergmann/phpunit/issues/2731): Empty exception message cannot be expected
+
+## [5.7.22] - 2017-09-24
+
+### Fixed
+
+* Fixed [#2769](https://github.com/sebastianbergmann/phpunit/issues/2769): Usage of `setUseErrorHandler()` produces `Undefined variable` error
+
+## [5.7.21] - 2017-06-21
+
+### Added
+
+* Added `PHPUnit\Framework\AssertionFailedError`, `PHPUnit\Framework\Test`, and `PHPUnit\Framework\TestSuite` to the forward compatibility layer for PHPUnit 6
+
+### Fixed
+
+* Fixed [#2705](https://github.com/sebastianbergmann/phpunit/issues/2705): `stderr` parameter in `phpunit.xml` always considered `true`
+
+## [5.7.20] - 2017-05-22
+
+### Fixed
+
+* Fixed [#2563](https://github.com/sebastianbergmann/phpunit/pull/2563): `phpunit --version` does not display version when running unsupported PHP
+
+## [5.7.19] - 2017-04-03
+
+### Fixed
+
+* Fixed [#2638](https://github.com/sebastianbergmann/phpunit/pull/2638): Regression in `PHPUnit\Framework\TestCase:registerMockObjectsFromTestArguments()`
+
+## [5.7.18] - 2017-04-02
+
+### Fixed
+
+* Fixed [#2145](https://github.com/sebastianbergmann/phpunit/issues/2145): `--stop-on-failure` fails to stop on PHP 7
+* Fixed [#2572](https://github.com/sebastianbergmann/phpunit/issues/2572): `PHPUnit\Framework\TestCase:registerMockObjectsFromTestArguments()` does not correctly handle arrays that reference themselves
+
+## [5.7.17] - 2017-03-19
+
+### Fixed
+
+* Fixed [#2016](https://github.com/sebastianbergmann/phpunit/issues/2016): `prophesize()` does not work when static attributes are backed up
+* Fixed [#2568](https://github.com/sebastianbergmann/phpunit/issues/2568): `ArraySubsetConstraint` uses invalid cast to array
+* Fixed [#2573](https://github.com/sebastianbergmann/phpunit/issues/2573): `getMockFromWsdl()` does not handle URLs with query parameters
+* `PHPUnit\Util\Test::getDataFromTestWithAnnotation()` raises notice when docblock contains Windows line endings
+
+## [5.7.16] - 2017-03-15
+
+### Fixed
+
+* Fixed [#2547](https://github.com/sebastianbergmann/phpunit/issues/2547): Code Coverage data is collected for test annotated with `@coversNothing`
+* Fixed [#2558](https://github.com/sebastianbergmann/phpunit/issues/2558): `countOf()` function is missing
+
+## [5.7.15] - 2017-03-02
+
+### Fixed
+
+* Fixed [#1999](https://github.com/sebastianbergmann/phpunit/issues/1999): Handler is inherited from previous custom option with handler
+* Fixed [#2149](https://github.com/sebastianbergmann/phpunit/issues/2149): `assertCount()` does not handle generators properly
+* Fixed [#2478](https://github.com/sebastianbergmann/phpunit/issues/2478): Tests that take too long are not reported as risky test
+
+## [5.7.14] - 2017-02-19
+
+### Fixed
+
+* Fixed [#2489](https://github.com/sebastianbergmann/phpunit/issues/2489): `processUncoveredFilesFromWhitelist` is not handled correctly
+* Fixed default values for `addUncoveredFilesFromWhitelist` and `processUncoveredFilesFromWhitelist` in `phpunit.xsd`
+
+## [5.7.13] - 2017-02-10
+
+### Fixed
+
+* Fixed [#2493](https://github.com/sebastianbergmann/phpunit/issues/2493): Fix for [#2475](https://github.com/sebastianbergmann/phpunit/pull/2475) does not apply to PHPUnit 5.7
+
+## [5.7.12] - 2017-02-08
+
+### Fixed
+
+* Fixed [#2475](https://github.com/sebastianbergmann/phpunit/pull/2475): Defining a test suite with only one file does not work
+
+## [5.7.11] - 2017-02-05
+
+### Fixed
+
+* Deprecation errors when used with PHP 7.2
+
+## [5.7.10] - 2017-02-04
+
+### Fixed
+
+* Fixed [#2462](https://github.com/sebastianbergmann/phpunit/issues/2462): Code Coverage whitelist is filled even if no code coverage data is to be collected
+
+## [5.7.9] - 2017-01-28
+
+### Fixed
+
+* Fixed [#2447](https://github.com/sebastianbergmann/phpunit/issues/2447): Reverted backwards incompatible change to handling of boolean environment variable values specified in XML
+
+## [5.7.8] - 2017-01-26
+
+### Fixed
+
+* Fixed [#2446](https://github.com/sebastianbergmann/phpunit/issues/2446): Reverted backwards incompatible change to exit code in case of warnings
+
+## [5.7.7] - 2017-01-25
+
+### Fixed
+
+* Fixed [#1896](https://github.com/sebastianbergmann/phpunit/issues/1896): Wrong test location when `@depends` and `@dataProvider` are combined
+* Fixed [#1983](https://github.com/sebastianbergmann/phpunit/pull/1983): Tests with `@expectedException` annotation cannot be skipped
+* Fixed [#2137](https://github.com/sebastianbergmann/phpunit/issues/2137): Warnings for invalid data providers are suppressed when test execution is filtered
+* Fixed [#2275](https://github.com/sebastianbergmann/phpunit/pull/2275): Invalid UTF-8 characters can lead to missing output
+* Fixed [#2299](https://github.com/sebastianbergmann/phpunit/issues/2299): `expectExceptionMessage()` and `expectExceptionCode()` do not work without `expectException()`
+* Fixed [#2328](https://github.com/sebastianbergmann/phpunit/issues/2328): `TestListener` callbacks `startTest()` and `endTest()` are not called when test is skipped due to `@depends`
+* Fixed [#2331](https://github.com/sebastianbergmann/phpunit/issues/2331): Boolean environment variable values specified in XML get mangled
+* Fixed [#2333](https://github.com/sebastianbergmann/phpunit/issues/2333): `assertContains()` and `assertNotContains()` do not handle UTF-8 strings correctly
+* Fixed [#2340](https://github.com/sebastianbergmann/phpunit/pull/2340): Data providers that use `yield` or implement `Iterator` cannot be combined
+* Fixed [#2349](https://github.com/sebastianbergmann/phpunit/pull/2349): `PHPUnit_TextUI_Command` does not `exit()` when it should
+* Fixed [#2392](https://github.com/sebastianbergmann/phpunit/issues/2392): Empty (but valid) data provider should skip the test
+* Fixed [#2431](https://github.com/sebastianbergmann/phpunit/issues/2431): `assertArraySubset()` does not support `ArrayAccess`
+* Fixed [#2435](https://github.com/sebastianbergmann/phpunit/issues/2435): Empty `@group` annotation causes error on PHP 7.2+
+
+## [5.7.6] - 2017-01-22
+
+### Fixed
+
+* Fixed [#2424](https://github.com/sebastianbergmann/phpunit/issues/2424): `TestCase::getStatus()` returns `STATUS_PASSED` instead of `STATUS_RISKY` for risky test
+* Fixed [#2427](https://github.com/sebastianbergmann/phpunit/issues/2427): TestDox group configuration is not handled
+* Fixed [#2428](https://github.com/sebastianbergmann/phpunit/pull/2428): Nested arrays specificied in XML configuration file are not handled correctly
+
+## [5.7.5] - 2016-12-28
+
+### Fixed
+
+* Fixed [#2404](https://github.com/sebastianbergmann/phpunit/pull/2404): `assertDirectoryNotIsWriteable()` calls itself
+
+## [5.7.4] - 2016-12-13
+
+### Fixed
+
+* Fixed [#2394](https://github.com/sebastianbergmann/phpunit/issues/2394): Do not treat `AssertionError` as assertion failure on PHP 5
+
+## [5.7.3] - 2016-12-09
+
+### Fixed
+
+* Fixed [#2384](https://github.com/sebastianbergmann/phpunit/pull/2384): Handle `PHPUnit_Framework_Exception` correctly when expecting exceptions
+
+## [5.7.2] - 2016-12-03
+
+### Fixed
+
+* Fixed [#2382](https://github.com/sebastianbergmann/phpunit/issues/2382): Uncloneable test doubles passed via data provider do not work
+
+## [5.7.1] - 2016-12-02
+
+### Fixed
+
+* Fixed [#2380](https://github.com/sebastianbergmann/phpunit/issues/2380): Data Providers cannot be generators anymore
+
+## [5.7.0] - 2016-12-02
+
+### Added
+
+* Merged [#2223](https://github.com/sebastianbergmann/phpunit/pull/2223): Add support for multiple data providers
+* Added `extensionsDirectory` configuration directive to configure a directory from which all `.phar` files are loaded as PHPUnit extensions
+* Added `--no-extensions` commandline option to suppress loading of extensions (from configured extension directory)
+* Added `PHPUnit\Framework\Assert` as an alias for `PHPUnit_Framework_Assert` for forward compatibility
+* Added `PHPUnit\Framework\BaseTestListener` as an alias for `PHPUnit_Framework_BaseTestListener` for forward compatibility
+* Added `PHPUnit\Framework\TestListener` as an alias for `PHPUnit_Framework_TestListener` for forward compatibility
+
+### Changed
+
+* The `--log-json` commandline option has been deprecated
+* The `--tap` and `--log-tap` commandline options have been deprecated
+* The `--self-update` and `--self-upgrade` commandline options have been deprecated (PHAR binary only)
+
+[5.7.27]: https://github.com/sebastianbergmann/phpunit/compare/5.7.26...5.7.27
+[5.7.26]: https://github.com/sebastianbergmann/phpunit/compare/5.7.25...5.7.26
+[5.7.25]: https://github.com/sebastianbergmann/phpunit/compare/5.7.24...5.7.25
+[5.7.24]: https://github.com/sebastianbergmann/phpunit/compare/5.7.23...5.7.24
+[5.7.23]: https://github.com/sebastianbergmann/phpunit/compare/5.7.22...5.7.23
+[5.7.22]: https://github.com/sebastianbergmann/phpunit/compare/5.7.21...5.7.22
+[5.7.21]: https://github.com/sebastianbergmann/phpunit/compare/5.7.20...5.7.21
+[5.7.20]: https://github.com/sebastianbergmann/phpunit/compare/5.7.19...5.7.20
+[5.7.19]: https://github.com/sebastianbergmann/phpunit/compare/5.7.18...5.7.19
+[5.7.18]: https://github.com/sebastianbergmann/phpunit/compare/5.7.17...5.7.18
+[5.7.17]: https://github.com/sebastianbergmann/phpunit/compare/5.7.16...5.7.17
+[5.7.16]: https://github.com/sebastianbergmann/phpunit/compare/5.7.15...5.7.16
+[5.7.15]: https://github.com/sebastianbergmann/phpunit/compare/5.7.14...5.7.15
+[5.7.14]: https://github.com/sebastianbergmann/phpunit/compare/5.7.13...5.7.14
+[5.7.13]: https://github.com/sebastianbergmann/phpunit/compare/5.7.12...5.7.13
+[5.7.12]: https://github.com/sebastianbergmann/phpunit/compare/5.7.11...5.7.12
+[5.7.11]: https://github.com/sebastianbergmann/phpunit/compare/5.7.10...5.7.11
+[5.7.10]: https://github.com/sebastianbergmann/phpunit/compare/5.7.9...5.7.10
+[5.7.9]: https://github.com/sebastianbergmann/phpunit/compare/5.7.8...5.7.9
+[5.7.8]: https://github.com/sebastianbergmann/phpunit/compare/5.7.7...5.7.8
+[5.7.7]: https://github.com/sebastianbergmann/phpunit/compare/5.7.6...5.7.7
+[5.7.6]: https://github.com/sebastianbergmann/phpunit/compare/5.7.5...5.7.6
+[5.7.5]: https://github.com/sebastianbergmann/phpunit/compare/5.7.4...5.7.5
+[5.7.4]: https://github.com/sebastianbergmann/phpunit/compare/5.7.3...5.7.4
+[5.7.3]: https://github.com/sebastianbergmann/phpunit/compare/5.7.2...5.7.3
+[5.7.2]: https://github.com/sebastianbergmann/phpunit/compare/5.7.1...5.7.2
+[5.7.1]: https://github.com/sebastianbergmann/phpunit/compare/5.7.0...5.7.1
+[5.7.0]: https://github.com/sebastianbergmann/phpunit/compare/5.6...5.7.0
+
diff --git a/vendor/phpunit/phpunit/LICENSE b/vendor/phpunit/phpunit/LICENSE
new file mode 100644
index 0000000..faba266
--- /dev/null
+++ b/vendor/phpunit/phpunit/LICENSE
@@ -0,0 +1,33 @@
+PHPUnit
+
+Copyright (c) 2001-2018, Sebastian Bergmann <sebastian@phpunit.de>.
+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/phpunit/phpunit/README.md b/vendor/phpunit/phpunit/README.md
new file mode 100644
index 0000000..e886b55
--- /dev/null
+++ b/vendor/phpunit/phpunit/README.md
@@ -0,0 +1,46 @@
+# PHPUnit
+
+PHPUnit is a programmer-oriented testing framework for PHP. It is an instance of the xUnit architecture for unit testing frameworks.
+
+[![Latest Stable Version](https://img.shields.io/packagist/v/phpunit/phpunit.svg?style=flat-square)](https://packagist.org/packages/phpunit/phpunit)
+[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%205.6-8892BF.svg?style=flat-square)](https://php.net/)
+[![Build Status](https://img.shields.io/travis/sebastianbergmann/phpunit/5.7.svg?style=flat-square)](https://phpunit.de/build-status.html)
+
+## Installation
+
+We distribute a [PHP Archive (PHAR)](https://php.net/phar) that has all required (as well as some optional) dependencies of PHPUnit bundled in a single file:
+
+```bash
+$ wget https://phar.phpunit.de/phpunit.phar
+
+$ chmod +x phpunit.phar
+
+$ mv phpunit.phar /usr/local/bin/phpunit
+```
+
+You can also immediately use the PHAR after you have downloaded it, of course:
+
+```bash
+$ wget https://phar.phpunit.de/phpunit.phar
+
+$ php phpunit.phar
+```
+
+Alternatively, you may use [Composer](https://getcomposer.org/) to download and install PHPUnit as well as its dependencies. Please refer to the [documentation](https://phpunit.de/documentation.html) for details on how to do this.
+
+## Contribute
+
+Please refer to [CONTRIBUTING.md](https://github.com/sebastianbergmann/phpunit/blob/master/.github/CONTRIBUTING.md) for information on how to contribute to PHPUnit and its related projects.
+
+## List of Contributors
+
+Thanks to everyone who has contributed to PHPUnit! You can find a detailed list of contributors on every PHPUnit related package on GitHub. This list shows only the major components:
+
+* [PHPUnit](https://github.com/sebastianbergmann/phpunit/graphs/contributors)
+* [PHP_CodeCoverage](https://github.com/sebastianbergmann/php-code-coverage/graphs/contributors)
+* [PHPUnit_MockObject](https://github.com/sebastianbergmann/phpunit-mock-objects/graphs/contributors)
+
+A very special thanks to everyone who has contributed to the documentation and helps maintain the translations:
+
+* [PHPUnit Documentation](https://github.com/sebastianbergmann/phpunit-documentation/graphs/contributors)
+
diff --git a/vendor/phpunit/phpunit/build.xml b/vendor/phpunit/phpunit/build.xml
new file mode 100644
index 0000000..224904b
--- /dev/null
+++ b/vendor/phpunit/phpunit/build.xml
@@ -0,0 +1,418 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="phpunit" default="setup">
+ <target name="setup" depends="clean,install-dependencies"/>
+ <target name="validate" depends="php-syntax-check,validate-composer-json,validate-phpunit-xsd"/>
+
+ <target name="clean" unless="clean.done" description="Cleanup build artifacts">
+ <delete dir="${basedir}/bin"/>
+ <delete dir="${basedir}/vendor"/>
+ <delete file="${basedir}/composer.lock"/>
+ <delete dir="${basedir}/build/documentation"/>
+ <delete dir="${basedir}/build/logfiles"/>
+ <delete dir="${basedir}/build/phar"/>
+ <delete>
+ <fileset dir="${basedir}/build">
+ <include name="**/phpunit*.phar"/>
+ <include name="**/phpunit*.phar.asc"/>
+ </fileset>
+ </delete>
+
+ <property name="clean.done" value="true"/>
+ </target>
+
+ <target name="prepare" unless="prepare.done" depends="clean" description="Prepare for build">
+ <mkdir dir="${basedir}/build/documentation"/>
+ <mkdir dir="${basedir}/build/logfiles"/>
+ <property name="prepare.done" value="true"/>
+ </target>
+
+ <target name="validate-composer-json" unless="validate-composer-json.done" description="Validate composer.json">
+ <exec executable="${basedir}/build/tools/composer" failonerror="true" taskname="composer">
+ <arg value="validate"/>
+ <arg value="--no-check-lock"/>
+ <arg value="--strict"/>
+ <arg value="${basedir}/composer.json"/>
+ </exec>
+
+ <property name="validate-composer-json.done" value="true"/>
+ </target>
+
+ <target name="-dependencies-installed">
+ <available file="${basedir}/composer.lock" property="dependencies-installed"/>
+ </target>
+
+ <target name="install-dependencies" unless="dependencies-installed" depends="-dependencies-installed,validate-composer-json" description="Install dependencies with Composer">
+ <exec executable="${basedir}/build/tools/composer" taskname="composer">
+ <arg value="update"/>
+ <arg value="--no-interaction"/>
+ <arg value="--no-progress"/>
+ <arg value="--no-ansi"/>
+ <arg value="--no-suggest"/>
+ </exec>
+ </target>
+
+ <target name="php-syntax-check" unless="php-syntax-check.done" description="Perform syntax check on PHP files">
+ <apply executable="php" failonerror="true" taskname="lint">
+ <arg value="-l"/>
+
+ <fileset dir="${basedir}/src">
+ <include name="**/*.php"/>
+ <modified/>
+ </fileset>
+
+ <fileset dir="${basedir}/tests">
+ <include name="**/*.php"/>
+ <modified/>
+ </fileset>
+ </apply>
+
+ <property name="php-syntax-check.done" value="true"/>
+ </target>
+
+ <target name="validate-phpunit-xsd" unless="validate-phpunit-xsd.done" description="Validate phpunit.xsd">
+ <exec executable="xmllint" failonerror="true" taskname="xmllint">
+ <arg value="--noout"/>
+ <arg path="${basedir}/phpunit.xsd"/>
+ </exec>
+
+ <property name="validate-phpunit-xsd.done" value="true"/>
+ </target>
+
+ <target name="test" depends="validate,install-dependencies" description="Run tests">
+ <exec executable="${basedir}/phpunit" taskname="phpunit"/>
+ </target>
+
+ <target name="signed-phar" depends="phar" description="Create signed PHAR archive of PHPUnit and all its dependencies">
+ <exec executable="gpg" failonerror="true">
+ <arg value="--local-user"/>
+ <arg value="sb@sebastian-bergmann.de"/>
+ <arg value="--armor"/>
+ <arg value="--detach-sign"/>
+ <arg path="${basedir}/build/phpunit-library-${version}.phar"/>
+ </exec>
+
+ <exec executable="gpg" failonerror="true">
+ <arg value="--local-user"/>
+ <arg value="sb@sebastian-bergmann.de"/>
+ <arg value="--armor"/>
+ <arg value="--detach-sign"/>
+ <arg path="${basedir}/build/phpunit-${version}.phar"/>
+ </exec>
+ </target>
+
+ <target name="phar" depends="-phar-determine-version,-phar-prepare" description="Create PHAR archive of PHPUnit and all its dependencies">
+ <antcall target="-phar-build">
+ <param name="type" value="release"/>
+ </antcall>
+ </target>
+
+ <target name="phar-nightly" depends="-phar-prepare" description="Create PHAR archive of PHPUnit and all its dependencies (nightly)">
+ <antcall target="-phar-build">
+ <param name="type" value="nightly"/>
+ </antcall>
+ </target>
+
+ <target name="-phar-prepare" depends="clean,install-dependencies">
+ <mkdir dir="${basedir}/build/phar"/>
+ <copy file="${basedir}/composer.json" tofile="${basedir}/composer.json.bak"/>
+
+ <exec executable="${basedir}/build/tools/composer">
+ <arg value="require"/>
+ <arg value="phpunit/dbunit:~2.0"/>
+ <arg value="phpunit/php-invoker:~1.1"/>
+ </exec>
+
+ <move file="${basedir}/composer.json.bak" tofile="${basedir}/composer.json"/>
+
+ <exec executable="${basedir}/build/phar-manifest.php" output="${basedir}/build/phar/manifest.txt"/>
+ <copy todir="${basedir}/build/phar" file="${basedir}/build/ca.pem" />
+
+ <copy file="${basedir}/vendor/phpunit/php-code-coverage/LICENSE" tofile="${basedir}/build/phar/php-code-coverage/LICENSE"/>
+ <copy todir="${basedir}/build/phar/php-code-coverage">
+ <fileset dir="${basedir}/vendor/phpunit/php-code-coverage/src">
+ <include name="**/*" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/phpunit/php-file-iterator/LICENSE" tofile="${basedir}/build/phar/php-file-iterator/LICENSE"/>
+ <copy todir="${basedir}/build/phar/php-file-iterator">
+ <fileset dir="${basedir}/vendor/phpunit/php-file-iterator/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/phpunit/php-text-template/LICENSE" tofile="${basedir}/build/phar/php-text-template/LICENSE"/>
+ <copy todir="${basedir}/build/phar/php-text-template">
+ <fileset dir="${basedir}/vendor/phpunit/php-text-template/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/phpunit/php-timer/LICENSE" tofile="${basedir}/build/phar/php-timer/LICENSE"/>
+ <copy todir="${basedir}/build/phar/php-timer">
+ <fileset dir="${basedir}/vendor/phpunit/php-timer/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/phpunit/php-token-stream/LICENSE" tofile="${basedir}/build/phar/php-token-stream/LICENSE"/>
+ <copy todir="${basedir}/build/phar/php-token-stream">
+ <fileset dir="${basedir}/vendor/phpunit/php-token-stream/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/phpunit/phpunit-mock-objects/LICENSE" tofile="${basedir}/build/phar/phpunit-mock-objects/LICENSE"/>
+ <copy todir="${basedir}/build/phar/phpunit-mock-objects">
+ <fileset dir="${basedir}/vendor/phpunit/phpunit-mock-objects/src">
+ <include name="**/*" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/sebastian/code-unit-reverse-lookup/LICENSE" tofile="${basedir}/build/phar/sebastian-code-unit-reverse-lookup/LICENSE"/>
+ <copy todir="${basedir}/build/phar/sebastian-code-unit-reverse-lookup">
+ <fileset dir="${basedir}/vendor/sebastian/code-unit-reverse-lookup/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/sebastian/comparator/LICENSE" tofile="${basedir}/build/phar/sebastian-comparator/LICENSE"/>
+ <copy todir="${basedir}/build/phar/sebastian-comparator">
+ <fileset dir="${basedir}/vendor/sebastian/comparator/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/sebastian/diff/LICENSE" tofile="${basedir}/build/phar/sebastian-diff/LICENSE"/>
+ <copy todir="${basedir}/build/phar/sebastian-diff">
+ <fileset dir="${basedir}/vendor/sebastian/diff/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/sebastian/environment/LICENSE" tofile="${basedir}/build/phar/sebastian-environment/LICENSE"/>
+ <copy todir="${basedir}/build/phar/sebastian-environment">
+ <fileset dir="${basedir}/vendor/sebastian/environment/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/sebastian/exporter/LICENSE" tofile="${basedir}/build/phar/sebastian-exporter/LICENSE"/>
+ <copy todir="${basedir}/build/phar/sebastian-exporter">
+ <fileset dir="${basedir}/vendor/sebastian/exporter/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/sebastian/recursion-context/LICENSE" tofile="${basedir}/build/phar/sebastian-recursion-context/LICENSE"/>
+ <copy todir="${basedir}/build/phar/sebastian-recursion-context">
+ <fileset dir="${basedir}/vendor/sebastian/recursion-context/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/sebastian/resource-operations/LICENSE" tofile="${basedir}/build/phar/sebastian-resource-operations/LICENSE"/>
+ <copy todir="${basedir}/build/phar/sebastian-resource-operations">
+ <fileset dir="${basedir}/vendor/sebastian/resource-operations/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/sebastian/global-state/LICENSE" tofile="${basedir}/build/phar/sebastian-global-state/LICENSE"/>
+ <copy todir="${basedir}/build/phar/sebastian-global-state">
+ <fileset dir="${basedir}/vendor/sebastian/global-state/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/sebastian/object-enumerator/LICENSE" tofile="${basedir}/build/phar/object-enumerator/LICENSE"/>
+ <copy todir="${basedir}/build/phar/sebastian-object-enumerator">
+ <fileset dir="${basedir}/vendor/sebastian/object-enumerator/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/sebastian/version/LICENSE" tofile="${basedir}/build/phar/sebastian-version/LICENSE"/>
+ <copy todir="${basedir}/build/phar/sebastian-version">
+ <fileset dir="${basedir}/vendor/sebastian/version/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/doctrine/instantiator/LICENSE" tofile="${basedir}/build/phar/doctrine-instantiator/LICENSE"/>
+ <copy todir="${basedir}/build/phar/doctrine-instantiator">
+ <fileset dir="${basedir}/vendor/doctrine/instantiator/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/symfony/yaml/LICENSE" tofile="${basedir}/build/phar/symfony/LICENSE"/>
+ <copy todir="${basedir}/build/phar/symfony">
+ <fileset dir="${basedir}/vendor/symfony">
+ <include name="**/*.php" />
+ <exclude name="**/Command/*.php" />
+ <exclude name="**/Tests/**" />
+ </fileset>
+ </copy>
+
+ <copy todir="${basedir}/build/phar/dbunit">
+ <fileset dir="${basedir}/vendor/phpunit/dbunit/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy todir="${basedir}/build/phar/php-invoker">
+ <fileset dir="${basedir}/vendor/phpunit/php-invoker/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/phpdocumentor/reflection-common/LICENSE" tofile="${basedir}/build/phar/phpdocumentor-reflection-common/LICENSE"/>
+ <copy todir="${basedir}/build/phar/phpdocumentor-reflection-common">
+ <fileset dir="${basedir}/vendor/phpdocumentor/reflection-common/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/phpdocumentor/reflection-docblock/LICENSE" tofile="${basedir}/build/phar/phpdocumentor-reflection-docblock/LICENSE"/>
+ <copy todir="${basedir}/build/phar/phpdocumentor-reflection-docblock">
+ <fileset dir="${basedir}/vendor/phpdocumentor/reflection-docblock/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/phpdocumentor/type-resolver/LICENSE" tofile="${basedir}/build/phar/phpdocumentor-type-resolver/LICENSE"/>
+ <copy todir="${basedir}/build/phar/phpdocumentor-type-resolver">
+ <fileset dir="${basedir}/vendor/phpdocumentor/type-resolver/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/phpspec/prophecy/LICENSE" tofile="${basedir}/build/phar/phpspec-prophecy/LICENSE"/>
+ <copy todir="${basedir}/build/phar/phpspec-prophecy">
+ <fileset dir="${basedir}/vendor/phpspec/prophecy/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/myclabs/deep-copy/LICENSE" tofile="${basedir}/build/phar/myclabs-deep-copy/LICENSE"/>
+ <copy todir="${basedir}/build/phar/myclabs-deep-copy">
+ <fileset dir="${basedir}/vendor/myclabs/deep-copy/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+
+ <copy file="${basedir}/vendor/webmozart/assert/LICENSE" tofile="${basedir}/build/phar/webmozart-assert/LICENSE"/>
+ <copy todir="${basedir}/build/phar/webmozart-assert">
+ <fileset dir="${basedir}/vendor/webmozart/assert/src">
+ <include name="**/*.php" />
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="-phar-build" depends="-phar-determine-version">
+ <copy todir="${basedir}/build/phar/phpunit">
+ <fileset dir="${basedir}/src">
+ <include name="**/*.php"/>
+ <include name="**/*.tpl*"/>
+ </fileset>
+ </copy>
+
+ <exec executable="${basedir}/build/phar-version.php" outputproperty="_version">
+ <arg value="${version}"/>
+ <arg value="${type}"/>
+ </exec>
+
+ <exec executable="${basedir}/build/tools/phpab" taskname="phpab">
+ <arg value="--all" />
+ <arg value="--static" />
+ <arg value="--once" />
+ <arg value="--phar" />
+ <arg value="--hash" />
+ <arg value="SHA-1" />
+ <arg value="--output" />
+ <arg path="${basedir}/build/phpunit-library-${_version}.phar" />
+ <arg value="--template" />
+ <arg path="${basedir}/build/library-phar-autoload.php.in" />
+ <arg path="${basedir}/build/phar" />
+ </exec>
+
+ <copy file="${basedir}/build/binary-phar-autoload.php.in" tofile="${basedir}/build/binary-phar-autoload.php"/>
+ <replace file="${basedir}/build/binary-phar-autoload.php" token="X.Y.Z" value="${_version}"/>
+
+ <exec executable="${basedir}/build/tools/phpab" taskname="phpab">
+ <arg value="--all" />
+ <arg value="--nolower" />
+ <arg value="--static" />
+ <arg value="--phar" />
+ <arg value="--hash" />
+ <arg value="SHA-1" />
+ <arg value="--output" />
+ <arg path="${basedir}/build/phpunit-${_version}.phar" />
+ <arg value="--template" />
+ <arg path="${basedir}/build/binary-phar-autoload.php" />
+ <arg path="${basedir}/build/phar" />
+ </exec>
+
+ <chmod file="${basedir}/build/phpunit-${_version}.phar" perm="ugo+rx"/>
+
+ <delete dir="${basedir}/build/phar"/>
+ <delete file="${basedir}/build/binary-phar-autoload.php"/>
+ </target>
+
+ <target name="-phar-determine-version">
+ <exec executable="${basedir}/build/version.php" outputproperty="version" />
+ </target>
+
+ <target name="generate-project-documentation" depends="-phploc,-phpcs,-phpmd,-phpunit">
+ <exec executable="${basedir}/build/tools/phpdox" dir="${basedir}/build" taskname="phpdox"/>
+ </target>
+
+ <target name="-phploc" depends="prepare">
+ <exec executable="${basedir}/build/tools/phploc" output="/dev/null" taskname="phploc">
+ <arg value="--count-tests"/>
+ <arg value="--log-xml"/>
+ <arg path="${basedir}/build/logfiles/phploc.xml"/>
+ <arg path="${basedir}/src"/>
+ <arg path="${basedir}/tests"/>
+ </exec>
+ </target>
+
+ <target name="phpcs">
+ <exec executable="${basedir}/build/tools/phpcs" taskname="phpcs">
+ <arg value="--standard=${basedir}/build/phpcs.xml"/>
+ <arg value="--extensions=php"/>
+ <arg value="--cache"/>
+ </exec>
+ </target>
+
+ <target name="-phpcs" depends="prepare">
+ <exec executable="${basedir}/build/tools/phpcs" output="/dev/null" taskname="phpcs">
+ <arg value="--standard=${basedir}/build/phpcs.xml"/>
+ <arg value="--extensions=php"/>
+ <arg value="--cache"/>
+ <arg value="--report=checkstyle"/>
+ <arg value="--report-file=${basedir}/build/logfiles/checkstyle.xml"/>
+ </exec>
+ </target>
+
+ <target name="-phpmd" depends="prepare">
+ <exec executable="${basedir}/build/tools/phpmd" taskname="phpmd">
+ <arg path="${basedir}/src"/>
+ <arg value="xml"/>
+ <arg path="${basedir}/build/phpmd.xml"/>
+ <arg value="--reportfile"/>
+ <arg path="${basedir}/build/logfiles/pmd.xml"/>
+ </exec>
+ </target>
+
+ <target name="-phpunit" depends="setup">
+ <exec executable="${basedir}/phpunit" taskname="phpunit">
+ <arg value="--coverage-xml"/>
+ <arg path="${basedir}/build/logfiles/coverage"/>
+ <arg value="--log-junit"/>
+ <arg path="${basedir}/build/logfiles/junit.xml"/>
+ </exec>
+ </target>
+</project>
+
diff --git a/vendor/phpunit/phpunit/composer.json b/vendor/phpunit/phpunit/composer.json
new file mode 100644
index 0000000..53bd8bb
--- /dev/null
+++ b/vendor/phpunit/phpunit/composer.json
@@ -0,0 +1,86 @@
+{
+ "name": "phpunit/phpunit",
+ "description": "The PHP Unit Testing framework.",
+ "type": "library",
+ "keywords": [
+ "phpunit",
+ "xunit",
+ "testing"
+ ],
+ "homepage": "https://phpunit.de/",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/phpunit/issues"
+ },
+ "prefer-stable": true,
+ "require": {
+ "php": "^5.6 || ^7.0",
+ "phpunit/php-file-iterator": "~1.4",
+ "phpunit/php-text-template": "~1.2",
+ "phpunit/php-code-coverage": "^4.0.4",
+ "phpunit/php-timer": "^1.0.6",
+ "phpunit/phpunit-mock-objects": "^3.2",
+ "phpspec/prophecy": "^1.6.2",
+ "symfony/yaml": "~2.1|~3.0|~4.0",
+ "sebastian/comparator": "^1.2.4",
+ "sebastian/diff": "^1.4.3",
+ "sebastian/environment": "^1.3.4 || ^2.0",
+ "sebastian/exporter": "~2.0",
+ "sebastian/global-state": "^1.1",
+ "sebastian/object-enumerator": "~2.0",
+ "sebastian/resource-operations": "~1.0",
+ "sebastian/version": "^1.0.6|^2.0.1",
+ "myclabs/deep-copy": "~1.3",
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "ext-libxml": "*"
+ },
+ "require-dev": {
+ "ext-PDO": "*"
+ },
+ "conflict": {
+ "phpdocumentor/reflection-docblock": "3.0.2"
+ },
+ "config": {
+ "platform": {
+ "php": "5.6.0"
+ },
+ "optimize-autoloader": true,
+ "sort-packages": true
+ },
+ "suggest": {
+ "phpunit/php-invoker": "~1.1",
+ "ext-xdebug": "*"
+ },
+ "bin": [
+ "phpunit"
+ ],
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "autoload-dev": {
+ "classmap": [
+ "tests/"
+ ],
+ "files": [
+ "src/Framework/Assert/Functions.php",
+ "tests/_files/CoveredFunction.php"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.7.x-dev"
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit/phpunit b/vendor/phpunit/phpunit/phpunit
new file mode 100755
index 0000000..f288633
--- /dev/null
+++ b/vendor/phpunit/phpunit/phpunit
@@ -0,0 +1,52 @@
+#!/usr/bin/env php
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+if (version_compare('5.6.0', PHP_VERSION, '>')) {
+ fwrite(
+ STDERR,
+ sprintf(
+ 'This version of PHPUnit is supported on PHP 5.6, PHP 7.0, and PHP 7.1.' . PHP_EOL .
+ 'You are using PHP %s (%s).' . PHP_EOL,
+ PHP_VERSION,
+ PHP_BINARY
+ )
+ );
+
+ die(1);
+}
+
+if (!ini_get('date.timezone')) {
+ ini_set('date.timezone', 'UTC');
+}
+
+foreach (array(__DIR__ . '/../../autoload.php', __DIR__ . '/../vendor/autoload.php', __DIR__ . '/vendor/autoload.php') as $file) {
+ if (file_exists($file)) {
+ define('PHPUNIT_COMPOSER_INSTALL', $file);
+
+ break;
+ }
+}
+
+unset($file);
+
+if (!defined('PHPUNIT_COMPOSER_INSTALL')) {
+ fwrite(STDERR,
+ 'You need to set up the project dependencies using Composer:' . PHP_EOL . PHP_EOL .
+ ' composer install' . PHP_EOL . PHP_EOL .
+ 'You can learn all about Composer on https://getcomposer.org/.' . PHP_EOL
+ );
+
+ die(1);
+}
+
+require PHPUNIT_COMPOSER_INSTALL;
+
+PHPUnit_TextUI_Command::main();
diff --git a/vendor/phpunit/phpunit/phpunit.xml b/vendor/phpunit/phpunit/phpunit.xml
new file mode 100644
index 0000000..378e047
--- /dev/null
+++ b/vendor/phpunit/phpunit/phpunit.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="phpunit.xsd"
+ bootstrap="tests/bootstrap.php"
+ backupGlobals="false"
+ verbose="true">
+ <testsuites>
+ <testsuite name="small">
+ <directory suffix="Test.php">tests/Framework</directory>
+ <directory suffix="Test.php">tests/Extensions</directory>
+ <directory suffix="Test.php">tests/Runner</directory>
+ <directory suffix="Test.php">tests/Util</directory>
+ </testsuite>
+
+ <testsuite name="large">
+ <directory suffix=".phpt">tests/TextUI</directory>
+ <directory suffix=".phpt">tests/Regression</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist processUncoveredFilesFromWhitelist="true">
+ <directory suffix=".php">src</directory>
+ <exclude>
+ <file>src/Framework/Assert/Functions.php</file>
+ <file>src/Util/PHP/eval-stdin.php</file>
+ </exclude>
+ </whitelist>
+ </filter>
+
+ <php>
+ <const name="PHPUNIT_TESTSUITE" value="true"/>
+ </php>
+</phpunit>
diff --git a/vendor/phpunit/phpunit/phpunit.xsd b/vendor/phpunit/phpunit/phpunit.xsd
new file mode 100644
index 0000000..4660b0d
--- /dev/null
+++ b/vendor/phpunit/phpunit/phpunit.xsd
@@ -0,0 +1,254 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:annotation>
+ <xs:documentation source="https://phpunit.de/manual/5.7/en/appendixes.configuration.html">
+ This Schema file defines the rules by which the XML configuration file of PHPUnit 5.7 may be structured.
+ </xs:documentation>
+ <xs:appinfo source="https://phpunit.de/manual/5.7/en/appendixes.configuration.html"/>
+ </xs:annotation>
+ <xs:element name="phpunit" type="phpUnitType">
+ <xs:annotation>
+ <xs:documentation>Root Element</xs:documentation>
+ </xs:annotation>
+ </xs:element>
+ <xs:complexType name="filtersType">
+ <xs:sequence>
+ <xs:element name="whitelist" type="whiteListType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="filterType">
+ <xs:sequence>
+ <xs:group ref="pathGroup"/>
+ <xs:element name="exclude" maxOccurs="unbounded" minOccurs="0">
+ <xs:complexType>
+ <xs:group ref="pathGroup"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="whiteListType">
+ <xs:complexContent>
+ <xs:extension base="filterType">
+ <xs:attribute name="addUncoveredFilesFromWhitelist" default="true" type="xs:boolean"/>
+ <xs:attribute name="processUncoveredFilesFromWhitelist" default="false" type="xs:boolean"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="groupsType">
+ <xs:choice>
+ <xs:sequence>
+ <xs:element name="include" type="groupType"/>
+ <xs:element name="exclude" type="groupType" minOccurs="0"/>
+ </xs:sequence>
+ <xs:sequence>
+ <xs:element name="exclude" type="groupType"/>
+ </xs:sequence>
+ </xs:choice>
+ </xs:complexType>
+ <xs:complexType name="groupType">
+ <xs:sequence>
+ <xs:element name="group" type="xs:string" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="listenersType">
+ <xs:sequence>
+ <xs:element name="listener" type="objectType" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="objectType">
+ <xs:sequence>
+ <xs:element name="arguments" minOccurs="0">
+ <xs:complexType>
+ <xs:group ref="argumentsGroup"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="class" type="xs:string" use="required"/>
+ <xs:attribute name="file" type="xs:anyURI"/>
+ </xs:complexType>
+ <xs:complexType name="arrayType">
+ <xs:sequence>
+ <xs:element name="element" type="argumentType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="argumentType">
+ <xs:group ref="argumentChoice"/>
+ <xs:attribute name="key" use="required"/>
+ </xs:complexType>
+ <xs:group name="argumentsGroup">
+ <xs:sequence>
+ <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="integer" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="double" type="xs:double" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="null" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="object" type="objectType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="file" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="directory" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:group>
+ <xs:group name="argumentChoice">
+ <xs:choice>
+ <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="integer" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="double" type="xs:double" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="null" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="object" type="objectType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="file" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="directory" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:choice>
+ </xs:group>
+ <xs:complexType name="loggersType">
+ <xs:sequence>
+ <xs:element name="log" type="loggerType" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="loggerType">
+ <xs:attribute name="type">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="coverage-html"/>
+ <xs:enumeration value="coverage-text"/>
+ <xs:enumeration value="coverage-clover"/>
+ <xs:enumeration value="coverage-crap4j"/>
+ <xs:enumeration value="coverage-xml"/>
+ <xs:enumeration value="json"/>
+ <xs:enumeration value="plain"/>
+ <xs:enumeration value="tap"/>
+ <xs:enumeration value="teamcity"/>
+ <xs:enumeration value="junit"/>
+ <xs:enumeration value="testdox-html"/>
+ <xs:enumeration value="testdox-text"/>
+ <xs:enumeration value="testdox-xml"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="target" type="xs:anyURI"/>
+ <xs:attribute name="lowUpperBound" type="xs:nonNegativeInteger" default="35"/>
+ <xs:attribute name="highLowerBound" type="xs:nonNegativeInteger" default="70"/>
+ <xs:attribute name="logIncompleteSkipped" type="xs:boolean" default="false"/>
+ <xs:attribute name="showUncoveredFiles" type="xs:boolean" default="false"/>
+ <xs:attribute name="threshold" type="xs:nonNegativeInteger" default="30"/>
+ </xs:complexType>
+ <xs:group name="pathGroup">
+ <xs:sequence>
+ <xs:element name="directory" type="directoryFilterType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="file" type="fileFilterType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:group>
+ <xs:complexType name="directoryFilterType">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attribute type="xs:string" name="suffix" default="Test.php"/>
+ <xs:attributeGroup ref="phpVersionGroup"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:complexType name="fileFilterType">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attributeGroup ref="phpVersionGroup"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:attributeGroup name="phpVersionGroup">
+ <xs:attribute name="phpVersion" type="xs:string" default="5.3.0"/>
+ <xs:attribute name="phpVersionOperator" type="xs:string" default="&gt;="/>
+ </xs:attributeGroup>
+ <xs:complexType name="phpType">
+ <xs:sequence>
+ <xs:choice maxOccurs="unbounded">
+ <xs:element name="includePath" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="ini" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="const" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="var" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="env" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="post" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="get" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="cookie" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="server" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="files" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="request" type="namedValueType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="namedValueType">
+ <xs:attribute name="name" use="required" type="xs:string"/>
+ <xs:attribute name="value" use="required" type="xs:anySimpleType"/>
+ </xs:complexType>
+ <xs:complexType name="phpUnitType">
+ <xs:annotation>
+ <xs:documentation>The main type specifying the document structure</xs:documentation>
+ </xs:annotation>
+ <xs:group ref="configGroup"/>
+ <xs:attributeGroup ref="configAttributeGroup"/>
+ </xs:complexType>
+ <xs:attributeGroup name="configAttributeGroup">
+ <xs:attribute name="backupGlobals" type="xs:boolean" default="true"/>
+ <xs:attribute name="backupStaticAttributes" type="xs:boolean" default="false"/>
+ <xs:attribute name="bootstrap" type="xs:anyURI"/>
+ <xs:attribute name="cacheTokens" type="xs:boolean"/>
+ <xs:attribute name="colors" type="xs:boolean" default="false"/>
+ <xs:attribute name="columns" type="xs:integer" default="80"/>
+ <xs:attribute name="convertErrorsToExceptions" type="xs:boolean" default="true"/>
+ <xs:attribute name="convertNoticesToExceptions" type="xs:boolean" default="true"/>
+ <xs:attribute name="convertWarningsToExceptions" type="xs:boolean" default="true"/>
+ <xs:attribute name="forceCoversAnnotation" type="xs:boolean" default="false"/>
+ <xs:attribute name="printerClass" type="xs:string" default="PHPUnit_TextUI_ResultPrinter"/>
+ <xs:attribute name="printerFile" type="xs:anyURI"/>
+ <xs:attribute name="processIsolation" type="xs:boolean" default="false"/>
+ <xs:attribute name="stopOnError" type="xs:boolean" default="false"/>
+ <xs:attribute name="stopOnFailure" type="xs:boolean" default="false"/>
+ <xs:attribute name="stopOnWarning" type="xs:boolean" default="false"/>
+ <xs:attribute name="stopOnIncomplete" type="xs:boolean" default="false"/>
+ <xs:attribute name="stopOnRisky" type="xs:boolean" default="false"/>
+ <xs:attribute name="stopOnSkipped" type="xs:boolean" default="false"/>
+ <xs:attribute name="failOnRisky" type="xs:boolean" default="false"/>
+ <xs:attribute name="failOnWarning" type="xs:boolean" default="false"/>
+ <xs:attribute name="beStrictAboutChangesToGlobalState" type="xs:boolean" default="false"/>
+ <xs:attribute name="beStrictAboutOutputDuringTests" type="xs:boolean" default="false"/>
+ <xs:attribute name="beStrictAboutResourceUsageDuringSmallTests" type="xs:boolean" default="false"/>
+ <xs:attribute name="beStrictAboutTestsThatDoNotTestAnything" type="xs:boolean" default="false"/>
+ <xs:attribute name="beStrictAboutTodoAnnotatedTests" type="xs:boolean" default="false"/>
+ <xs:attribute name="beStrictAboutCoversAnnotation" type="xs:boolean" default="false"/>
+ <xs:attribute name="checkForUnintentionallyCoveredCode" type="xs:boolean" default="false"/>
+ <xs:attribute name="enforceTimeLimit" type="xs:boolean" default="false"/>
+ <xs:attribute name="timeoutForSmallTests" type="xs:integer" default="1"/>
+ <xs:attribute name="timeoutForMediumTests" type="xs:integer" default="10"/>
+ <xs:attribute name="timeoutForLargeTests" type="xs:integer" default="60"/>
+ <xs:attribute name="testSuiteLoaderClass" type="xs:string" default="PHPUnit_Runner_StandardTestSuiteLoader"/>
+ <xs:attribute name="testSuiteLoaderFile" type="xs:anyURI"/>
+ <xs:attribute name="verbose" type="xs:boolean" default="false"/>
+ <xs:attribute name="stderr" type="xs:boolean" default="false"/>
+ <xs:attribute name="reverseDefectList" type="xs:boolean" default="false"/>
+ <xs:attribute name="registerMockObjectsFromTestArgumentsRecursively" type="xs:boolean" default="false"/>
+ <xs:attribute name="extensionsDirectory" type="xs:string"/>
+ </xs:attributeGroup>
+ <xs:group name="configGroup">
+ <xs:all>
+ <xs:element ref="testSuiteFacet" minOccurs="0"/>
+ <xs:element name="groups" type="groupsType" minOccurs="0"/>
+ <xs:element name="testdoxGroups" type="groupsType" minOccurs="0"/>
+ <xs:element name="filter" type="filtersType" minOccurs="0"/>
+ <xs:element name="logging" type="loggersType" minOccurs="0"/>
+ <xs:element name="listeners" type="listenersType" minOccurs="0"/>
+ <xs:element name="php" type="phpType" minOccurs="0"/>
+ </xs:all>
+ </xs:group>
+ <xs:element name="testSuiteFacet" abstract="true"/>
+ <xs:element name="testsuite" type="testSuiteType" substitutionGroup="testSuiteFacet"/>
+ <xs:element name="testsuites" type="testSuitesType" substitutionGroup="testSuiteFacet"/>
+ <xs:complexType name="testSuitesType">
+ <xs:sequence>
+ <xs:element name="testsuite" type="testSuiteType" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="testSuiteType">
+ <xs:sequence>
+ <xs:group ref="pathGroup"/>
+ <xs:element name="exclude" type="xs:anyURI" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ </xs:complexType>
+</xs:schema>
diff --git a/vendor/phpunit/phpunit/src/Exception.php b/vendor/phpunit/phpunit/src/Exception.php
new file mode 100644
index 0000000..b9c30dc
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Exception.php
@@ -0,0 +1,16 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Marker interface for PHPUnit exceptions.
+ */
+interface PHPUnit_Exception
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Extensions/GroupTestSuite.php b/vendor/phpunit/phpunit/src/Extensions/GroupTestSuite.php
new file mode 100644
index 0000000..2708b5a
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Extensions/GroupTestSuite.php
@@ -0,0 +1,58 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * We have a TestSuite object A.
+ * In TestSuite object A we have Tests tagged with @group.
+ * We want a TestSuite object B that contains TestSuite objects C, D, ...
+ * for the Tests tagged with @group C, @group D, ...
+ * Running the Tests from TestSuite object B results in Tests tagged with both
+ *
+ * @group C and @group D in TestSuite object A to be run twice .
+ *
+ * <code>
+ * $suite = new PHPUnit_Extensions_GroupTestSuite($A, array('C', 'D'));
+ * </code>
+ */
+class PHPUnit_Extensions_GroupTestSuite extends PHPUnit_Framework_TestSuite
+{
+ public function __construct(PHPUnit_Framework_TestSuite $suite, array $groups)
+ {
+ $groupSuites = [];
+ $name = $suite->getName();
+
+ foreach ($groups as $group) {
+ $groupSuites[$group] = new PHPUnit_Framework_TestSuite($name . ' - ' . $group);
+ $this->addTest($groupSuites[$group]);
+ }
+
+ $tests = new RecursiveIteratorIterator(
+ new PHPUnit_Util_TestSuiteIterator($suite),
+ RecursiveIteratorIterator::LEAVES_ONLY
+ );
+
+ foreach ($tests as $test) {
+ if ($test instanceof PHPUnit_Framework_TestCase) {
+ $testGroups = PHPUnit_Util_Test::getGroups(
+ get_class($test),
+ $test->getName(false)
+ );
+
+ foreach ($groups as $group) {
+ foreach ($testGroups as $testGroup) {
+ if ($group == $testGroup) {
+ $groupSuites[$group]->addTest($test);
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Extensions/PhptTestCase.php b/vendor/phpunit/phpunit/src/Extensions/PhptTestCase.php
new file mode 100644
index 0000000..4d143e2
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Extensions/PhptTestCase.php
@@ -0,0 +1,430 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Runner for PHPT test cases.
+ */
+class PHPUnit_Extensions_PhptTestCase implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing
+{
+ /**
+ * @var string
+ */
+ private $filename;
+
+ /**
+ * @var PHPUnit_Util_PHP
+ */
+ private $phpUtil;
+
+ /**
+ * @var array
+ */
+ private $settings = [
+ 'allow_url_fopen=1',
+ 'auto_append_file=',
+ 'auto_prepend_file=',
+ 'disable_functions=',
+ 'display_errors=1',
+ 'docref_root=',
+ 'docref_ext=.html',
+ 'error_append_string=',
+ 'error_prepend_string=',
+ 'error_reporting=-1',
+ 'html_errors=0',
+ 'log_errors=0',
+ 'magic_quotes_runtime=0',
+ 'output_handler=',
+ 'open_basedir=',
+ 'output_buffering=Off',
+ 'report_memleaks=0',
+ 'report_zend_debug=0',
+ 'safe_mode=0',
+ 'xdebug.default_enable=0'
+ ];
+
+ /**
+ * Constructs a test case with the given filename.
+ *
+ * @param string $filename
+ * @param PHPUnit_Util_PHP $phpUtil
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function __construct($filename, $phpUtil = null)
+ {
+ if (!is_string($filename)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!is_file($filename)) {
+ throw new PHPUnit_Framework_Exception(
+ sprintf(
+ 'File "%s" does not exist.',
+ $filename
+ )
+ );
+ }
+
+ $this->filename = $filename;
+ $this->phpUtil = $phpUtil ?: PHPUnit_Util_PHP::factory();
+ }
+
+ /**
+ * Counts the number of test cases executed by run(TestResult result).
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return 1;
+ }
+
+ /**
+ * @param array $sections
+ * @param string $output
+ */
+ private function assertPhptExpectation(array $sections, $output)
+ {
+ $assertions = [
+ 'EXPECT' => 'assertEquals',
+ 'EXPECTF' => 'assertStringMatchesFormat',
+ 'EXPECTREGEX' => 'assertRegExp',
+ ];
+
+ $actual = preg_replace('/\r\n/', "\n", trim($output));
+
+ foreach ($assertions as $sectionName => $sectionAssertion) {
+ if (isset($sections[$sectionName])) {
+ $sectionContent = preg_replace('/\r\n/', "\n", trim($sections[$sectionName]));
+ $assertion = $sectionAssertion;
+ $expected = $sectionName == 'EXPECTREGEX' ? "/{$sectionContent}/" : $sectionContent;
+
+ break;
+ }
+ }
+
+ PHPUnit_Framework_Assert::$assertion($expected, $actual);
+ }
+
+ /**
+ * Runs a test and collects its result in a TestResult instance.
+ *
+ * @param PHPUnit_Framework_TestResult $result
+ *
+ * @return PHPUnit_Framework_TestResult
+ */
+ public function run(PHPUnit_Framework_TestResult $result = null)
+ {
+ $sections = $this->parse();
+ $code = $this->render($sections['FILE']);
+
+ if ($result === null) {
+ $result = new PHPUnit_Framework_TestResult;
+ }
+
+ $skip = false;
+ $xfail = false;
+ $time = 0;
+ $settings = $this->settings;
+
+ $result->startTest($this);
+
+ if (isset($sections['INI'])) {
+ $settings = array_merge($settings, $this->parseIniSection($sections['INI']));
+ }
+
+ if (isset($sections['ENV'])) {
+ $env = $this->parseEnvSection($sections['ENV']);
+ $this->phpUtil->setEnv($env);
+ }
+
+ // Redirects STDERR to STDOUT
+ $this->phpUtil->setUseStderrRedirection(true);
+
+ if ($result->enforcesTimeLimit()) {
+ $this->phpUtil->setTimeout($result->getTimeoutForLargeTests());
+ }
+
+ if (isset($sections['SKIPIF'])) {
+ $jobResult = $this->phpUtil->runJob($sections['SKIPIF'], $settings);
+
+ if (!strncasecmp('skip', ltrim($jobResult['stdout']), 4)) {
+ if (preg_match('/^\s*skip\s*(.+)\s*/i', $jobResult['stdout'], $message)) {
+ $message = substr($message[1], 2);
+ } else {
+ $message = '';
+ }
+
+ $result->addFailure($this, new PHPUnit_Framework_SkippedTestError($message), 0);
+
+ $skip = true;
+ }
+ }
+
+ if (isset($sections['XFAIL'])) {
+ $xfail = trim($sections['XFAIL']);
+ }
+
+ if (!$skip) {
+ if (isset($sections['STDIN'])) {
+ $this->phpUtil->setStdin($sections['STDIN']);
+ }
+
+ if (isset($sections['ARGS'])) {
+ $this->phpUtil->setArgs($sections['ARGS']);
+ }
+
+ PHP_Timer::start();
+
+ $jobResult = $this->phpUtil->runJob($code, $settings);
+ $time = PHP_Timer::stop();
+
+ try {
+ $this->assertPhptExpectation($sections, $jobResult['stdout']);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ if ($xfail !== false) {
+ $result->addFailure(
+ $this,
+ new PHPUnit_Framework_IncompleteTestError(
+ $xfail,
+ 0,
+ $e
+ ),
+ $time
+ );
+ } else {
+ $result->addFailure($this, $e, $time);
+ }
+ } catch (Throwable $t) {
+ $result->addError($this, $t, $time);
+ } catch (Exception $e) {
+ $result->addError($this, $e, $time);
+ }
+
+ if ($result->allCompletelyImplemented() && $xfail !== false) {
+ $result->addFailure(
+ $this,
+ new PHPUnit_Framework_IncompleteTestError(
+ 'XFAIL section but test passes'
+ ),
+ $time
+ );
+ }
+
+ $this->phpUtil->setStdin('');
+ $this->phpUtil->setArgs('');
+
+ if (isset($sections['CLEAN'])) {
+ $cleanCode = $this->render($sections['CLEAN']);
+
+ $this->phpUtil->runJob($cleanCode, $this->settings);
+ }
+ }
+
+ $result->endTest($this, $time);
+
+ return $result;
+ }
+
+ /**
+ * Returns the name of the test case.
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->toString();
+ }
+
+ /**
+ * Returns a string representation of the test case.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return $this->filename;
+ }
+
+ /**
+ * @return array
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ private function parse()
+ {
+ $sections = [];
+ $section = '';
+
+ $allowExternalSections = [
+ 'FILE',
+ 'EXPECT',
+ 'EXPECTF',
+ 'EXPECTREGEX'
+ ];
+
+ $requiredSections = [
+ 'FILE',
+ [
+ 'EXPECT',
+ 'EXPECTF',
+ 'EXPECTREGEX'
+ ]
+ ];
+
+ $unsupportedSections = [
+ 'REDIRECTTEST',
+ 'REQUEST',
+ 'POST',
+ 'PUT',
+ 'POST_RAW',
+ 'GZIP_POST',
+ 'DEFLATE_POST',
+ 'GET',
+ 'COOKIE',
+ 'HEADERS',
+ 'CGI',
+ 'EXPECTHEADERS',
+ 'EXTENSIONS',
+ 'PHPDBG'
+ ];
+
+ foreach (file($this->filename) as $line) {
+ if (preg_match('/^--([_A-Z]+)--/', $line, $result)) {
+ $section = $result[1];
+ $sections[$section] = '';
+
+ continue;
+ } elseif (empty($section)) {
+ throw new PHPUnit_Framework_Exception('Invalid PHPT file');
+ }
+
+ $sections[$section] .= $line;
+ }
+
+ if (isset($sections['FILEEOF'])) {
+ $sections['FILE'] = rtrim($sections['FILEEOF'], "\r\n");
+ unset($sections['FILEEOF']);
+ }
+
+ $testDirectory = dirname($this->filename) . DIRECTORY_SEPARATOR;
+
+ foreach ($allowExternalSections as $section) {
+ if (isset($sections[$section . '_EXTERNAL'])) {
+ // do not allow directory traversal
+ $externalFilename = str_replace('..', '', trim($sections[$section . '_EXTERNAL']));
+
+ // only allow files from the test directory
+ if (!is_file($testDirectory . $externalFilename) || !is_readable($testDirectory . $externalFilename)) {
+ throw new PHPUnit_Framework_Exception(
+ sprintf(
+ 'Could not load --%s-- %s for PHPT file',
+ $section . '_EXTERNAL',
+ $testDirectory . $externalFilename
+ )
+ );
+ }
+
+ $sections[$section] = file_get_contents($testDirectory . $externalFilename);
+
+ unset($sections[$section . '_EXTERNAL']);
+ }
+ }
+
+ $isValid = true;
+
+ foreach ($requiredSections as $section) {
+ if (is_array($section)) {
+ $foundSection = false;
+
+ foreach ($section as $anySection) {
+ if (isset($sections[$anySection])) {
+ $foundSection = true;
+
+ break;
+ }
+ }
+
+ if (!$foundSection) {
+ $isValid = false;
+
+ break;
+ }
+ } else {
+ if (!isset($sections[$section])) {
+ $isValid = false;
+
+ break;
+ }
+ }
+ }
+
+ if (!$isValid) {
+ throw new PHPUnit_Framework_Exception('Invalid PHPT file');
+ }
+
+ foreach ($unsupportedSections as $section) {
+ if (isset($sections[$section])) {
+ throw new PHPUnit_Framework_Exception(
+ 'PHPUnit does not support this PHPT file'
+ );
+ }
+ }
+
+ return $sections;
+ }
+
+ /**
+ * @param string $code
+ *
+ * @return string
+ */
+ private function render($code)
+ {
+ return str_replace(
+ [
+ '__DIR__',
+ '__FILE__'
+ ],
+ [
+ "'" . dirname($this->filename) . "'",
+ "'" . $this->filename . "'"
+ ],
+ $code
+ );
+ }
+
+ /**
+ * Parse --INI-- section key value pairs and return as array.
+ *
+ * @param string
+ *
+ * @return array
+ */
+ protected function parseIniSection($content)
+ {
+ return preg_split('/\n|\r/', $content, -1, PREG_SPLIT_NO_EMPTY);
+ }
+
+ protected function parseEnvSection($content)
+ {
+ $env = [];
+
+ foreach (explode("\n", trim($content)) as $e) {
+ $e = explode('=', trim($e), 2);
+
+ if (!empty($e[0]) && isset($e[1])) {
+ $env[$e[0]] = $e[1];
+ }
+ }
+
+ return $env;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Extensions/PhptTestSuite.php b/vendor/phpunit/phpunit/src/Extensions/PhptTestSuite.php
new file mode 100644
index 0000000..3f37be8
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Extensions/PhptTestSuite.php
@@ -0,0 +1,38 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Suite for .phpt test cases.
+ */
+class PHPUnit_Extensions_PhptTestSuite extends PHPUnit_Framework_TestSuite
+{
+ /**
+ * Constructs a new TestSuite for .phpt test cases.
+ *
+ * @param string $directory
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function __construct($directory)
+ {
+ if (is_string($directory) && is_dir($directory)) {
+ $this->setName($directory);
+
+ $facade = new File_Iterator_Facade;
+ $files = $facade->getFilesAsArray($directory, '.phpt');
+
+ foreach ($files as $file) {
+ $this->addTestFile($file);
+ }
+ } else {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'directory name');
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Extensions/RepeatedTest.php b/vendor/phpunit/phpunit/src/Extensions/RepeatedTest.php
new file mode 100644
index 0000000..fb972a7
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Extensions/RepeatedTest.php
@@ -0,0 +1,88 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A Decorator that runs a test repeatedly.
+ */
+class PHPUnit_Extensions_RepeatedTest extends PHPUnit_Extensions_TestDecorator
+{
+ /**
+ * @var bool
+ */
+ protected $processIsolation = false;
+
+ /**
+ * @var int
+ */
+ protected $timesRepeat = 1;
+
+ /**
+ * @param PHPUnit_Framework_Test $test
+ * @param int $timesRepeat
+ * @param bool $processIsolation
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function __construct(PHPUnit_Framework_Test $test, $timesRepeat = 1, $processIsolation = false)
+ {
+ parent::__construct($test);
+
+ if (is_int($timesRepeat) &&
+ $timesRepeat >= 0) {
+ $this->timesRepeat = $timesRepeat;
+ } else {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 2,
+ 'positive integer'
+ );
+ }
+
+ $this->processIsolation = $processIsolation;
+ }
+
+ /**
+ * Counts the number of test cases that
+ * will be run by this test.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return $this->timesRepeat * count($this->test);
+ }
+
+ /**
+ * Runs the decorated test and collects the
+ * result in a TestResult.
+ *
+ * @param PHPUnit_Framework_TestResult $result
+ *
+ * @return PHPUnit_Framework_TestResult
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function run(PHPUnit_Framework_TestResult $result = null)
+ {
+ if ($result === null) {
+ $result = $this->createResult();
+ }
+
+ //@codingStandardsIgnoreStart
+ for ($i = 0; $i < $this->timesRepeat && !$result->shouldStop(); $i++) {
+ //@codingStandardsIgnoreEnd
+ if ($this->test instanceof PHPUnit_Framework_TestSuite) {
+ $this->test->setRunTestInSeparateProcess($this->processIsolation);
+ }
+ $this->test->run($result);
+ }
+
+ return $result;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Extensions/TestDecorator.php b/vendor/phpunit/phpunit/src/Extensions/TestDecorator.php
new file mode 100644
index 0000000..fd0a658
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Extensions/TestDecorator.php
@@ -0,0 +1,107 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A Decorator for Tests.
+ *
+ * Use TestDecorator as the base class for defining new
+ * test decorators. Test decorator subclasses can be introduced
+ * to add behaviour before or after a test is run.
+ */
+class PHPUnit_Extensions_TestDecorator extends PHPUnit_Framework_Assert implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing
+{
+ /**
+ * The Test to be decorated.
+ *
+ * @var object
+ */
+ protected $test = null;
+
+ /**
+ * Constructor.
+ *
+ * @param PHPUnit_Framework_Test $test
+ */
+ public function __construct(PHPUnit_Framework_Test $test)
+ {
+ $this->test = $test;
+ }
+
+ /**
+ * Returns a string representation of the test.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return $this->test->toString();
+ }
+
+ /**
+ * Runs the test and collects the
+ * result in a TestResult.
+ *
+ * @param PHPUnit_Framework_TestResult $result
+ */
+ public function basicRun(PHPUnit_Framework_TestResult $result)
+ {
+ $this->test->run($result);
+ }
+
+ /**
+ * Counts the number of test cases that
+ * will be run by this test.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return count($this->test);
+ }
+
+ /**
+ * Creates a default TestResult object.
+ *
+ * @return PHPUnit_Framework_TestResult
+ */
+ protected function createResult()
+ {
+ return new PHPUnit_Framework_TestResult;
+ }
+
+ /**
+ * Returns the test to be run.
+ *
+ * @return PHPUnit_Framework_Test
+ */
+ public function getTest()
+ {
+ return $this->test;
+ }
+
+ /**
+ * Runs the decorated test and collects the
+ * result in a TestResult.
+ *
+ * @param PHPUnit_Framework_TestResult $result
+ *
+ * @return PHPUnit_Framework_TestResult
+ */
+ public function run(PHPUnit_Framework_TestResult $result = null)
+ {
+ if ($result === null) {
+ $result = $this->createResult();
+ }
+
+ $this->basicRun($result);
+
+ return $result;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Extensions/TicketListener.php b/vendor/phpunit/phpunit/src/Extensions/TicketListener.php
new file mode 100644
index 0000000..32ccc15
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Extensions/TicketListener.php
@@ -0,0 +1,194 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Base class for test listeners that interact with an issue tracker.
+ */
+abstract class PHPUnit_Extensions_TicketListener implements PHPUnit_Framework_TestListener
+{
+ /**
+ * @var array
+ */
+ protected $ticketCounts = [];
+
+ /**
+ * @var bool
+ */
+ protected $ran = false;
+
+ /**
+ * An error occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ }
+
+ /**
+ * A failure occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_AssertionFailedError $e
+ * @param float $time
+ */
+ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
+ {
+ }
+
+ /**
+ * Incomplete test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ }
+
+ /**
+ * Risky test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ }
+
+ /**
+ * Skipped test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ }
+
+ /**
+ * A test suite started.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ }
+
+ /**
+ * A test suite ended.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ }
+
+ /**
+ * A test started.
+ *
+ * @param PHPUnit_Framework_Test $test
+ */
+ public function startTest(PHPUnit_Framework_Test $test)
+ {
+ if (!$test instanceof PHPUnit_Framework_WarningTestCase) {
+ if ($this->ran) {
+ return;
+ }
+
+ $name = $test->getName(false);
+ $tickets = PHPUnit_Util_Test::getTickets(get_class($test), $name);
+
+ foreach ($tickets as $ticket) {
+ $this->ticketCounts[$ticket][$name] = 1;
+ }
+
+ $this->ran = true;
+ }
+ }
+
+ /**
+ * A test ended.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param float $time
+ */
+ public function endTest(PHPUnit_Framework_Test $test, $time)
+ {
+ if (!$test instanceof PHPUnit_Framework_WarningTestCase) {
+ if ($test->getStatus() == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) {
+ $ifStatus = ['assigned', 'new', 'reopened'];
+ $newStatus = 'closed';
+ $message = 'Automatically closed by PHPUnit (test passed).';
+ $resolution = 'fixed';
+ $cumulative = true;
+ } elseif ($test->getStatus() == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE) {
+ $ifStatus = ['closed'];
+ $newStatus = 'reopened';
+ $message = 'Automatically reopened by PHPUnit (test failed).';
+ $resolution = '';
+ $cumulative = false;
+ } else {
+ return;
+ }
+
+ $name = $test->getName(false);
+ $tickets = PHPUnit_Util_Test::getTickets(get_class($test), $name);
+
+ foreach ($tickets as $ticket) {
+ // Remove this test from the totals (if it passed).
+ if ($test->getStatus() == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) {
+ unset($this->ticketCounts[$ticket][$name]);
+ }
+
+ // Only close tickets if ALL referenced cases pass
+ // but reopen tickets if a single test fails.
+ if ($cumulative) {
+ // Determine number of to-pass tests:
+ if (count($this->ticketCounts[$ticket]) > 0) {
+ // There exist remaining test cases with this reference.
+ $adjustTicket = false;
+ } else {
+ // No remaining tickets, go ahead and adjust.
+ $adjustTicket = true;
+ }
+ } else {
+ $adjustTicket = true;
+ }
+
+ $ticketInfo = $this->getTicketInfo($ticket);
+
+ if ($adjustTicket && in_array($ticketInfo['status'], $ifStatus)) {
+ $this->updateTicket($ticket, $newStatus, $message, $resolution);
+ }
+ }
+ }
+ }
+
+ /**
+ * @param mixed $ticketId
+ *
+ * @return mixed
+ */
+ abstract protected function getTicketInfo($ticketId = null);
+
+ /**
+ * @param string $ticketId
+ * @param string $newStatus
+ * @param string $message
+ * @param string $resolution
+ */
+ abstract protected function updateTicket($ticketId, $newStatus, $message, $resolution);
+}
diff --git a/vendor/phpunit/phpunit/src/ForwardCompatibility/Assert.php b/vendor/phpunit/phpunit/src/ForwardCompatibility/Assert.php
new file mode 100644
index 0000000..cf3186a
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/ForwardCompatibility/Assert.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PHPUnit\Framework;
+
+use PHPUnit_Framework_Assert;
+
+abstract class Assert extends PHPUnit_Framework_Assert
+{
+}
diff --git a/vendor/phpunit/phpunit/src/ForwardCompatibility/AssertionFailedError.php b/vendor/phpunit/phpunit/src/ForwardCompatibility/AssertionFailedError.php
new file mode 100644
index 0000000..d0cbe72
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/ForwardCompatibility/AssertionFailedError.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PHPUnit\Framework;
+
+use PHPUnit_Framework_AssertionFailedError;
+
+class AssertionFailedError extends PHPUnit_Framework_AssertionFailedError
+{
+}
diff --git a/vendor/phpunit/phpunit/src/ForwardCompatibility/BaseTestListener.php b/vendor/phpunit/phpunit/src/ForwardCompatibility/BaseTestListener.php
new file mode 100644
index 0000000..3eef490
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/ForwardCompatibility/BaseTestListener.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PHPUnit\Framework;
+
+use PHPUnit_Framework_BaseTestListener;
+
+abstract class BaseTestListener extends PHPUnit_Framework_BaseTestListener
+{
+}
diff --git a/vendor/phpunit/phpunit/src/ForwardCompatibility/Test.php b/vendor/phpunit/phpunit/src/ForwardCompatibility/Test.php
new file mode 100644
index 0000000..ce98526
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/ForwardCompatibility/Test.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PHPUnit\Framework;
+
+use PHPUnit_Framework_Test;
+
+interface Test extends PHPUnit_Framework_Test
+{
+}
diff --git a/vendor/phpunit/phpunit/src/ForwardCompatibility/TestCase.php b/vendor/phpunit/phpunit/src/ForwardCompatibility/TestCase.php
new file mode 100644
index 0000000..03189e3
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/ForwardCompatibility/TestCase.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PHPUnit\Framework;
+
+use PHPUnit_Framework_TestCase;
+
+abstract class TestCase extends PHPUnit_Framework_TestCase
+{
+}
diff --git a/vendor/phpunit/phpunit/src/ForwardCompatibility/TestListener.php b/vendor/phpunit/phpunit/src/ForwardCompatibility/TestListener.php
new file mode 100644
index 0000000..8440b14
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/ForwardCompatibility/TestListener.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PHPUnit\Framework;
+
+use PHPUnit_Framework_TestListener;
+
+interface TestListener extends PHPUnit_Framework_TestListener
+{
+}
diff --git a/vendor/phpunit/phpunit/src/ForwardCompatibility/TestSuite.php b/vendor/phpunit/phpunit/src/ForwardCompatibility/TestSuite.php
new file mode 100644
index 0000000..535bbbe
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/ForwardCompatibility/TestSuite.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace PHPUnit\Framework;
+
+use PHPUnit_Framework_TestSuite;
+
+class TestSuite extends PHPUnit_Framework_TestSuite
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Assert.php b/vendor/phpunit/phpunit/src/Framework/Assert.php
new file mode 100644
index 0000000..de009d1
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Assert.php
@@ -0,0 +1,2952 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A set of assertion methods.
+ */
+abstract class PHPUnit_Framework_Assert
+{
+ /**
+ * @var int
+ */
+ private static $count = 0;
+
+ /**
+ * Asserts that an array has a specified key.
+ *
+ * @param mixed $key
+ * @param array|ArrayAccess $array
+ * @param string $message
+ */
+ public static function assertArrayHasKey($key, $array, $message = '')
+ {
+ if (!(is_int($key) || is_string($key))) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 1,
+ 'integer or string'
+ );
+ }
+
+ if (!(is_array($array) || $array instanceof ArrayAccess)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 2,
+ 'array or ArrayAccess'
+ );
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_ArrayHasKey($key);
+
+ static::assertThat($array, $constraint, $message);
+ }
+
+ /**
+ * Asserts that an array has a specified subset.
+ *
+ * @param array|ArrayAccess $subset
+ * @param array|ArrayAccess $array
+ * @param bool $strict Check for object identity
+ * @param string $message
+ */
+ public static function assertArraySubset($subset, $array, $strict = false, $message = '')
+ {
+ if (!(is_array($subset) || $subset instanceof ArrayAccess)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 1,
+ 'array or ArrayAccess'
+ );
+ }
+
+ if (!(is_array($array) || $array instanceof ArrayAccess)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 2,
+ 'array or ArrayAccess'
+ );
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_ArraySubset($subset, $strict);
+
+ static::assertThat($array, $constraint, $message);
+ }
+
+ /**
+ * Asserts that an array does not have a specified key.
+ *
+ * @param mixed $key
+ * @param array|ArrayAccess $array
+ * @param string $message
+ */
+ public static function assertArrayNotHasKey($key, $array, $message = '')
+ {
+ if (!(is_int($key) || is_string($key))) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 1,
+ 'integer or string'
+ );
+ }
+
+ if (!(is_array($array) || $array instanceof ArrayAccess)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 2,
+ 'array or ArrayAccess'
+ );
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_ArrayHasKey($key)
+ );
+
+ static::assertThat($array, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a haystack contains a needle.
+ *
+ * @param mixed $needle
+ * @param mixed $haystack
+ * @param string $message
+ * @param bool $ignoreCase
+ * @param bool $checkForObjectIdentity
+ * @param bool $checkForNonObjectIdentity
+ */
+ public static function assertContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
+ {
+ if (is_array($haystack) ||
+ is_object($haystack) && $haystack instanceof Traversable) {
+ $constraint = new PHPUnit_Framework_Constraint_TraversableContains(
+ $needle,
+ $checkForObjectIdentity,
+ $checkForNonObjectIdentity
+ );
+ } elseif (is_string($haystack)) {
+ if (!is_string($needle)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 1,
+ 'string'
+ );
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_StringContains(
+ $needle,
+ $ignoreCase
+ );
+ } else {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 2,
+ 'array, traversable or string'
+ );
+ }
+
+ static::assertThat($haystack, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a haystack that is stored in a static attribute of a class
+ * or an attribute of an object contains a needle.
+ *
+ * @param mixed $needle
+ * @param string $haystackAttributeName
+ * @param string|object $haystackClassOrObject
+ * @param string $message
+ * @param bool $ignoreCase
+ * @param bool $checkForObjectIdentity
+ * @param bool $checkForNonObjectIdentity
+ */
+ public static function assertAttributeContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
+ {
+ static::assertContains(
+ $needle,
+ static::readAttribute($haystackClassOrObject, $haystackAttributeName),
+ $message,
+ $ignoreCase,
+ $checkForObjectIdentity,
+ $checkForNonObjectIdentity
+ );
+ }
+
+ /**
+ * Asserts that a haystack does not contain a needle.
+ *
+ * @param mixed $needle
+ * @param mixed $haystack
+ * @param string $message
+ * @param bool $ignoreCase
+ * @param bool $checkForObjectIdentity
+ * @param bool $checkForNonObjectIdentity
+ */
+ public static function assertNotContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
+ {
+ if (is_array($haystack) ||
+ is_object($haystack) && $haystack instanceof Traversable) {
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_TraversableContains(
+ $needle,
+ $checkForObjectIdentity,
+ $checkForNonObjectIdentity
+ )
+ );
+ } elseif (is_string($haystack)) {
+ if (!is_string($needle)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 1,
+ 'string'
+ );
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_StringContains(
+ $needle,
+ $ignoreCase
+ )
+ );
+ } else {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 2,
+ 'array, traversable or string'
+ );
+ }
+
+ static::assertThat($haystack, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a haystack that is stored in a static attribute of a class
+ * or an attribute of an object does not contain a needle.
+ *
+ * @param mixed $needle
+ * @param string $haystackAttributeName
+ * @param string|object $haystackClassOrObject
+ * @param string $message
+ * @param bool $ignoreCase
+ * @param bool $checkForObjectIdentity
+ * @param bool $checkForNonObjectIdentity
+ */
+ public static function assertAttributeNotContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
+ {
+ static::assertNotContains(
+ $needle,
+ static::readAttribute($haystackClassOrObject, $haystackAttributeName),
+ $message,
+ $ignoreCase,
+ $checkForObjectIdentity,
+ $checkForNonObjectIdentity
+ );
+ }
+
+ /**
+ * Asserts that a haystack contains only values of a given type.
+ *
+ * @param string $type
+ * @param mixed $haystack
+ * @param bool $isNativeType
+ * @param string $message
+ */
+ public static function assertContainsOnly($type, $haystack, $isNativeType = null, $message = '')
+ {
+ if (!(is_array($haystack) ||
+ is_object($haystack) && $haystack instanceof Traversable)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 2,
+ 'array or traversable'
+ );
+ }
+
+ if ($isNativeType == null) {
+ $isNativeType = PHPUnit_Util_Type::isType($type);
+ }
+
+ static::assertThat(
+ $haystack,
+ new PHPUnit_Framework_Constraint_TraversableContainsOnly(
+ $type,
+ $isNativeType
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a haystack contains only instances of a given classname
+ *
+ * @param string $classname
+ * @param array|Traversable $haystack
+ * @param string $message
+ */
+ public static function assertContainsOnlyInstancesOf($classname, $haystack, $message = '')
+ {
+ if (!(is_array($haystack) ||
+ is_object($haystack) && $haystack instanceof Traversable)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 2,
+ 'array or traversable'
+ );
+ }
+
+ static::assertThat(
+ $haystack,
+ new PHPUnit_Framework_Constraint_TraversableContainsOnly(
+ $classname,
+ false
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a haystack that is stored in a static attribute of a class
+ * or an attribute of an object contains only values of a given type.
+ *
+ * @param string $type
+ * @param string $haystackAttributeName
+ * @param string|object $haystackClassOrObject
+ * @param bool $isNativeType
+ * @param string $message
+ */
+ public static function assertAttributeContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = null, $message = '')
+ {
+ static::assertContainsOnly(
+ $type,
+ static::readAttribute($haystackClassOrObject, $haystackAttributeName),
+ $isNativeType,
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a haystack does not contain only values of a given type.
+ *
+ * @param string $type
+ * @param mixed $haystack
+ * @param bool $isNativeType
+ * @param string $message
+ */
+ public static function assertNotContainsOnly($type, $haystack, $isNativeType = null, $message = '')
+ {
+ if (!(is_array($haystack) ||
+ is_object($haystack) && $haystack instanceof Traversable)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 2,
+ 'array or traversable'
+ );
+ }
+
+ if ($isNativeType == null) {
+ $isNativeType = PHPUnit_Util_Type::isType($type);
+ }
+
+ static::assertThat(
+ $haystack,
+ new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_TraversableContainsOnly(
+ $type,
+ $isNativeType
+ )
+ ),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a haystack that is stored in a static attribute of a class
+ * or an attribute of an object does not contain only values of a given
+ * type.
+ *
+ * @param string $type
+ * @param string $haystackAttributeName
+ * @param string|object $haystackClassOrObject
+ * @param bool $isNativeType
+ * @param string $message
+ */
+ public static function assertAttributeNotContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = null, $message = '')
+ {
+ static::assertNotContainsOnly(
+ $type,
+ static::readAttribute($haystackClassOrObject, $haystackAttributeName),
+ $isNativeType,
+ $message
+ );
+ }
+
+ /**
+ * Asserts the number of elements of an array, Countable or Traversable.
+ *
+ * @param int $expectedCount
+ * @param mixed $haystack
+ * @param string $message
+ */
+ public static function assertCount($expectedCount, $haystack, $message = '')
+ {
+ if (!is_int($expectedCount)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
+ }
+
+ if (!$haystack instanceof Countable &&
+ !$haystack instanceof Traversable &&
+ !is_array($haystack)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable');
+ }
+
+ static::assertThat(
+ $haystack,
+ new PHPUnit_Framework_Constraint_Count($expectedCount),
+ $message
+ );
+ }
+
+ /**
+ * Asserts the number of elements of an array, Countable or Traversable
+ * that is stored in an attribute.
+ *
+ * @param int $expectedCount
+ * @param string $haystackAttributeName
+ * @param string|object $haystackClassOrObject
+ * @param string $message
+ */
+ public static function assertAttributeCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '')
+ {
+ static::assertCount(
+ $expectedCount,
+ static::readAttribute($haystackClassOrObject, $haystackAttributeName),
+ $message
+ );
+ }
+
+ /**
+ * Asserts the number of elements of an array, Countable or Traversable.
+ *
+ * @param int $expectedCount
+ * @param mixed $haystack
+ * @param string $message
+ */
+ public static function assertNotCount($expectedCount, $haystack, $message = '')
+ {
+ if (!is_int($expectedCount)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
+ }
+
+ if (!$haystack instanceof Countable &&
+ !$haystack instanceof Traversable &&
+ !is_array($haystack)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_Count($expectedCount)
+ );
+
+ static::assertThat($haystack, $constraint, $message);
+ }
+
+ /**
+ * Asserts the number of elements of an array, Countable or Traversable
+ * that is stored in an attribute.
+ *
+ * @param int $expectedCount
+ * @param string $haystackAttributeName
+ * @param string|object $haystackClassOrObject
+ * @param string $message
+ */
+ public static function assertAttributeNotCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '')
+ {
+ static::assertNotCount(
+ $expectedCount,
+ static::readAttribute($haystackClassOrObject, $haystackAttributeName),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that two variables are equal.
+ *
+ * @param mixed $expected
+ * @param mixed $actual
+ * @param string $message
+ * @param float $delta
+ * @param int $maxDepth
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ */
+ public static function assertEquals($expected, $actual, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
+ {
+ $constraint = new PHPUnit_Framework_Constraint_IsEqual(
+ $expected,
+ $delta,
+ $maxDepth,
+ $canonicalize,
+ $ignoreCase
+ );
+
+ static::assertThat($actual, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a variable is equal to an attribute of an object.
+ *
+ * @param mixed $expected
+ * @param string $actualAttributeName
+ * @param string|object $actualClassOrObject
+ * @param string $message
+ * @param float $delta
+ * @param int $maxDepth
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ */
+ public static function assertAttributeEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
+ {
+ static::assertEquals(
+ $expected,
+ static::readAttribute($actualClassOrObject, $actualAttributeName),
+ $message,
+ $delta,
+ $maxDepth,
+ $canonicalize,
+ $ignoreCase
+ );
+ }
+
+ /**
+ * Asserts that two variables are not equal.
+ *
+ * @param mixed $expected
+ * @param mixed $actual
+ * @param string $message
+ * @param float $delta
+ * @param int $maxDepth
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ */
+ public static function assertNotEquals($expected, $actual, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
+ {
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_IsEqual(
+ $expected,
+ $delta,
+ $maxDepth,
+ $canonicalize,
+ $ignoreCase
+ )
+ );
+
+ static::assertThat($actual, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a variable is not equal to an attribute of an object.
+ *
+ * @param mixed $expected
+ * @param string $actualAttributeName
+ * @param string|object $actualClassOrObject
+ * @param string $message
+ * @param float $delta
+ * @param int $maxDepth
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ */
+ public static function assertAttributeNotEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
+ {
+ static::assertNotEquals(
+ $expected,
+ static::readAttribute($actualClassOrObject, $actualAttributeName),
+ $message,
+ $delta,
+ $maxDepth,
+ $canonicalize,
+ $ignoreCase
+ );
+ }
+
+ /**
+ * Asserts that a variable is empty.
+ *
+ * @param mixed $actual
+ * @param string $message
+ *
+ * @throws PHPUnit_Framework_AssertionFailedError
+ */
+ public static function assertEmpty($actual, $message = '')
+ {
+ static::assertThat($actual, static::isEmpty(), $message);
+ }
+
+ /**
+ * Asserts that a static attribute of a class or an attribute of an object
+ * is empty.
+ *
+ * @param string $haystackAttributeName
+ * @param string|object $haystackClassOrObject
+ * @param string $message
+ */
+ public static function assertAttributeEmpty($haystackAttributeName, $haystackClassOrObject, $message = '')
+ {
+ static::assertEmpty(
+ static::readAttribute($haystackClassOrObject, $haystackAttributeName),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is not empty.
+ *
+ * @param mixed $actual
+ * @param string $message
+ *
+ * @throws PHPUnit_Framework_AssertionFailedError
+ */
+ public static function assertNotEmpty($actual, $message = '')
+ {
+ static::assertThat($actual, static::logicalNot(static::isEmpty()), $message);
+ }
+
+ /**
+ * Asserts that a static attribute of a class or an attribute of an object
+ * is not empty.
+ *
+ * @param string $haystackAttributeName
+ * @param string|object $haystackClassOrObject
+ * @param string $message
+ */
+ public static function assertAttributeNotEmpty($haystackAttributeName, $haystackClassOrObject, $message = '')
+ {
+ static::assertNotEmpty(
+ static::readAttribute($haystackClassOrObject, $haystackAttributeName),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a value is greater than another value.
+ *
+ * @param mixed $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+ public static function assertGreaterThan($expected, $actual, $message = '')
+ {
+ static::assertThat($actual, static::greaterThan($expected), $message);
+ }
+
+ /**
+ * Asserts that an attribute is greater than another value.
+ *
+ * @param mixed $expected
+ * @param string $actualAttributeName
+ * @param string|object $actualClassOrObject
+ * @param string $message
+ */
+ public static function assertAttributeGreaterThan($expected, $actualAttributeName, $actualClassOrObject, $message = '')
+ {
+ static::assertGreaterThan(
+ $expected,
+ static::readAttribute($actualClassOrObject, $actualAttributeName),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a value is greater than or equal to another value.
+ *
+ * @param mixed $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+ public static function assertGreaterThanOrEqual($expected, $actual, $message = '')
+ {
+ static::assertThat(
+ $actual,
+ static::greaterThanOrEqual($expected),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that an attribute is greater than or equal to another value.
+ *
+ * @param mixed $expected
+ * @param string $actualAttributeName
+ * @param string|object $actualClassOrObject
+ * @param string $message
+ */
+ public static function assertAttributeGreaterThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '')
+ {
+ static::assertGreaterThanOrEqual(
+ $expected,
+ static::readAttribute($actualClassOrObject, $actualAttributeName),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a value is smaller than another value.
+ *
+ * @param mixed $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+ public static function assertLessThan($expected, $actual, $message = '')
+ {
+ static::assertThat($actual, static::lessThan($expected), $message);
+ }
+
+ /**
+ * Asserts that an attribute is smaller than another value.
+ *
+ * @param mixed $expected
+ * @param string $actualAttributeName
+ * @param string|object $actualClassOrObject
+ * @param string $message
+ */
+ public static function assertAttributeLessThan($expected, $actualAttributeName, $actualClassOrObject, $message = '')
+ {
+ static::assertLessThan(
+ $expected,
+ static::readAttribute($actualClassOrObject, $actualAttributeName),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a value is smaller than or equal to another value.
+ *
+ * @param mixed $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+ public static function assertLessThanOrEqual($expected, $actual, $message = '')
+ {
+ static::assertThat($actual, static::lessThanOrEqual($expected), $message);
+ }
+
+ /**
+ * Asserts that an attribute is smaller than or equal to another value.
+ *
+ * @param mixed $expected
+ * @param string $actualAttributeName
+ * @param string|object $actualClassOrObject
+ * @param string $message
+ */
+ public static function assertAttributeLessThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '')
+ {
+ static::assertLessThanOrEqual(
+ $expected,
+ static::readAttribute($actualClassOrObject, $actualAttributeName),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that the contents of one file is equal to the contents of another
+ * file.
+ *
+ * @param string $expected
+ * @param string $actual
+ * @param string $message
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ */
+ public static function assertFileEquals($expected, $actual, $message = '', $canonicalize = false, $ignoreCase = false)
+ {
+ static::assertFileExists($expected, $message);
+ static::assertFileExists($actual, $message);
+
+ static::assertEquals(
+ file_get_contents($expected),
+ file_get_contents($actual),
+ $message,
+ 0,
+ 10,
+ $canonicalize,
+ $ignoreCase
+ );
+ }
+
+ /**
+ * Asserts that the contents of one file is not equal to the contents of
+ * another file.
+ *
+ * @param string $expected
+ * @param string $actual
+ * @param string $message
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ */
+ public static function assertFileNotEquals($expected, $actual, $message = '', $canonicalize = false, $ignoreCase = false)
+ {
+ static::assertFileExists($expected, $message);
+ static::assertFileExists($actual, $message);
+
+ static::assertNotEquals(
+ file_get_contents($expected),
+ file_get_contents($actual),
+ $message,
+ 0,
+ 10,
+ $canonicalize,
+ $ignoreCase
+ );
+ }
+
+ /**
+ * Asserts that the contents of a string is equal
+ * to the contents of a file.
+ *
+ * @param string $expectedFile
+ * @param string $actualString
+ * @param string $message
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ */
+ public static function assertStringEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = false, $ignoreCase = false)
+ {
+ static::assertFileExists($expectedFile, $message);
+
+ static::assertEquals(
+ file_get_contents($expectedFile),
+ $actualString,
+ $message,
+ 0,
+ 10,
+ $canonicalize,
+ $ignoreCase
+ );
+ }
+
+ /**
+ * Asserts that the contents of a string is not equal
+ * to the contents of a file.
+ *
+ * @param string $expectedFile
+ * @param string $actualString
+ * @param string $message
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ */
+ public static function assertStringNotEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = false, $ignoreCase = false)
+ {
+ static::assertFileExists($expectedFile, $message);
+
+ static::assertNotEquals(
+ file_get_contents($expectedFile),
+ $actualString,
+ $message,
+ 0,
+ 10,
+ $canonicalize,
+ $ignoreCase
+ );
+ }
+
+ /**
+ * Asserts that a file/dir is readable.
+ *
+ * @param string $filename
+ * @param string $message
+ */
+ public static function assertIsReadable($filename, $message = '')
+ {
+ if (!is_string($filename)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_IsReadable;
+
+ static::assertThat($filename, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a file/dir exists and is not readable.
+ *
+ * @param string $filename
+ * @param string $message
+ */
+ public static function assertNotIsReadable($filename, $message = '')
+ {
+ if (!is_string($filename)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_IsReadable
+ );
+
+ static::assertThat($filename, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a file/dir exists and is writable.
+ *
+ * @param string $filename
+ * @param string $message
+ */
+ public static function assertIsWritable($filename, $message = '')
+ {
+ if (!is_string($filename)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_IsWritable;
+
+ static::assertThat($filename, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a file/dir exists and is not writable.
+ *
+ * @param string $filename
+ * @param string $message
+ */
+ public static function assertNotIsWritable($filename, $message = '')
+ {
+ if (!is_string($filename)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_IsWritable
+ );
+
+ static::assertThat($filename, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a directory exists.
+ *
+ * @param string $directory
+ * @param string $message
+ */
+ public static function assertDirectoryExists($directory, $message = '')
+ {
+ if (!is_string($directory)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_DirectoryExists;
+
+ static::assertThat($directory, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a directory does not exist.
+ *
+ * @param string $directory
+ * @param string $message
+ */
+ public static function assertDirectoryNotExists($directory, $message = '')
+ {
+ if (!is_string($directory)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_DirectoryExists
+ );
+
+ static::assertThat($directory, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a directory exists and is readable.
+ *
+ * @param string $directory
+ * @param string $message
+ */
+ public static function assertDirectoryIsReadable($directory, $message = '')
+ {
+ self::assertDirectoryExists($directory, $message);
+ self::assertIsReadable($directory, $message);
+ }
+
+ /**
+ * Asserts that a directory exists and is not readable.
+ *
+ * @param string $directory
+ * @param string $message
+ */
+ public static function assertDirectoryNotIsReadable($directory, $message = '')
+ {
+ self::assertDirectoryExists($directory, $message);
+ self::assertNotIsReadable($directory, $message);
+ }
+
+ /**
+ * Asserts that a directory exists and is writable.
+ *
+ * @param string $directory
+ * @param string $message
+ */
+ public static function assertDirectoryIsWritable($directory, $message = '')
+ {
+ self::assertDirectoryExists($directory, $message);
+ self::assertIsWritable($directory, $message);
+ }
+
+ /**
+ * Asserts that a directory exists and is not writable.
+ *
+ * @param string $directory
+ * @param string $message
+ */
+ public static function assertDirectoryNotIsWritable($directory, $message = '')
+ {
+ self::assertDirectoryExists($directory, $message);
+ self::assertNotIsWritable($directory, $message);
+ }
+
+ /**
+ * Asserts that a file exists.
+ *
+ * @param string $filename
+ * @param string $message
+ */
+ public static function assertFileExists($filename, $message = '')
+ {
+ if (!is_string($filename)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_FileExists;
+
+ static::assertThat($filename, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a file does not exist.
+ *
+ * @param string $filename
+ * @param string $message
+ */
+ public static function assertFileNotExists($filename, $message = '')
+ {
+ if (!is_string($filename)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_FileExists
+ );
+
+ static::assertThat($filename, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a file exists and is readable.
+ *
+ * @param string $file
+ * @param string $message
+ */
+ public static function assertFileIsReadable($file, $message = '')
+ {
+ self::assertFileExists($file, $message);
+ self::assertIsReadable($file, $message);
+ }
+
+ /**
+ * Asserts that a file exists and is not readable.
+ *
+ * @param string $file
+ * @param string $message
+ */
+ public static function assertFileNotIsReadable($file, $message = '')
+ {
+ self::assertFileExists($file, $message);
+ self::assertNotIsReadable($file, $message);
+ }
+
+ /**
+ * Asserts that a file exists and is writable.
+ *
+ * @param string $file
+ * @param string $message
+ */
+ public static function assertFileIsWritable($file, $message = '')
+ {
+ self::assertFileExists($file, $message);
+ self::assertIsWritable($file, $message);
+ }
+
+ /**
+ * Asserts that a file exists and is not writable.
+ *
+ * @param string $file
+ * @param string $message
+ */
+ public static function assertFileNotIsWritable($file, $message = '')
+ {
+ self::assertFileExists($file, $message);
+ self::assertNotIsWritable($file, $message);
+ }
+
+ /**
+ * Asserts that a condition is true.
+ *
+ * @param bool $condition
+ * @param string $message
+ *
+ * @throws PHPUnit_Framework_AssertionFailedError
+ */
+ public static function assertTrue($condition, $message = '')
+ {
+ static::assertThat($condition, static::isTrue(), $message);
+ }
+
+ /**
+ * Asserts that a condition is not true.
+ *
+ * @param bool $condition
+ * @param string $message
+ *
+ * @throws PHPUnit_Framework_AssertionFailedError
+ */
+ public static function assertNotTrue($condition, $message = '')
+ {
+ static::assertThat($condition, static::logicalNot(static::isTrue()), $message);
+ }
+
+ /**
+ * Asserts that a condition is false.
+ *
+ * @param bool $condition
+ * @param string $message
+ *
+ * @throws PHPUnit_Framework_AssertionFailedError
+ */
+ public static function assertFalse($condition, $message = '')
+ {
+ static::assertThat($condition, static::isFalse(), $message);
+ }
+
+ /**
+ * Asserts that a condition is not false.
+ *
+ * @param bool $condition
+ * @param string $message
+ *
+ * @throws PHPUnit_Framework_AssertionFailedError
+ */
+ public static function assertNotFalse($condition, $message = '')
+ {
+ static::assertThat($condition, static::logicalNot(static::isFalse()), $message);
+ }
+
+ /**
+ * Asserts that a variable is null.
+ *
+ * @param mixed $actual
+ * @param string $message
+ */
+ public static function assertNull($actual, $message = '')
+ {
+ static::assertThat($actual, static::isNull(), $message);
+ }
+
+ /**
+ * Asserts that a variable is not null.
+ *
+ * @param mixed $actual
+ * @param string $message
+ */
+ public static function assertNotNull($actual, $message = '')
+ {
+ static::assertThat($actual, static::logicalNot(static::isNull()), $message);
+ }
+
+ /**
+ * Asserts that a variable is finite.
+ *
+ * @param mixed $actual
+ * @param string $message
+ */
+ public static function assertFinite($actual, $message = '')
+ {
+ static::assertThat($actual, static::isFinite(), $message);
+ }
+
+ /**
+ * Asserts that a variable is infinite.
+ *
+ * @param mixed $actual
+ * @param string $message
+ */
+ public static function assertInfinite($actual, $message = '')
+ {
+ static::assertThat($actual, static::isInfinite(), $message);
+ }
+
+ /**
+ * Asserts that a variable is nan.
+ *
+ * @param mixed $actual
+ * @param string $message
+ */
+ public static function assertNan($actual, $message = '')
+ {
+ static::assertThat($actual, static::isNan(), $message);
+ }
+
+ /**
+ * Asserts that a class has a specified attribute.
+ *
+ * @param string $attributeName
+ * @param string $className
+ * @param string $message
+ */
+ public static function assertClassHasAttribute($attributeName, $className, $message = '')
+ {
+ if (!is_string($attributeName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
+ }
+
+ if (!is_string($className) || !class_exists($className)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name', $className);
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_ClassHasAttribute(
+ $attributeName
+ );
+
+ static::assertThat($className, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a class does not have a specified attribute.
+ *
+ * @param string $attributeName
+ * @param string $className
+ * @param string $message
+ */
+ public static function assertClassNotHasAttribute($attributeName, $className, $message = '')
+ {
+ if (!is_string($attributeName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
+ }
+
+ if (!is_string($className) || !class_exists($className)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name', $className);
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_ClassHasAttribute($attributeName)
+ );
+
+ static::assertThat($className, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a class has a specified static attribute.
+ *
+ * @param string $attributeName
+ * @param string $className
+ * @param string $message
+ */
+ public static function assertClassHasStaticAttribute($attributeName, $className, $message = '')
+ {
+ if (!is_string($attributeName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
+ }
+
+ if (!is_string($className) || !class_exists($className)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name', $className);
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_ClassHasStaticAttribute(
+ $attributeName
+ );
+
+ static::assertThat($className, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a class does not have a specified static attribute.
+ *
+ * @param string $attributeName
+ * @param string $className
+ * @param string $message
+ */
+ public static function assertClassNotHasStaticAttribute($attributeName, $className, $message = '')
+ {
+ if (!is_string($attributeName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
+ }
+
+ if (!is_string($className) || !class_exists($className)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name', $className);
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_ClassHasStaticAttribute(
+ $attributeName
+ )
+ );
+
+ static::assertThat($className, $constraint, $message);
+ }
+
+ /**
+ * Asserts that an object has a specified attribute.
+ *
+ * @param string $attributeName
+ * @param object $object
+ * @param string $message
+ */
+ public static function assertObjectHasAttribute($attributeName, $object, $message = '')
+ {
+ if (!is_string($attributeName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
+ }
+
+ if (!is_object($object)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'object');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_ObjectHasAttribute(
+ $attributeName
+ );
+
+ static::assertThat($object, $constraint, $message);
+ }
+
+ /**
+ * Asserts that an object does not have a specified attribute.
+ *
+ * @param string $attributeName
+ * @param object $object
+ * @param string $message
+ */
+ public static function assertObjectNotHasAttribute($attributeName, $object, $message = '')
+ {
+ if (!is_string($attributeName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
+ }
+
+ if (!is_object($object)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'object');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_ObjectHasAttribute($attributeName)
+ );
+
+ static::assertThat($object, $constraint, $message);
+ }
+
+ /**
+ * Asserts that two variables have the same type and value.
+ * Used on objects, it asserts that two variables reference
+ * the same object.
+ *
+ * @param mixed $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+ public static function assertSame($expected, $actual, $message = '')
+ {
+ if (is_bool($expected) && is_bool($actual)) {
+ static::assertEquals($expected, $actual, $message);
+ } else {
+ $constraint = new PHPUnit_Framework_Constraint_IsIdentical(
+ $expected
+ );
+
+ static::assertThat($actual, $constraint, $message);
+ }
+ }
+
+ /**
+ * Asserts that a variable and an attribute of an object have the same type
+ * and value.
+ *
+ * @param mixed $expected
+ * @param string $actualAttributeName
+ * @param string|object $actualClassOrObject
+ * @param string $message
+ */
+ public static function assertAttributeSame($expected, $actualAttributeName, $actualClassOrObject, $message = '')
+ {
+ static::assertSame(
+ $expected,
+ static::readAttribute($actualClassOrObject, $actualAttributeName),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that two variables do not have the same type and value.
+ * Used on objects, it asserts that two variables do not reference
+ * the same object.
+ *
+ * @param mixed $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+ public static function assertNotSame($expected, $actual, $message = '')
+ {
+ if (is_bool($expected) && is_bool($actual)) {
+ static::assertNotEquals($expected, $actual, $message);
+ } else {
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_IsIdentical($expected)
+ );
+
+ static::assertThat($actual, $constraint, $message);
+ }
+ }
+
+ /**
+ * Asserts that a variable and an attribute of an object do not have the
+ * same type and value.
+ *
+ * @param mixed $expected
+ * @param string $actualAttributeName
+ * @param string|object $actualClassOrObject
+ * @param string $message
+ */
+ public static function assertAttributeNotSame($expected, $actualAttributeName, $actualClassOrObject, $message = '')
+ {
+ static::assertNotSame(
+ $expected,
+ static::readAttribute($actualClassOrObject, $actualAttributeName),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is of a given type.
+ *
+ * @param string $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+ public static function assertInstanceOf($expected, $actual, $message = '')
+ {
+ if (!(is_string($expected) && (class_exists($expected) || interface_exists($expected)))) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'class or interface name');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_IsInstanceOf(
+ $expected
+ );
+
+ static::assertThat($actual, $constraint, $message);
+ }
+
+ /**
+ * Asserts that an attribute is of a given type.
+ *
+ * @param string $expected
+ * @param string $attributeName
+ * @param string|object $classOrObject
+ * @param string $message
+ */
+ public static function assertAttributeInstanceOf($expected, $attributeName, $classOrObject, $message = '')
+ {
+ static::assertInstanceOf(
+ $expected,
+ static::readAttribute($classOrObject, $attributeName),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is not of a given type.
+ *
+ * @param string $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+ public static function assertNotInstanceOf($expected, $actual, $message = '')
+ {
+ if (!(is_string($expected) && (class_exists($expected) || interface_exists($expected)))) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'class or interface name');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_IsInstanceOf($expected)
+ );
+
+ static::assertThat($actual, $constraint, $message);
+ }
+
+ /**
+ * Asserts that an attribute is of a given type.
+ *
+ * @param string $expected
+ * @param string $attributeName
+ * @param string|object $classOrObject
+ * @param string $message
+ */
+ public static function assertAttributeNotInstanceOf($expected, $attributeName, $classOrObject, $message = '')
+ {
+ static::assertNotInstanceOf(
+ $expected,
+ static::readAttribute($classOrObject, $attributeName),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is of a given type.
+ *
+ * @param string $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+ public static function assertInternalType($expected, $actual, $message = '')
+ {
+ if (!is_string($expected)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_IsType(
+ $expected
+ );
+
+ static::assertThat($actual, $constraint, $message);
+ }
+
+ /**
+ * Asserts that an attribute is of a given type.
+ *
+ * @param string $expected
+ * @param string $attributeName
+ * @param string|object $classOrObject
+ * @param string $message
+ */
+ public static function assertAttributeInternalType($expected, $attributeName, $classOrObject, $message = '')
+ {
+ static::assertInternalType(
+ $expected,
+ static::readAttribute($classOrObject, $attributeName),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a variable is not of a given type.
+ *
+ * @param string $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+ public static function assertNotInternalType($expected, $actual, $message = '')
+ {
+ if (!is_string($expected)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_IsType($expected)
+ );
+
+ static::assertThat($actual, $constraint, $message);
+ }
+
+ /**
+ * Asserts that an attribute is of a given type.
+ *
+ * @param string $expected
+ * @param string $attributeName
+ * @param string|object $classOrObject
+ * @param string $message
+ */
+ public static function assertAttributeNotInternalType($expected, $attributeName, $classOrObject, $message = '')
+ {
+ static::assertNotInternalType(
+ $expected,
+ static::readAttribute($classOrObject, $attributeName),
+ $message
+ );
+ }
+
+ /**
+ * Asserts that a string matches a given regular expression.
+ *
+ * @param string $pattern
+ * @param string $string
+ * @param string $message
+ */
+ public static function assertRegExp($pattern, $string, $message = '')
+ {
+ if (!is_string($pattern)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!is_string($string)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_PCREMatch($pattern);
+
+ static::assertThat($string, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a string does not match a given regular expression.
+ *
+ * @param string $pattern
+ * @param string $string
+ * @param string $message
+ */
+ public static function assertNotRegExp($pattern, $string, $message = '')
+ {
+ if (!is_string($pattern)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!is_string($string)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_PCREMatch($pattern)
+ );
+
+ static::assertThat($string, $constraint, $message);
+ }
+
+ /**
+ * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
+ * is the same.
+ *
+ * @param array|Countable|Traversable $expected
+ * @param array|Countable|Traversable $actual
+ * @param string $message
+ */
+ public static function assertSameSize($expected, $actual, $message = '')
+ {
+ if (!$expected instanceof Countable &&
+ !$expected instanceof Traversable &&
+ !is_array($expected)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'countable or traversable');
+ }
+
+ if (!$actual instanceof Countable &&
+ !$actual instanceof Traversable &&
+ !is_array($actual)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable');
+ }
+
+ static::assertThat(
+ $actual,
+ new PHPUnit_Framework_Constraint_SameSize($expected),
+ $message
+ );
+ }
+
+ /**
+ * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
+ * is not the same.
+ *
+ * @param array|Countable|Traversable $expected
+ * @param array|Countable|Traversable $actual
+ * @param string $message
+ */
+ public static function assertNotSameSize($expected, $actual, $message = '')
+ {
+ if (!$expected instanceof Countable &&
+ !$expected instanceof Traversable &&
+ !is_array($expected)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'countable or traversable');
+ }
+
+ if (!$actual instanceof Countable &&
+ !$actual instanceof Traversable &&
+ !is_array($actual)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_SameSize($expected)
+ );
+
+ static::assertThat($actual, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a string matches a given format string.
+ *
+ * @param string $format
+ * @param string $string
+ * @param string $message
+ */
+ public static function assertStringMatchesFormat($format, $string, $message = '')
+ {
+ if (!is_string($format)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!is_string($string)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_StringMatches($format);
+
+ static::assertThat($string, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a string does not match a given format string.
+ *
+ * @param string $format
+ * @param string $string
+ * @param string $message
+ */
+ public static function assertStringNotMatchesFormat($format, $string, $message = '')
+ {
+ if (!is_string($format)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!is_string($string)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_StringMatches($format)
+ );
+
+ static::assertThat($string, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a string matches a given format file.
+ *
+ * @param string $formatFile
+ * @param string $string
+ * @param string $message
+ */
+ public static function assertStringMatchesFormatFile($formatFile, $string, $message = '')
+ {
+ static::assertFileExists($formatFile, $message);
+
+ if (!is_string($string)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_StringMatches(
+ file_get_contents($formatFile)
+ );
+
+ static::assertThat($string, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a string does not match a given format string.
+ *
+ * @param string $formatFile
+ * @param string $string
+ * @param string $message
+ */
+ public static function assertStringNotMatchesFormatFile($formatFile, $string, $message = '')
+ {
+ static::assertFileExists($formatFile, $message);
+
+ if (!is_string($string)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_StringMatches(
+ file_get_contents($formatFile)
+ )
+ );
+
+ static::assertThat($string, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a string starts with a given prefix.
+ *
+ * @param string $prefix
+ * @param string $string
+ * @param string $message
+ */
+ public static function assertStringStartsWith($prefix, $string, $message = '')
+ {
+ if (!is_string($prefix)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!is_string($string)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_StringStartsWith(
+ $prefix
+ );
+
+ static::assertThat($string, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a string starts not with a given prefix.
+ *
+ * @param string $prefix
+ * @param string $string
+ * @param string $message
+ */
+ public static function assertStringStartsNotWith($prefix, $string, $message = '')
+ {
+ if (!is_string($prefix)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!is_string($string)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_StringStartsWith($prefix)
+ );
+
+ static::assertThat($string, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a string ends with a given suffix.
+ *
+ * @param string $suffix
+ * @param string $string
+ * @param string $message
+ */
+ public static function assertStringEndsWith($suffix, $string, $message = '')
+ {
+ if (!is_string($suffix)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!is_string($string)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_StringEndsWith($suffix);
+
+ static::assertThat($string, $constraint, $message);
+ }
+
+ /**
+ * Asserts that a string ends not with a given suffix.
+ *
+ * @param string $suffix
+ * @param string $string
+ * @param string $message
+ */
+ public static function assertStringEndsNotWith($suffix, $string, $message = '')
+ {
+ if (!is_string($suffix)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!is_string($string)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
+ }
+
+ $constraint = new PHPUnit_Framework_Constraint_Not(
+ new PHPUnit_Framework_Constraint_StringEndsWith($suffix)
+ );
+
+ static::assertThat($string, $constraint, $message);
+ }
+
+ /**
+ * Asserts that two XML files are equal.
+ *
+ * @param string $expectedFile
+ * @param string $actualFile
+ * @param string $message
+ */
+ public static function assertXmlFileEqualsXmlFile($expectedFile, $actualFile, $message = '')
+ {
+ $expected = PHPUnit_Util_XML::loadFile($expectedFile);
+ $actual = PHPUnit_Util_XML::loadFile($actualFile);
+
+ static::assertEquals($expected, $actual, $message);
+ }
+
+ /**
+ * Asserts that two XML files are not equal.
+ *
+ * @param string $expectedFile
+ * @param string $actualFile
+ * @param string $message
+ */
+ public static function assertXmlFileNotEqualsXmlFile($expectedFile, $actualFile, $message = '')
+ {
+ $expected = PHPUnit_Util_XML::loadFile($expectedFile);
+ $actual = PHPUnit_Util_XML::loadFile($actualFile);
+
+ static::assertNotEquals($expected, $actual, $message);
+ }
+
+ /**
+ * Asserts that two XML documents are equal.
+ *
+ * @param string $expectedFile
+ * @param string $actualXml
+ * @param string $message
+ */
+ public static function assertXmlStringEqualsXmlFile($expectedFile, $actualXml, $message = '')
+ {
+ $expected = PHPUnit_Util_XML::loadFile($expectedFile);
+ $actual = PHPUnit_Util_XML::load($actualXml);
+
+ static::assertEquals($expected, $actual, $message);
+ }
+
+ /**
+ * Asserts that two XML documents are not equal.
+ *
+ * @param string $expectedFile
+ * @param string $actualXml
+ * @param string $message
+ */
+ public static function assertXmlStringNotEqualsXmlFile($expectedFile, $actualXml, $message = '')
+ {
+ $expected = PHPUnit_Util_XML::loadFile($expectedFile);
+ $actual = PHPUnit_Util_XML::load($actualXml);
+
+ static::assertNotEquals($expected, $actual, $message);
+ }
+
+ /**
+ * Asserts that two XML documents are equal.
+ *
+ * @param string $expectedXml
+ * @param string $actualXml
+ * @param string $message
+ */
+ public static function assertXmlStringEqualsXmlString($expectedXml, $actualXml, $message = '')
+ {
+ $expected = PHPUnit_Util_XML::load($expectedXml);
+ $actual = PHPUnit_Util_XML::load($actualXml);
+
+ static::assertEquals($expected, $actual, $message);
+ }
+
+ /**
+ * Asserts that two XML documents are not equal.
+ *
+ * @param string $expectedXml
+ * @param string $actualXml
+ * @param string $message
+ */
+ public static function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, $message = '')
+ {
+ $expected = PHPUnit_Util_XML::load($expectedXml);
+ $actual = PHPUnit_Util_XML::load($actualXml);
+
+ static::assertNotEquals($expected, $actual, $message);
+ }
+
+ /**
+ * Asserts that a hierarchy of DOMElements matches.
+ *
+ * @param DOMElement $expectedElement
+ * @param DOMElement $actualElement
+ * @param bool $checkAttributes
+ * @param string $message
+ */
+ public static function assertEqualXMLStructure(DOMElement $expectedElement, DOMElement $actualElement, $checkAttributes = false, $message = '')
+ {
+ $tmp = new DOMDocument;
+ $expectedElement = $tmp->importNode($expectedElement, true);
+
+ $tmp = new DOMDocument;
+ $actualElement = $tmp->importNode($actualElement, true);
+
+ unset($tmp);
+
+ static::assertEquals(
+ $expectedElement->tagName,
+ $actualElement->tagName,
+ $message
+ );
+
+ if ($checkAttributes) {
+ static::assertEquals(
+ $expectedElement->attributes->length,
+ $actualElement->attributes->length,
+ sprintf(
+ '%s%sNumber of attributes on node "%s" does not match',
+ $message,
+ !empty($message) ? "\n" : '',
+ $expectedElement->tagName
+ )
+ );
+
+ for ($i = 0; $i < $expectedElement->attributes->length; $i++) {
+ $expectedAttribute = $expectedElement->attributes->item($i);
+ $actualAttribute = $actualElement->attributes->getNamedItem(
+ $expectedAttribute->name
+ );
+
+ if (!$actualAttribute) {
+ static::fail(
+ sprintf(
+ '%s%sCould not find attribute "%s" on node "%s"',
+ $message,
+ !empty($message) ? "\n" : '',
+ $expectedAttribute->name,
+ $expectedElement->tagName
+ )
+ );
+ }
+ }
+ }
+
+ PHPUnit_Util_XML::removeCharacterDataNodes($expectedElement);
+ PHPUnit_Util_XML::removeCharacterDataNodes($actualElement);
+
+ static::assertEquals(
+ $expectedElement->childNodes->length,
+ $actualElement->childNodes->length,
+ sprintf(
+ '%s%sNumber of child nodes of "%s" differs',
+ $message,
+ !empty($message) ? "\n" : '',
+ $expectedElement->tagName
+ )
+ );
+
+ for ($i = 0; $i < $expectedElement->childNodes->length; $i++) {
+ static::assertEqualXMLStructure(
+ $expectedElement->childNodes->item($i),
+ $actualElement->childNodes->item($i),
+ $checkAttributes,
+ $message
+ );
+ }
+ }
+
+ /**
+ * Evaluates a PHPUnit_Framework_Constraint matcher object.
+ *
+ * @param mixed $value
+ * @param PHPUnit_Framework_Constraint $constraint
+ * @param string $message
+ */
+ public static function assertThat($value, PHPUnit_Framework_Constraint $constraint, $message = '')
+ {
+ self::$count += count($constraint);
+
+ $constraint->evaluate($value, $message);
+ }
+
+ /**
+ * Asserts that a string is a valid JSON string.
+ *
+ * @param string $actualJson
+ * @param string $message
+ */
+ public static function assertJson($actualJson, $message = '')
+ {
+ if (!is_string($actualJson)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ static::assertThat($actualJson, static::isJson(), $message);
+ }
+
+ /**
+ * Asserts that two given JSON encoded objects or arrays are equal.
+ *
+ * @param string $expectedJson
+ * @param string $actualJson
+ * @param string $message
+ */
+ public static function assertJsonStringEqualsJsonString($expectedJson, $actualJson, $message = '')
+ {
+ static::assertJson($expectedJson, $message);
+ static::assertJson($actualJson, $message);
+
+ $expected = json_decode($expectedJson);
+ $actual = json_decode($actualJson);
+
+ static::assertEquals($expected, $actual, $message);
+ }
+
+ /**
+ * Asserts that two given JSON encoded objects or arrays are not equal.
+ *
+ * @param string $expectedJson
+ * @param string $actualJson
+ * @param string $message
+ */
+ public static function assertJsonStringNotEqualsJsonString($expectedJson, $actualJson, $message = '')
+ {
+ static::assertJson($expectedJson, $message);
+ static::assertJson($actualJson, $message);
+
+ $expected = json_decode($expectedJson);
+ $actual = json_decode($actualJson);
+
+ static::assertNotEquals($expected, $actual, $message);
+ }
+
+ /**
+ * Asserts that the generated JSON encoded object and the content of the given file are equal.
+ *
+ * @param string $expectedFile
+ * @param string $actualJson
+ * @param string $message
+ */
+ public static function assertJsonStringEqualsJsonFile($expectedFile, $actualJson, $message = '')
+ {
+ static::assertFileExists($expectedFile, $message);
+ $expectedJson = file_get_contents($expectedFile);
+
+ static::assertJson($expectedJson, $message);
+ static::assertJson($actualJson, $message);
+
+ // call constraint
+ $constraint = new PHPUnit_Framework_Constraint_JsonMatches(
+ $expectedJson
+ );
+
+ static::assertThat($actualJson, $constraint, $message);
+ }
+
+ /**
+ * Asserts that the generated JSON encoded object and the content of the given file are not equal.
+ *
+ * @param string $expectedFile
+ * @param string $actualJson
+ * @param string $message
+ */
+ public static function assertJsonStringNotEqualsJsonFile($expectedFile, $actualJson, $message = '')
+ {
+ static::assertFileExists($expectedFile, $message);
+ $expectedJson = file_get_contents($expectedFile);
+
+ static::assertJson($expectedJson, $message);
+ static::assertJson($actualJson, $message);
+
+ // call constraint
+ $constraint = new PHPUnit_Framework_Constraint_JsonMatches(
+ $expectedJson
+ );
+
+ static::assertThat($actualJson, new PHPUnit_Framework_Constraint_Not($constraint), $message);
+ }
+
+ /**
+ * Asserts that two JSON files are equal.
+ *
+ * @param string $expectedFile
+ * @param string $actualFile
+ * @param string $message
+ */
+ public static function assertJsonFileEqualsJsonFile($expectedFile, $actualFile, $message = '')
+ {
+ static::assertFileExists($expectedFile, $message);
+ static::assertFileExists($actualFile, $message);
+
+ $actualJson = file_get_contents($actualFile);
+ $expectedJson = file_get_contents($expectedFile);
+
+ static::assertJson($expectedJson, $message);
+ static::assertJson($actualJson, $message);
+
+ // call constraint
+ $constraintExpected = new PHPUnit_Framework_Constraint_JsonMatches(
+ $expectedJson
+ );
+
+ $constraintActual = new PHPUnit_Framework_Constraint_JsonMatches($actualJson);
+
+ static::assertThat($expectedJson, $constraintActual, $message);
+ static::assertThat($actualJson, $constraintExpected, $message);
+ }
+
+ /**
+ * Asserts that two JSON files are not equal.
+ *
+ * @param string $expectedFile
+ * @param string $actualFile
+ * @param string $message
+ */
+ public static function assertJsonFileNotEqualsJsonFile($expectedFile, $actualFile, $message = '')
+ {
+ static::assertFileExists($expectedFile, $message);
+ static::assertFileExists($actualFile, $message);
+
+ $actualJson = file_get_contents($actualFile);
+ $expectedJson = file_get_contents($expectedFile);
+
+ static::assertJson($expectedJson, $message);
+ static::assertJson($actualJson, $message);
+
+ // call constraint
+ $constraintExpected = new PHPUnit_Framework_Constraint_JsonMatches(
+ $expectedJson
+ );
+
+ $constraintActual = new PHPUnit_Framework_Constraint_JsonMatches($actualJson);
+
+ static::assertThat($expectedJson, new PHPUnit_Framework_Constraint_Not($constraintActual), $message);
+ static::assertThat($actualJson, new PHPUnit_Framework_Constraint_Not($constraintExpected), $message);
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_And matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_And
+ */
+ public static function logicalAnd()
+ {
+ $constraints = func_get_args();
+
+ $constraint = new PHPUnit_Framework_Constraint_And;
+ $constraint->setConstraints($constraints);
+
+ return $constraint;
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_Or matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_Or
+ */
+ public static function logicalOr()
+ {
+ $constraints = func_get_args();
+
+ $constraint = new PHPUnit_Framework_Constraint_Or;
+ $constraint->setConstraints($constraints);
+
+ return $constraint;
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_Not matcher object.
+ *
+ * @param PHPUnit_Framework_Constraint $constraint
+ *
+ * @return PHPUnit_Framework_Constraint_Not
+ */
+ public static function logicalNot(PHPUnit_Framework_Constraint $constraint)
+ {
+ return new PHPUnit_Framework_Constraint_Not($constraint);
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_Xor matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_Xor
+ */
+ public static function logicalXor()
+ {
+ $constraints = func_get_args();
+
+ $constraint = new PHPUnit_Framework_Constraint_Xor;
+ $constraint->setConstraints($constraints);
+
+ return $constraint;
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_IsAnything matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_IsAnything
+ */
+ public static function anything()
+ {
+ return new PHPUnit_Framework_Constraint_IsAnything;
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_IsTrue matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_IsTrue
+ */
+ public static function isTrue()
+ {
+ return new PHPUnit_Framework_Constraint_IsTrue;
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_Callback matcher object.
+ *
+ * @param callable $callback
+ *
+ * @return PHPUnit_Framework_Constraint_Callback
+ */
+ public static function callback($callback)
+ {
+ return new PHPUnit_Framework_Constraint_Callback($callback);
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_IsFalse matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_IsFalse
+ */
+ public static function isFalse()
+ {
+ return new PHPUnit_Framework_Constraint_IsFalse;
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_IsJson matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_IsJson
+ */
+ public static function isJson()
+ {
+ return new PHPUnit_Framework_Constraint_IsJson;
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_IsNull matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_IsNull
+ */
+ public static function isNull()
+ {
+ return new PHPUnit_Framework_Constraint_IsNull;
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_IsFinite matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_IsFinite
+ */
+ public static function isFinite()
+ {
+ return new PHPUnit_Framework_Constraint_IsFinite;
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_IsInfinite matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_IsInfinite
+ */
+ public static function isInfinite()
+ {
+ return new PHPUnit_Framework_Constraint_IsInfinite;
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_IsNan matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_IsNan
+ */
+ public static function isNan()
+ {
+ return new PHPUnit_Framework_Constraint_IsNan;
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_Attribute matcher object.
+ *
+ * @param PHPUnit_Framework_Constraint $constraint
+ * @param string $attributeName
+ *
+ * @return PHPUnit_Framework_Constraint_Attribute
+ */
+ public static function attribute(PHPUnit_Framework_Constraint $constraint, $attributeName)
+ {
+ return new PHPUnit_Framework_Constraint_Attribute(
+ $constraint,
+ $attributeName
+ );
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_TraversableContains matcher
+ * object.
+ *
+ * @param mixed $value
+ * @param bool $checkForObjectIdentity
+ * @param bool $checkForNonObjectIdentity
+ *
+ * @return PHPUnit_Framework_Constraint_TraversableContains
+ */
+ public static function contains($value, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
+ {
+ return new PHPUnit_Framework_Constraint_TraversableContains($value, $checkForObjectIdentity, $checkForNonObjectIdentity);
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher
+ * object.
+ *
+ * @param string $type
+ *
+ * @return PHPUnit_Framework_Constraint_TraversableContainsOnly
+ */
+ public static function containsOnly($type)
+ {
+ return new PHPUnit_Framework_Constraint_TraversableContainsOnly($type);
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher
+ * object.
+ *
+ * @param string $classname
+ *
+ * @return PHPUnit_Framework_Constraint_TraversableContainsOnly
+ */
+ public static function containsOnlyInstancesOf($classname)
+ {
+ return new PHPUnit_Framework_Constraint_TraversableContainsOnly($classname, false);
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_ArrayHasKey matcher object.
+ *
+ * @param mixed $key
+ *
+ * @return PHPUnit_Framework_Constraint_ArrayHasKey
+ */
+ public static function arrayHasKey($key)
+ {
+ return new PHPUnit_Framework_Constraint_ArrayHasKey($key);
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object.
+ *
+ * @param mixed $value
+ * @param float $delta
+ * @param int $maxDepth
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ *
+ * @return PHPUnit_Framework_Constraint_IsEqual
+ */
+ public static function equalTo($value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
+ {
+ return new PHPUnit_Framework_Constraint_IsEqual(
+ $value,
+ $delta,
+ $maxDepth,
+ $canonicalize,
+ $ignoreCase
+ );
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object
+ * that is wrapped in a PHPUnit_Framework_Constraint_Attribute matcher
+ * object.
+ *
+ * @param string $attributeName
+ * @param mixed $value
+ * @param float $delta
+ * @param int $maxDepth
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ *
+ * @return PHPUnit_Framework_Constraint_Attribute
+ */
+ public static function attributeEqualTo($attributeName, $value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
+ {
+ return static::attribute(
+ static::equalTo(
+ $value,
+ $delta,
+ $maxDepth,
+ $canonicalize,
+ $ignoreCase
+ ),
+ $attributeName
+ );
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_IsEmpty matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_IsEmpty
+ */
+ public static function isEmpty()
+ {
+ return new PHPUnit_Framework_Constraint_IsEmpty;
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_IsWritable matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_IsWritable
+ */
+ public static function isWritable()
+ {
+ return new PHPUnit_Framework_Constraint_IsWritable;
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_IsReadable matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_IsReadable
+ */
+ public static function isReadable()
+ {
+ return new PHPUnit_Framework_Constraint_IsReadable;
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_DirectoryExists matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_DirectoryExists
+ */
+ public static function directoryExists()
+ {
+ return new PHPUnit_Framework_Constraint_DirectoryExists;
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_FileExists matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_FileExists
+ */
+ public static function fileExists()
+ {
+ return new PHPUnit_Framework_Constraint_FileExists;
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_GreaterThan matcher object.
+ *
+ * @param mixed $value
+ *
+ * @return PHPUnit_Framework_Constraint_GreaterThan
+ */
+ public static function greaterThan($value)
+ {
+ return new PHPUnit_Framework_Constraint_GreaterThan($value);
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps
+ * a PHPUnit_Framework_Constraint_IsEqual and a
+ * PHPUnit_Framework_Constraint_GreaterThan matcher object.
+ *
+ * @param mixed $value
+ *
+ * @return PHPUnit_Framework_Constraint_Or
+ */
+ public static function greaterThanOrEqual($value)
+ {
+ return static::logicalOr(
+ new PHPUnit_Framework_Constraint_IsEqual($value),
+ new PHPUnit_Framework_Constraint_GreaterThan($value)
+ );
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_ClassHasAttribute matcher object.
+ *
+ * @param string $attributeName
+ *
+ * @return PHPUnit_Framework_Constraint_ClassHasAttribute
+ */
+ public static function classHasAttribute($attributeName)
+ {
+ return new PHPUnit_Framework_Constraint_ClassHasAttribute(
+ $attributeName
+ );
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_ClassHasStaticAttribute matcher
+ * object.
+ *
+ * @param string $attributeName
+ *
+ * @return PHPUnit_Framework_Constraint_ClassHasStaticAttribute
+ */
+ public static function classHasStaticAttribute($attributeName)
+ {
+ return new PHPUnit_Framework_Constraint_ClassHasStaticAttribute(
+ $attributeName
+ );
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_ObjectHasAttribute matcher object.
+ *
+ * @param string $attributeName
+ *
+ * @return PHPUnit_Framework_Constraint_ObjectHasAttribute
+ */
+ public static function objectHasAttribute($attributeName)
+ {
+ return new PHPUnit_Framework_Constraint_ObjectHasAttribute(
+ $attributeName
+ );
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_IsIdentical matcher object.
+ *
+ * @param mixed $value
+ *
+ * @return PHPUnit_Framework_Constraint_IsIdentical
+ */
+ public static function identicalTo($value)
+ {
+ return new PHPUnit_Framework_Constraint_IsIdentical($value);
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_IsInstanceOf matcher object.
+ *
+ * @param string $className
+ *
+ * @return PHPUnit_Framework_Constraint_IsInstanceOf
+ */
+ public static function isInstanceOf($className)
+ {
+ return new PHPUnit_Framework_Constraint_IsInstanceOf($className);
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_IsType matcher object.
+ *
+ * @param string $type
+ *
+ * @return PHPUnit_Framework_Constraint_IsType
+ */
+ public static function isType($type)
+ {
+ return new PHPUnit_Framework_Constraint_IsType($type);
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_LessThan matcher object.
+ *
+ * @param mixed $value
+ *
+ * @return PHPUnit_Framework_Constraint_LessThan
+ */
+ public static function lessThan($value)
+ {
+ return new PHPUnit_Framework_Constraint_LessThan($value);
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps
+ * a PHPUnit_Framework_Constraint_IsEqual and a
+ * PHPUnit_Framework_Constraint_LessThan matcher object.
+ *
+ * @param mixed $value
+ *
+ * @return PHPUnit_Framework_Constraint_Or
+ */
+ public static function lessThanOrEqual($value)
+ {
+ return static::logicalOr(
+ new PHPUnit_Framework_Constraint_IsEqual($value),
+ new PHPUnit_Framework_Constraint_LessThan($value)
+ );
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_PCREMatch matcher object.
+ *
+ * @param string $pattern
+ *
+ * @return PHPUnit_Framework_Constraint_PCREMatch
+ */
+ public static function matchesRegularExpression($pattern)
+ {
+ return new PHPUnit_Framework_Constraint_PCREMatch($pattern);
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_StringMatches matcher object.
+ *
+ * @param string $string
+ *
+ * @return PHPUnit_Framework_Constraint_StringMatches
+ */
+ public static function matches($string)
+ {
+ return new PHPUnit_Framework_Constraint_StringMatches($string);
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_StringStartsWith matcher object.
+ *
+ * @param mixed $prefix
+ *
+ * @return PHPUnit_Framework_Constraint_StringStartsWith
+ */
+ public static function stringStartsWith($prefix)
+ {
+ return new PHPUnit_Framework_Constraint_StringStartsWith($prefix);
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_StringContains matcher object.
+ *
+ * @param string $string
+ * @param bool $case
+ *
+ * @return PHPUnit_Framework_Constraint_StringContains
+ */
+ public static function stringContains($string, $case = true)
+ {
+ return new PHPUnit_Framework_Constraint_StringContains($string, $case);
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_StringEndsWith matcher object.
+ *
+ * @param mixed $suffix
+ *
+ * @return PHPUnit_Framework_Constraint_StringEndsWith
+ */
+ public static function stringEndsWith($suffix)
+ {
+ return new PHPUnit_Framework_Constraint_StringEndsWith($suffix);
+ }
+
+ /**
+ * Returns a PHPUnit_Framework_Constraint_Count matcher object.
+ *
+ * @param int $count
+ *
+ * @return PHPUnit_Framework_Constraint_Count
+ */
+ public static function countOf($count)
+ {
+ return new PHPUnit_Framework_Constraint_Count($count);
+ }
+ /**
+ * Fails a test with the given message.
+ *
+ * @param string $message
+ *
+ * @throws PHPUnit_Framework_AssertionFailedError
+ */
+ public static function fail($message = '')
+ {
+ throw new PHPUnit_Framework_AssertionFailedError($message);
+ }
+
+ /**
+ * Returns the value of an attribute of a class or an object.
+ * This also works for attributes that are declared protected or private.
+ *
+ * @param string|object $classOrObject
+ * @param string $attributeName
+ *
+ * @return mixed
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public static function readAttribute($classOrObject, $attributeName)
+ {
+ if (!is_string($attributeName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
+ }
+
+ if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'valid attribute name');
+ }
+
+ if (is_string($classOrObject)) {
+ if (!class_exists($classOrObject)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 1,
+ 'class name'
+ );
+ }
+
+ return static::getStaticAttribute(
+ $classOrObject,
+ $attributeName
+ );
+ } elseif (is_object($classOrObject)) {
+ return static::getObjectAttribute(
+ $classOrObject,
+ $attributeName
+ );
+ } else {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 1,
+ 'class name or object'
+ );
+ }
+ }
+
+ /**
+ * Returns the value of a static attribute.
+ * This also works for attributes that are declared protected or private.
+ *
+ * @param string $className
+ * @param string $attributeName
+ *
+ * @return mixed
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public static function getStaticAttribute($className, $attributeName)
+ {
+ if (!is_string($className)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (!class_exists($className)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'class name');
+ }
+
+ if (!is_string($attributeName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
+ }
+
+ if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'valid attribute name');
+ }
+
+ $class = new ReflectionClass($className);
+
+ while ($class) {
+ $attributes = $class->getStaticProperties();
+
+ if (array_key_exists($attributeName, $attributes)) {
+ return $attributes[$attributeName];
+ }
+
+ $class = $class->getParentClass();
+ }
+
+ throw new PHPUnit_Framework_Exception(
+ sprintf(
+ 'Attribute "%s" not found in class.',
+ $attributeName
+ )
+ );
+ }
+
+ /**
+ * Returns the value of an object's attribute.
+ * This also works for attributes that are declared protected or private.
+ *
+ * @param object $object
+ * @param string $attributeName
+ *
+ * @return mixed
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public static function getObjectAttribute($object, $attributeName)
+ {
+ if (!is_object($object)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'object');
+ }
+
+ if (!is_string($attributeName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
+ }
+
+ if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'valid attribute name');
+ }
+
+ try {
+ $attribute = new ReflectionProperty($object, $attributeName);
+ } catch (ReflectionException $e) {
+ $reflector = new ReflectionObject($object);
+
+ while ($reflector = $reflector->getParentClass()) {
+ try {
+ $attribute = $reflector->getProperty($attributeName);
+ break;
+ } catch (ReflectionException $e) {
+ }
+ }
+ }
+
+ if (isset($attribute)) {
+ if (!$attribute || $attribute->isPublic()) {
+ return $object->$attributeName;
+ }
+
+ $attribute->setAccessible(true);
+ $value = $attribute->getValue($object);
+ $attribute->setAccessible(false);
+
+ return $value;
+ }
+
+ throw new PHPUnit_Framework_Exception(
+ sprintf(
+ 'Attribute "%s" not found in object.',
+ $attributeName
+ )
+ );
+ }
+
+ /**
+ * Mark the test as incomplete.
+ *
+ * @param string $message
+ *
+ * @throws PHPUnit_Framework_IncompleteTestError
+ */
+ public static function markTestIncomplete($message = '')
+ {
+ throw new PHPUnit_Framework_IncompleteTestError($message);
+ }
+
+ /**
+ * Mark the test as skipped.
+ *
+ * @param string $message
+ *
+ * @throws PHPUnit_Framework_SkippedTestError
+ */
+ public static function markTestSkipped($message = '')
+ {
+ throw new PHPUnit_Framework_SkippedTestError($message);
+ }
+
+ /**
+ * Return the current assertion count.
+ *
+ * @return int
+ */
+ public static function getCount()
+ {
+ return self::$count;
+ }
+
+ /**
+ * Reset the assertion counter.
+ */
+ public static function resetCount()
+ {
+ self::$count = 0;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Assert/Functions.php b/vendor/phpunit/phpunit/src/Framework/Assert/Functions.php
new file mode 100644
index 0000000..c048e14
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Assert/Functions.php
@@ -0,0 +1,2174 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Returns a matcher that matches when the method is executed
+ * zero or more times.
+ *
+ * @return PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount
+ */
+function any()
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_TestCase::any',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_IsAnything matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_IsAnything
+ */
+function anything()
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::anything',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_ArrayHasKey matcher object.
+ *
+ * @param mixed $key
+ *
+ * @return PHPUnit_Framework_Constraint_ArrayHasKey
+ */
+function arrayHasKey($key)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::arrayHasKey',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that an array has a specified key.
+ *
+ * @param mixed $key
+ * @param array|ArrayAccess $array
+ * @param string $message
+ */
+function assertArrayHasKey($key, $array, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertArrayHasKey',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that an array has a specified subset.
+ *
+ * @param array|ArrayAccess $subset
+ * @param array|ArrayAccess $array
+ * @param bool $strict Check for object identity
+ * @param string $message
+ */
+function assertArraySubset($subset, $array, $strict = false, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertArraySubset',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that an array does not have a specified key.
+ *
+ * @param mixed $key
+ * @param array|ArrayAccess $array
+ * @param string $message
+ */
+function assertArrayNotHasKey($key, $array, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertArrayNotHasKey',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a haystack that is stored in a static attribute of a class
+ * or an attribute of an object contains a needle.
+ *
+ * @param mixed $needle
+ * @param string $haystackAttributeName
+ * @param mixed $haystackClassOrObject
+ * @param string $message
+ * @param bool $ignoreCase
+ * @param bool $checkForObjectIdentity
+ * @param bool $checkForNonObjectIdentity
+ */
+function assertAttributeContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeContains',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a haystack that is stored in a static attribute of a class
+ * or an attribute of an object contains only values of a given type.
+ *
+ * @param string $type
+ * @param string $haystackAttributeName
+ * @param mixed $haystackClassOrObject
+ * @param bool $isNativeType
+ * @param string $message
+ */
+function assertAttributeContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = null, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeContainsOnly',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts the number of elements of an array, Countable or Traversable
+ * that is stored in an attribute.
+ *
+ * @param int $expectedCount
+ * @param string $haystackAttributeName
+ * @param mixed $haystackClassOrObject
+ * @param string $message
+ */
+function assertAttributeCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeCount',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a static attribute of a class or an attribute of an object
+ * is empty.
+ *
+ * @param string $haystackAttributeName
+ * @param mixed $haystackClassOrObject
+ * @param string $message
+ */
+function assertAttributeEmpty($haystackAttributeName, $haystackClassOrObject, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeEmpty',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a variable is equal to an attribute of an object.
+ *
+ * @param mixed $expected
+ * @param string $actualAttributeName
+ * @param string $actualClassOrObject
+ * @param string $message
+ * @param float $delta
+ * @param int $maxDepth
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ */
+function assertAttributeEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeEquals',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that an attribute is greater than another value.
+ *
+ * @param mixed $expected
+ * @param string $actualAttributeName
+ * @param string $actualClassOrObject
+ * @param string $message
+ */
+function assertAttributeGreaterThan($expected, $actualAttributeName, $actualClassOrObject, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeGreaterThan',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that an attribute is greater than or equal to another value.
+ *
+ * @param mixed $expected
+ * @param string $actualAttributeName
+ * @param string $actualClassOrObject
+ * @param string $message
+ */
+function assertAttributeGreaterThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeGreaterThanOrEqual',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that an attribute is of a given type.
+ *
+ * @param string $expected
+ * @param string $attributeName
+ * @param mixed $classOrObject
+ * @param string $message
+ */
+function assertAttributeInstanceOf($expected, $attributeName, $classOrObject, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeInstanceOf',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that an attribute is of a given type.
+ *
+ * @param string $expected
+ * @param string $attributeName
+ * @param mixed $classOrObject
+ * @param string $message
+ */
+function assertAttributeInternalType($expected, $attributeName, $classOrObject, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeInternalType',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that an attribute is smaller than another value.
+ *
+ * @param mixed $expected
+ * @param string $actualAttributeName
+ * @param string $actualClassOrObject
+ * @param string $message
+ */
+function assertAttributeLessThan($expected, $actualAttributeName, $actualClassOrObject, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeLessThan',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that an attribute is smaller than or equal to another value.
+ *
+ * @param mixed $expected
+ * @param string $actualAttributeName
+ * @param string $actualClassOrObject
+ * @param string $message
+ */
+function assertAttributeLessThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeLessThanOrEqual',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a haystack that is stored in a static attribute of a class
+ * or an attribute of an object does not contain a needle.
+ *
+ * @param mixed $needle
+ * @param string $haystackAttributeName
+ * @param mixed $haystackClassOrObject
+ * @param string $message
+ * @param bool $ignoreCase
+ * @param bool $checkForObjectIdentity
+ * @param bool $checkForNonObjectIdentity
+ */
+function assertAttributeNotContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeNotContains',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a haystack that is stored in a static attribute of a class
+ * or an attribute of an object does not contain only values of a given
+ * type.
+ *
+ * @param string $type
+ * @param string $haystackAttributeName
+ * @param mixed $haystackClassOrObject
+ * @param bool $isNativeType
+ * @param string $message
+ */
+function assertAttributeNotContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = null, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeNotContainsOnly',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts the number of elements of an array, Countable or Traversable
+ * that is stored in an attribute.
+ *
+ * @param int $expectedCount
+ * @param string $haystackAttributeName
+ * @param mixed $haystackClassOrObject
+ * @param string $message
+ */
+function assertAttributeNotCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeNotCount',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a static attribute of a class or an attribute of an object
+ * is not empty.
+ *
+ * @param string $haystackAttributeName
+ * @param mixed $haystackClassOrObject
+ * @param string $message
+ */
+function assertAttributeNotEmpty($haystackAttributeName, $haystackClassOrObject, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeNotEmpty',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a variable is not equal to an attribute of an object.
+ *
+ * @param mixed $expected
+ * @param string $actualAttributeName
+ * @param string $actualClassOrObject
+ * @param string $message
+ * @param float $delta
+ * @param int $maxDepth
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ */
+function assertAttributeNotEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeNotEquals',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that an attribute is of a given type.
+ *
+ * @param string $expected
+ * @param string $attributeName
+ * @param mixed $classOrObject
+ * @param string $message
+ */
+function assertAttributeNotInstanceOf($expected, $attributeName, $classOrObject, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeNotInstanceOf',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that an attribute is of a given type.
+ *
+ * @param string $expected
+ * @param string $attributeName
+ * @param mixed $classOrObject
+ * @param string $message
+ */
+function assertAttributeNotInternalType($expected, $attributeName, $classOrObject, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeNotInternalType',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a variable and an attribute of an object do not have the
+ * same type and value.
+ *
+ * @param mixed $expected
+ * @param string $actualAttributeName
+ * @param object $actualClassOrObject
+ * @param string $message
+ */
+function assertAttributeNotSame($expected, $actualAttributeName, $actualClassOrObject, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeNotSame',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a variable and an attribute of an object have the same type
+ * and value.
+ *
+ * @param mixed $expected
+ * @param string $actualAttributeName
+ * @param object $actualClassOrObject
+ * @param string $message
+ */
+function assertAttributeSame($expected, $actualAttributeName, $actualClassOrObject, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertAttributeSame',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a class has a specified attribute.
+ *
+ * @param string $attributeName
+ * @param string $className
+ * @param string $message
+ */
+function assertClassHasAttribute($attributeName, $className, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertClassHasAttribute',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a class has a specified static attribute.
+ *
+ * @param string $attributeName
+ * @param string $className
+ * @param string $message
+ */
+function assertClassHasStaticAttribute($attributeName, $className, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertClassHasStaticAttribute',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a class does not have a specified attribute.
+ *
+ * @param string $attributeName
+ * @param string $className
+ * @param string $message
+ */
+function assertClassNotHasAttribute($attributeName, $className, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertClassNotHasAttribute',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a class does not have a specified static attribute.
+ *
+ * @param string $attributeName
+ * @param string $className
+ * @param string $message
+ */
+function assertClassNotHasStaticAttribute($attributeName, $className, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertClassNotHasStaticAttribute',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a haystack contains a needle.
+ *
+ * @param mixed $needle
+ * @param mixed $haystack
+ * @param string $message
+ * @param bool $ignoreCase
+ * @param bool $checkForObjectIdentity
+ * @param bool $checkForNonObjectIdentity
+ */
+function assertContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertContains',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a haystack contains only values of a given type.
+ *
+ * @param string $type
+ * @param mixed $haystack
+ * @param bool $isNativeType
+ * @param string $message
+ */
+function assertContainsOnly($type, $haystack, $isNativeType = null, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertContainsOnly',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a haystack contains only instances of a given classname
+ *
+ * @param string $classname
+ * @param array|Traversable $haystack
+ * @param string $message
+ */
+function assertContainsOnlyInstancesOf($classname, $haystack, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertContainsOnlyInstancesOf',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts the number of elements of an array, Countable or Traversable.
+ *
+ * @param int $expectedCount
+ * @param mixed $haystack
+ * @param string $message
+ */
+function assertCount($expectedCount, $haystack, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertCount',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a variable is empty.
+ *
+ * @param mixed $actual
+ * @param string $message
+ *
+ * @throws PHPUnit_Framework_AssertionFailedError
+ */
+function assertEmpty($actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertEmpty',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a hierarchy of DOMElements matches.
+ *
+ * @param DOMElement $expectedElement
+ * @param DOMElement $actualElement
+ * @param bool $checkAttributes
+ * @param string $message
+ */
+function assertEqualXMLStructure(DOMElement $expectedElement, DOMElement $actualElement, $checkAttributes = false, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertEqualXMLStructure',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that two variables are equal.
+ *
+ * @param mixed $expected
+ * @param mixed $actual
+ * @param string $message
+ * @param float $delta
+ * @param int $maxDepth
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ */
+function assertEquals($expected, $actual, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertEquals',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a condition is not true.
+ *
+ * @param bool $condition
+ * @param string $message
+ *
+ * @throws PHPUnit_Framework_AssertionFailedError
+ */
+function assertNotTrue($condition, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertNotTrue',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a condition is false.
+ *
+ * @param bool $condition
+ * @param string $message
+ *
+ * @throws PHPUnit_Framework_AssertionFailedError
+ */
+function assertFalse($condition, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertFalse',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that the contents of one file is equal to the contents of another
+ * file.
+ *
+ * @param string $expected
+ * @param string $actual
+ * @param string $message
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ */
+function assertFileEquals($expected, $actual, $message = '', $canonicalize = false, $ignoreCase = false)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertFileEquals',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a file exists.
+ *
+ * @param string $filename
+ * @param string $message
+ */
+function assertFileExists($filename, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertFileExists',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that the contents of one file is not equal to the contents of
+ * another file.
+ *
+ * @param string $expected
+ * @param string $actual
+ * @param string $message
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ */
+function assertFileNotEquals($expected, $actual, $message = '', $canonicalize = false, $ignoreCase = false)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertFileNotEquals',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a file does not exist.
+ *
+ * @param string $filename
+ * @param string $message
+ */
+function assertFileNotExists($filename, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertFileNotExists',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a value is greater than another value.
+ *
+ * @param mixed $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+function assertGreaterThan($expected, $actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertGreaterThan',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a value is greater than or equal to another value.
+ *
+ * @param mixed $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+function assertGreaterThanOrEqual($expected, $actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertGreaterThanOrEqual',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a variable is of a given type.
+ *
+ * @param string $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+function assertInstanceOf($expected, $actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertInstanceOf',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a variable is of a given type.
+ *
+ * @param string $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+function assertInternalType($expected, $actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertInternalType',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a string is a valid JSON string.
+ *
+ * @param string $actualJson
+ * @param string $message
+ */
+function assertJson($actualJson, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertJson',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that two JSON files are equal.
+ *
+ * @param string $expectedFile
+ * @param string $actualFile
+ * @param string $message
+ */
+function assertJsonFileEqualsJsonFile($expectedFile, $actualFile, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertJsonFileEqualsJsonFile',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that two JSON files are not equal.
+ *
+ * @param string $expectedFile
+ * @param string $actualFile
+ * @param string $message
+ */
+function assertJsonFileNotEqualsJsonFile($expectedFile, $actualFile, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertJsonFileNotEqualsJsonFile',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that the generated JSON encoded object and the content of the given file are equal.
+ *
+ * @param string $expectedFile
+ * @param string $actualJson
+ * @param string $message
+ */
+function assertJsonStringEqualsJsonFile($expectedFile, $actualJson, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertJsonStringEqualsJsonFile',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that two given JSON encoded objects or arrays are equal.
+ *
+ * @param string $expectedJson
+ * @param string $actualJson
+ * @param string $message
+ */
+function assertJsonStringEqualsJsonString($expectedJson, $actualJson, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertJsonStringEqualsJsonString',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that the generated JSON encoded object and the content of the given file are not equal.
+ *
+ * @param string $expectedFile
+ * @param string $actualJson
+ * @param string $message
+ */
+function assertJsonStringNotEqualsJsonFile($expectedFile, $actualJson, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertJsonStringNotEqualsJsonFile',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that two given JSON encoded objects or arrays are not equal.
+ *
+ * @param string $expectedJson
+ * @param string $actualJson
+ * @param string $message
+ */
+function assertJsonStringNotEqualsJsonString($expectedJson, $actualJson, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertJsonStringNotEqualsJsonString',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a value is smaller than another value.
+ *
+ * @param mixed $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+function assertLessThan($expected, $actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertLessThan',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a value is smaller than or equal to another value.
+ *
+ * @param mixed $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+function assertLessThanOrEqual($expected, $actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertLessThanOrEqual',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a variable is finite.
+ *
+ * @param mixed $actual
+ * @param string $message
+ */
+function assertFinite($actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertFinite',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a variable is infinite.
+ *
+ * @param mixed $actual
+ * @param string $message
+ */
+function assertInfinite($actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertInfinite',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a variable is nan.
+ *
+ * @param mixed $actual
+ * @param string $message
+ */
+function assertNan($actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertNan',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a haystack does not contain a needle.
+ *
+ * @param mixed $needle
+ * @param mixed $haystack
+ * @param string $message
+ * @param bool $ignoreCase
+ * @param bool $checkForObjectIdentity
+ * @param bool $checkForNonObjectIdentity
+ */
+function assertNotContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertNotContains',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a haystack does not contain only values of a given type.
+ *
+ * @param string $type
+ * @param mixed $haystack
+ * @param bool $isNativeType
+ * @param string $message
+ */
+function assertNotContainsOnly($type, $haystack, $isNativeType = null, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertNotContainsOnly',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts the number of elements of an array, Countable or Traversable.
+ *
+ * @param int $expectedCount
+ * @param mixed $haystack
+ * @param string $message
+ */
+function assertNotCount($expectedCount, $haystack, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertNotCount',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a variable is not empty.
+ *
+ * @param mixed $actual
+ * @param string $message
+ *
+ * @throws PHPUnit_Framework_AssertionFailedError
+ */
+function assertNotEmpty($actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertNotEmpty',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that two variables are not equal.
+ *
+ * @param mixed $expected
+ * @param mixed $actual
+ * @param string $message
+ * @param float $delta
+ * @param int $maxDepth
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ */
+function assertNotEquals($expected, $actual, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertNotEquals',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a variable is not of a given type.
+ *
+ * @param string $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+function assertNotInstanceOf($expected, $actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertNotInstanceOf',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a variable is not of a given type.
+ *
+ * @param string $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+function assertNotInternalType($expected, $actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertNotInternalType',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a condition is not false.
+ *
+ * @param bool $condition
+ * @param string $message
+ *
+ * @throws PHPUnit_Framework_AssertionFailedError
+ */
+function assertNotFalse($condition, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertNotFalse',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a variable is not null.
+ *
+ * @param mixed $actual
+ * @param string $message
+ */
+function assertNotNull($actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertNotNull',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a string does not match a given regular expression.
+ *
+ * @param string $pattern
+ * @param string $string
+ * @param string $message
+ */
+function assertNotRegExp($pattern, $string, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertNotRegExp',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that two variables do not have the same type and value.
+ * Used on objects, it asserts that two variables do not reference
+ * the same object.
+ *
+ * @param mixed $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+function assertNotSame($expected, $actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertNotSame',
+ func_get_args()
+ );
+}
+
+/**
+ * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
+ * is not the same.
+ *
+ * @param array|Countable|Traversable $expected
+ * @param array|Countable|Traversable $actual
+ * @param string $message
+ */
+function assertNotSameSize($expected, $actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertNotSameSize',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a variable is null.
+ *
+ * @param mixed $actual
+ * @param string $message
+ */
+function assertNull($actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertNull',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that an object has a specified attribute.
+ *
+ * @param string $attributeName
+ * @param object $object
+ * @param string $message
+ */
+function assertObjectHasAttribute($attributeName, $object, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertObjectHasAttribute',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that an object does not have a specified attribute.
+ *
+ * @param string $attributeName
+ * @param object $object
+ * @param string $message
+ */
+function assertObjectNotHasAttribute($attributeName, $object, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertObjectNotHasAttribute',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a string matches a given regular expression.
+ *
+ * @param string $pattern
+ * @param string $string
+ * @param string $message
+ */
+function assertRegExp($pattern, $string, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertRegExp',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that two variables have the same type and value.
+ * Used on objects, it asserts that two variables reference
+ * the same object.
+ *
+ * @param mixed $expected
+ * @param mixed $actual
+ * @param string $message
+ */
+function assertSame($expected, $actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertSame',
+ func_get_args()
+ );
+}
+
+/**
+ * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
+ * is the same.
+ *
+ * @param array|Countable|Traversable $expected
+ * @param array|Countable|Traversable $actual
+ * @param string $message
+ */
+function assertSameSize($expected, $actual, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertSameSize',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a string ends not with a given prefix.
+ *
+ * @param string $suffix
+ * @param string $string
+ * @param string $message
+ */
+function assertStringEndsNotWith($suffix, $string, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertStringEndsNotWith',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a string ends with a given prefix.
+ *
+ * @param string $suffix
+ * @param string $string
+ * @param string $message
+ */
+function assertStringEndsWith($suffix, $string, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertStringEndsWith',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that the contents of a string is equal
+ * to the contents of a file.
+ *
+ * @param string $expectedFile
+ * @param string $actualString
+ * @param string $message
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ */
+function assertStringEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = false, $ignoreCase = false)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertStringEqualsFile',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a string matches a given format string.
+ *
+ * @param string $format
+ * @param string $string
+ * @param string $message
+ */
+function assertStringMatchesFormat($format, $string, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertStringMatchesFormat',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a string matches a given format file.
+ *
+ * @param string $formatFile
+ * @param string $string
+ * @param string $message
+ */
+function assertStringMatchesFormatFile($formatFile, $string, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertStringMatchesFormatFile',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that the contents of a string is not equal
+ * to the contents of a file.
+ *
+ * @param string $expectedFile
+ * @param string $actualString
+ * @param string $message
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ */
+function assertStringNotEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = false, $ignoreCase = false)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertStringNotEqualsFile',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a string does not match a given format string.
+ *
+ * @param string $format
+ * @param string $string
+ * @param string $message
+ */
+function assertStringNotMatchesFormat($format, $string, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertStringNotMatchesFormat',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a string does not match a given format string.
+ *
+ * @param string $formatFile
+ * @param string $string
+ * @param string $message
+ */
+function assertStringNotMatchesFormatFile($formatFile, $string, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertStringNotMatchesFormatFile',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a string starts not with a given prefix.
+ *
+ * @param string $prefix
+ * @param string $string
+ * @param string $message
+ */
+function assertStringStartsNotWith($prefix, $string, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertStringStartsNotWith',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a string starts with a given prefix.
+ *
+ * @param string $prefix
+ * @param string $string
+ * @param string $message
+ */
+function assertStringStartsWith($prefix, $string, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertStringStartsWith',
+ func_get_args()
+ );
+}
+
+/**
+ * Evaluates a PHPUnit_Framework_Constraint matcher object.
+ *
+ * @param mixed $value
+ * @param PHPUnit_Framework_Constraint $constraint
+ * @param string $message
+ */
+function assertThat($value, PHPUnit_Framework_Constraint $constraint, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertThat',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that a condition is true.
+ *
+ * @param bool $condition
+ * @param string $message
+ *
+ * @throws PHPUnit_Framework_AssertionFailedError
+ */
+function assertTrue($condition, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertTrue',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that two XML files are equal.
+ *
+ * @param string $expectedFile
+ * @param string $actualFile
+ * @param string $message
+ */
+function assertXmlFileEqualsXmlFile($expectedFile, $actualFile, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertXmlFileEqualsXmlFile',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that two XML files are not equal.
+ *
+ * @param string $expectedFile
+ * @param string $actualFile
+ * @param string $message
+ */
+function assertXmlFileNotEqualsXmlFile($expectedFile, $actualFile, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertXmlFileNotEqualsXmlFile',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that two XML documents are equal.
+ *
+ * @param string $expectedFile
+ * @param string $actualXml
+ * @param string $message
+ */
+function assertXmlStringEqualsXmlFile($expectedFile, $actualXml, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertXmlStringEqualsXmlFile',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that two XML documents are equal.
+ *
+ * @param string $expectedXml
+ * @param string $actualXml
+ * @param string $message
+ */
+function assertXmlStringEqualsXmlString($expectedXml, $actualXml, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertXmlStringEqualsXmlString',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that two XML documents are not equal.
+ *
+ * @param string $expectedFile
+ * @param string $actualXml
+ * @param string $message
+ */
+function assertXmlStringNotEqualsXmlFile($expectedFile, $actualXml, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertXmlStringNotEqualsXmlFile',
+ func_get_args()
+ );
+}
+
+/**
+ * Asserts that two XML documents are not equal.
+ *
+ * @param string $expectedXml
+ * @param string $actualXml
+ * @param string $message
+ */
+function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, $message = '')
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::assertXmlStringNotEqualsXmlString',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a matcher that matches when the method is executed
+ * at the given $index.
+ *
+ * @param int $index
+ *
+ * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex
+ */
+function at($index)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_TestCase::at',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a matcher that matches when the method is executed at least once.
+ *
+ * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce
+ */
+function atLeastOnce()
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_TestCase::atLeastOnce',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_Attribute matcher object.
+ *
+ * @param PHPUnit_Framework_Constraint $constraint
+ * @param string $attributeName
+ *
+ * @return PHPUnit_Framework_Constraint_Attribute
+ */
+function attribute(PHPUnit_Framework_Constraint $constraint, $attributeName)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::attribute',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object
+ * that is wrapped in a PHPUnit_Framework_Constraint_Attribute matcher
+ * object.
+ *
+ * @param string $attributeName
+ * @param mixed $value
+ * @param float $delta
+ * @param int $maxDepth
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ *
+ * @return PHPUnit_Framework_Constraint_Attribute
+ */
+function attributeEqualTo($attributeName, $value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::attributeEqualTo',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_Callback matcher object.
+ *
+ * @param callable $callback
+ *
+ * @return PHPUnit_Framework_Constraint_Callback
+ */
+function callback($callback)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::callback',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_ClassHasAttribute matcher object.
+ *
+ * @param string $attributeName
+ *
+ * @return PHPUnit_Framework_Constraint_ClassHasAttribute
+ */
+function classHasAttribute($attributeName)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::classHasAttribute',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_ClassHasStaticAttribute matcher
+ * object.
+ *
+ * @param string $attributeName
+ *
+ * @return PHPUnit_Framework_Constraint_ClassHasStaticAttribute
+ */
+function classHasStaticAttribute($attributeName)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::classHasStaticAttribute',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_TraversableContains matcher
+ * object.
+ *
+ * @param mixed $value
+ * @param bool $checkForObjectIdentity
+ * @param bool $checkForNonObjectIdentity
+ *
+ * @return PHPUnit_Framework_Constraint_TraversableContains
+ */
+function contains($value, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::contains',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher
+ * object.
+ *
+ * @param string $type
+ *
+ * @return PHPUnit_Framework_Constraint_TraversableContainsOnly
+ */
+function containsOnly($type)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::containsOnly',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher
+ * object.
+ *
+ * @param string $classname
+ *
+ * @return PHPUnit_Framework_Constraint_TraversableContainsOnly
+ */
+function containsOnlyInstancesOf($classname)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::containsOnlyInstancesOf',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_Count matcher object.
+ *
+ * @param int $count
+ *
+ * @return Count
+ */
+function countOf($count)
+{
+ return call_user_func_array(
+ 'PHPUnit\Framework\Assert::countOf',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object.
+ *
+ * @param mixed $value
+ * @param float $delta
+ * @param int $maxDepth
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ *
+ * @return PHPUnit_Framework_Constraint_IsEqual
+ */
+function equalTo($value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::equalTo',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a matcher that matches when the method is executed
+ * exactly $count times.
+ *
+ * @param int $count
+ *
+ * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
+ */
+function exactly($count)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_TestCase::exactly',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_FileExists matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_FileExists
+ */
+function fileExists()
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::fileExists',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_GreaterThan matcher object.
+ *
+ * @param mixed $value
+ *
+ * @return PHPUnit_Framework_Constraint_GreaterThan
+ */
+function greaterThan($value)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::greaterThan',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps
+ * a PHPUnit_Framework_Constraint_IsEqual and a
+ * PHPUnit_Framework_Constraint_GreaterThan matcher object.
+ *
+ * @param mixed $value
+ *
+ * @return PHPUnit_Framework_Constraint_Or
+ */
+function greaterThanOrEqual($value)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::greaterThanOrEqual',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_IsIdentical matcher object.
+ *
+ * @param mixed $value
+ *
+ * @return PHPUnit_Framework_Constraint_IsIdentical
+ */
+function identicalTo($value)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::identicalTo',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_IsEmpty matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_IsEmpty
+ */
+function isEmpty()
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::isEmpty',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_IsFalse matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_IsFalse
+ */
+function isFalse()
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::isFalse',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_IsInstanceOf matcher object.
+ *
+ * @param string $className
+ *
+ * @return PHPUnit_Framework_Constraint_IsInstanceOf
+ */
+function isInstanceOf($className)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::isInstanceOf',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_IsJson matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_IsJson
+ */
+function isJson()
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::isJson',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_IsNull matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_IsNull
+ */
+function isNull()
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::isNull',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_IsTrue matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_IsTrue
+ */
+function isTrue()
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::isTrue',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_IsType matcher object.
+ *
+ * @param string $type
+ *
+ * @return PHPUnit_Framework_Constraint_IsType
+ */
+function isType($type)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::isType',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_LessThan matcher object.
+ *
+ * @param mixed $value
+ *
+ * @return PHPUnit_Framework_Constraint_LessThan
+ */
+function lessThan($value)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::lessThan',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps
+ * a PHPUnit_Framework_Constraint_IsEqual and a
+ * PHPUnit_Framework_Constraint_LessThan matcher object.
+ *
+ * @param mixed $value
+ *
+ * @return PHPUnit_Framework_Constraint_Or
+ */
+function lessThanOrEqual($value)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::lessThanOrEqual',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_And matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_And
+ */
+function logicalAnd()
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::logicalAnd',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_Not matcher object.
+ *
+ * @param PHPUnit_Framework_Constraint $constraint
+ *
+ * @return PHPUnit_Framework_Constraint_Not
+ */
+function logicalNot(PHPUnit_Framework_Constraint $constraint)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::logicalNot',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_Or matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_Or
+ */
+function logicalOr()
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::logicalOr',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_Xor matcher object.
+ *
+ * @return PHPUnit_Framework_Constraint_Xor
+ */
+function logicalXor()
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::logicalXor',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_StringMatches matcher object.
+ *
+ * @param string $string
+ *
+ * @return PHPUnit_Framework_Constraint_StringMatches
+ */
+function matches($string)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::matches',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_PCREMatch matcher object.
+ *
+ * @param string $pattern
+ *
+ * @return PHPUnit_Framework_Constraint_PCREMatch
+ */
+function matchesRegularExpression($pattern)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::matchesRegularExpression',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a matcher that matches when the method is never executed.
+ *
+ * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
+ */
+function never()
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_TestCase::never',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_ObjectHasAttribute matcher object.
+ *
+ * @param string $attributeName
+ *
+ * @return PHPUnit_Framework_Constraint_ObjectHasAttribute
+ */
+function objectHasAttribute($attributeName)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::objectHasAttribute',
+ func_get_args()
+ );
+}
+
+/**
+ * @param mixed $value, ...
+ *
+ * @return PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls
+ */
+function onConsecutiveCalls()
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_TestCase::onConsecutiveCalls',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a matcher that matches when the method is executed exactly once.
+ *
+ * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
+ */
+function once()
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_TestCase::once',
+ func_get_args()
+ );
+}
+
+/**
+ * @param int $argumentIndex
+ *
+ * @return PHPUnit_Framework_MockObject_Stub_ReturnArgument
+ */
+function returnArgument($argumentIndex)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_TestCase::returnArgument',
+ func_get_args()
+ );
+}
+
+/**
+ * @param mixed $callback
+ *
+ * @return PHPUnit_Framework_MockObject_Stub_ReturnCallback
+ */
+function returnCallback($callback)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_TestCase::returnCallback',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns the current object.
+ *
+ * This method is useful when mocking a fluent interface.
+ *
+ * @return PHPUnit_Framework_MockObject_Stub_ReturnSelf
+ */
+function returnSelf()
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_TestCase::returnSelf',
+ func_get_args()
+ );
+}
+
+/**
+ * @param mixed $value
+ *
+ * @return PHPUnit_Framework_MockObject_Stub_Return
+ */
+function returnValue($value)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_TestCase::returnValue',
+ func_get_args()
+ );
+}
+
+/**
+ * @param array $valueMap
+ *
+ * @return PHPUnit_Framework_MockObject_Stub_ReturnValueMap
+ */
+function returnValueMap(array $valueMap)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_TestCase::returnValueMap',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_StringContains matcher object.
+ *
+ * @param string $string
+ * @param bool $case
+ *
+ * @return PHPUnit_Framework_Constraint_StringContains
+ */
+function stringContains($string, $case = true)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::stringContains',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_StringEndsWith matcher object.
+ *
+ * @param mixed $suffix
+ *
+ * @return PHPUnit_Framework_Constraint_StringEndsWith
+ */
+function stringEndsWith($suffix)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::stringEndsWith',
+ func_get_args()
+ );
+}
+
+/**
+ * Returns a PHPUnit_Framework_Constraint_StringStartsWith matcher object.
+ *
+ * @param mixed $prefix
+ *
+ * @return PHPUnit_Framework_Constraint_StringStartsWith
+ */
+function stringStartsWith($prefix)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_Assert::stringStartsWith',
+ func_get_args()
+ );
+}
+
+/**
+ * @param Exception $exception
+ *
+ * @return PHPUnit_Framework_MockObject_Stub_Exception
+ */
+function throwException(Exception $exception)
+{
+ return call_user_func_array(
+ 'PHPUnit_Framework_TestCase::throwException',
+ func_get_args()
+ );
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/AssertionFailedError.php b/vendor/phpunit/phpunit/src/Framework/AssertionFailedError.php
new file mode 100644
index 0000000..77c6843
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/AssertionFailedError.php
@@ -0,0 +1,25 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Thrown when an assertion failed.
+ */
+class PHPUnit_Framework_AssertionFailedError extends PHPUnit_Framework_Exception implements PHPUnit_Framework_SelfDescribing
+{
+ /**
+ * Wrapper for getMessage() which is declared as final.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return $this->getMessage();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/BaseTestListener.php b/vendor/phpunit/phpunit/src/Framework/BaseTestListener.php
new file mode 100644
index 0000000..0fd7cf5
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/BaseTestListener.php
@@ -0,0 +1,58 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * An empty Listener that can be extended to implement TestListener
+ * with just a few lines of code.
+ *
+ * @see PHPUnit_Framework_TestListener for documentation on the API methods.
+ */
+abstract class PHPUnit_Framework_BaseTestListener implements PHPUnit_Framework_TestListener
+{
+ public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ }
+
+ public function addWarning(PHPUnit_Framework_Test $test, PHPUnit_Framework_Warning $e, $time)
+ {
+ }
+
+ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
+ {
+ }
+
+ public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ }
+
+ public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ }
+
+ public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ }
+
+ public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ }
+
+ public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ }
+
+ public function startTest(PHPUnit_Framework_Test $test)
+ {
+ }
+
+ public function endTest(PHPUnit_Framework_Test $test, $time)
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/CodeCoverageException.php b/vendor/phpunit/phpunit/src/Framework/CodeCoverageException.php
new file mode 100644
index 0000000..6fe365d
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/CodeCoverageException.php
@@ -0,0 +1,13 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Framework_CodeCoverageException extends PHPUnit_Framework_Exception
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint.php b/vendor/phpunit/phpunit/src/Framework/Constraint.php
new file mode 100644
index 0000000..80bba68
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint.php
@@ -0,0 +1,149 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use SebastianBergmann\Exporter\Exporter;
+
+/**
+ * Abstract base class for constraints which can be applied to any value.
+ */
+abstract class PHPUnit_Framework_Constraint implements Countable, PHPUnit_Framework_SelfDescribing
+{
+ protected $exporter;
+
+ public function __construct()
+ {
+ $this->exporter = new Exporter;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @param mixed $other Value or object to evaluate.
+ * @param string $description Additional information about the test
+ * @param bool $returnResult Whether to return a result or throw an exception
+ *
+ * @return mixed
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function evaluate($other, $description = '', $returnResult = false)
+ {
+ $success = false;
+
+ if ($this->matches($other)) {
+ $success = true;
+ }
+
+ if ($returnResult) {
+ return $success;
+ }
+
+ if (!$success) {
+ $this->fail($other, $description);
+ }
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * This method can be overridden to implement the evaluation algorithm.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return false;
+ }
+
+ /**
+ * Counts the number of constraint elements.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return 1;
+ }
+
+ /**
+ * Throws an exception for the given compared value and test description
+ *
+ * @param mixed $other Evaluated value or object.
+ * @param string $description Additional information about the test
+ * @param SebastianBergmann\Comparator\ComparisonFailure $comparisonFailure
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ protected function fail($other, $description, SebastianBergmann\Comparator\ComparisonFailure $comparisonFailure = null)
+ {
+ $failureDescription = sprintf(
+ 'Failed asserting that %s.',
+ $this->failureDescription($other)
+ );
+
+ $additionalFailureDescription = $this->additionalFailureDescription($other);
+
+ if ($additionalFailureDescription) {
+ $failureDescription .= "\n" . $additionalFailureDescription;
+ }
+
+ if (!empty($description)) {
+ $failureDescription = $description . "\n" . $failureDescription;
+ }
+
+ throw new PHPUnit_Framework_ExpectationFailedException(
+ $failureDescription,
+ $comparisonFailure
+ );
+ }
+
+ /**
+ * Return additional failure description where needed
+ *
+ * The function can be overridden to provide additional failure
+ * information like a diff
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function additionalFailureDescription($other)
+ {
+ return '';
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * To provide additional failure information additionalFailureDescription
+ * can be used.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ return $this->exporter->export($other) . ' ' . $this->toString();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/And.php b/vendor/phpunit/phpunit/src/Framework/Constraint/And.php
new file mode 100644
index 0000000..640d774
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/And.php
@@ -0,0 +1,121 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Logical AND.
+ */
+class PHPUnit_Framework_Constraint_And extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var PHPUnit_Framework_Constraint[]
+ */
+ protected $constraints = [];
+
+ /**
+ * @var PHPUnit_Framework_Constraint
+ */
+ protected $lastConstraint = null;
+
+ /**
+ * @param PHPUnit_Framework_Constraint[] $constraints
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function setConstraints(array $constraints)
+ {
+ $this->constraints = [];
+
+ foreach ($constraints as $constraint) {
+ if (!($constraint instanceof PHPUnit_Framework_Constraint)) {
+ throw new PHPUnit_Framework_Exception(
+ 'All parameters to ' . __CLASS__ .
+ ' must be a constraint object.'
+ );
+ }
+
+ $this->constraints[] = $constraint;
+ }
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @param mixed $other Value or object to evaluate.
+ * @param string $description Additional information about the test
+ * @param bool $returnResult Whether to return a result or throw an exception
+ *
+ * @return mixed
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function evaluate($other, $description = '', $returnResult = false)
+ {
+ $success = true;
+ $constraint = null;
+
+ foreach ($this->constraints as $constraint) {
+ if (!$constraint->evaluate($other, $description, true)) {
+ $success = false;
+ break;
+ }
+ }
+
+ if ($returnResult) {
+ return $success;
+ }
+
+ if (!$success) {
+ $this->fail($other, $description);
+ }
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ $text = '';
+
+ foreach ($this->constraints as $key => $constraint) {
+ if ($key > 0) {
+ $text .= ' and ';
+ }
+
+ $text .= $constraint->toString();
+ }
+
+ return $text;
+ }
+
+ /**
+ * Counts the number of constraint elements.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ $count = 0;
+
+ foreach ($this->constraints as $constraint) {
+ $count += count($constraint);
+ }
+
+ return $count;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php b/vendor/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php
new file mode 100644
index 0000000..19904eb
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php
@@ -0,0 +1,80 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that asserts that the array it is evaluated for has a given key.
+ *
+ * Uses array_key_exists() to check if the key is found in the input array, if
+ * not found the evaluation fails.
+ *
+ * The array key is passed in the constructor.
+ */
+class PHPUnit_Framework_Constraint_ArrayHasKey extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var int|string
+ */
+ protected $key;
+
+ /**
+ * @param int|string $key
+ */
+ public function __construct($key)
+ {
+ parent::__construct();
+ $this->key = $key;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ if (is_array($other)) {
+ return array_key_exists($this->key, $other);
+ }
+
+ if ($other instanceof ArrayAccess) {
+ return $other->offsetExists($this->key);
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'has the key ' . $this->exporter->export($this->key);
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ return 'an array ' . $this->toString();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php b/vendor/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php
new file mode 100644
index 0000000..5d3e6c4
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php
@@ -0,0 +1,107 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that asserts that the array it is evaluated for has a specified subset.
+ *
+ * Uses array_replace_recursive() to check if a key value subset is part of the
+ * subject array.
+ */
+class PHPUnit_Framework_Constraint_ArraySubset extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var array|Traversable
+ */
+ protected $subset;
+
+ /**
+ * @var bool
+ */
+ protected $strict;
+
+ /**
+ * @param array|Traversable $subset
+ * @param bool $strict Check for object identity
+ */
+ public function __construct($subset, $strict = false)
+ {
+ parent::__construct();
+ $this->strict = $strict;
+ $this->subset = $subset;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param array|Traversable $other Array or Traversable object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ //type cast $other & $this->subset as an array to allow
+ //support in standard array functions.
+ $other = $this->toArray($other);
+ $this->subset = $this->toArray($this->subset);
+
+ $patched = array_replace_recursive($other, $this->subset);
+
+ if ($this->strict) {
+ return $other === $patched;
+ } else {
+ return $other == $patched;
+ }
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'has the subset ' . $this->exporter->export($this->subset);
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ return 'an array ' . $this->toString();
+ }
+
+ /**
+ * @param array|Traversable $other
+ *
+ * @return array
+ */
+ private function toArray($other)
+ {
+ if (is_array($other)) {
+ return $other;
+ } elseif ($other instanceof ArrayObject) {
+ return $other->getArrayCopy();
+ } elseif ($other instanceof Traversable) {
+ return iterator_to_array($other);
+ }
+
+ // Keep BC even if we know that array would not be the expected one
+ return (array) $other;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Attribute.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Attribute.php
new file mode 100644
index 0000000..e63c1d4
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Attribute.php
@@ -0,0 +1,84 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Framework_Constraint_Attribute extends PHPUnit_Framework_Constraint_Composite
+{
+ /**
+ * @var string
+ */
+ protected $attributeName;
+
+ /**
+ * @param PHPUnit_Framework_Constraint $constraint
+ * @param string $attributeName
+ */
+ public function __construct(PHPUnit_Framework_Constraint $constraint, $attributeName)
+ {
+ parent::__construct($constraint);
+
+ $this->attributeName = $attributeName;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @param mixed $other Value or object to evaluate.
+ * @param string $description Additional information about the test
+ * @param bool $returnResult Whether to return a result or throw an exception
+ *
+ * @return mixed
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function evaluate($other, $description = '', $returnResult = false)
+ {
+ return parent::evaluate(
+ PHPUnit_Framework_Assert::readAttribute(
+ $other,
+ $this->attributeName
+ ),
+ $description,
+ $returnResult
+ );
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'attribute "' . $this->attributeName . '" ' .
+ $this->innerConstraint->toString();
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ return $this->toString();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Callback.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Callback.php
new file mode 100644
index 0000000..df60d68
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Callback.php
@@ -0,0 +1,59 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that evaluates against a specified closure.
+ */
+class PHPUnit_Framework_Constraint_Callback extends PHPUnit_Framework_Constraint
+{
+ private $callback;
+
+ /**
+ * @param callable $callback
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function __construct($callback)
+ {
+ if (!is_callable($callback)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 1,
+ 'callable'
+ );
+ }
+
+ parent::__construct();
+
+ $this->callback = $callback;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $value. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return call_user_func($this->callback, $other);
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'is accepted by specified callback';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php b/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php
new file mode 100644
index 0000000..68c7db7
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php
@@ -0,0 +1,80 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that asserts that the class it is evaluated for has a given
+ * attribute.
+ *
+ * The attribute name is passed in the constructor.
+ */
+class PHPUnit_Framework_Constraint_ClassHasAttribute extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var string
+ */
+ protected $attributeName;
+
+ /**
+ * @param string $attributeName
+ */
+ public function __construct($attributeName)
+ {
+ parent::__construct();
+ $this->attributeName = $attributeName;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ $class = new ReflectionClass($other);
+
+ return $class->hasProperty($this->attributeName);
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return sprintf(
+ 'has attribute "%s"',
+ $this->attributeName
+ );
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ return sprintf(
+ '%sclass "%s" %s',
+ is_object($other) ? 'object of ' : '',
+ is_object($other) ? get_class($other) : $other,
+ $this->toString()
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php b/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php
new file mode 100644
index 0000000..e274770
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php
@@ -0,0 +1,52 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that asserts that the class it is evaluated for has a given
+ * static attribute.
+ *
+ * The attribute name is passed in the constructor.
+ */
+class PHPUnit_Framework_Constraint_ClassHasStaticAttribute extends PHPUnit_Framework_Constraint_ClassHasAttribute
+{
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ $class = new ReflectionClass($other);
+
+ if ($class->hasProperty($this->attributeName)) {
+ $attribute = $class->getProperty($this->attributeName);
+
+ return $attribute->isStatic();
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return sprintf(
+ 'has static attribute "%s"',
+ $this->attributeName
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Composite.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Composite.php
new file mode 100644
index 0000000..34e50a8
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Composite.php
@@ -0,0 +1,67 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+abstract class PHPUnit_Framework_Constraint_Composite extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var PHPUnit_Framework_Constraint
+ */
+ protected $innerConstraint;
+
+ /**
+ * @param PHPUnit_Framework_Constraint $innerConstraint
+ */
+ public function __construct(PHPUnit_Framework_Constraint $innerConstraint)
+ {
+ parent::__construct();
+ $this->innerConstraint = $innerConstraint;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @param mixed $other Value or object to evaluate.
+ * @param string $description Additional information about the test
+ * @param bool $returnResult Whether to return a result or throw an exception
+ *
+ * @return mixed
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function evaluate($other, $description = '', $returnResult = false)
+ {
+ try {
+ return $this->innerConstraint->evaluate(
+ $other,
+ $description,
+ $returnResult
+ );
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->fail($other, $description);
+ }
+ }
+
+ /**
+ * Counts the number of constraint elements.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return count($this->innerConstraint);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Count.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Count.php
new file mode 100644
index 0000000..5014dc9
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Count.php
@@ -0,0 +1,122 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Framework_Constraint_Count extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var int
+ */
+ protected $expectedCount = 0;
+
+ /**
+ * @param int $expected
+ */
+ public function __construct($expected)
+ {
+ parent::__construct();
+ $this->expectedCount = $expected;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return $this->expectedCount === $this->getCountOf($other);
+ }
+
+ /**
+ * @param mixed $other
+ *
+ * @return bool
+ */
+ protected function getCountOf($other)
+ {
+ if ($other instanceof Countable || is_array($other)) {
+ return count($other);
+ } elseif ($other instanceof Traversable) {
+ if ($other instanceof IteratorAggregate) {
+ $iterator = $other->getIterator();
+ } else {
+ $iterator = $other;
+ }
+
+ if ($iterator instanceof Generator) {
+ return $this->getCountOfGenerator($iterator);
+ }
+
+ $key = $iterator->key();
+ $count = iterator_count($iterator);
+
+ // Manually rewind $iterator to previous key, since iterator_count
+ // moves pointer.
+ if ($key !== null) {
+ $iterator->rewind();
+ while ($iterator->valid() && $key !== $iterator->key()) {
+ $iterator->next();
+ }
+ }
+
+ return $count;
+ }
+ }
+
+ /**
+ * Returns the total number of iterations from a generator.
+ * This will fully exhaust the generator.
+ *
+ * @param Generator $generator
+ *
+ * @return int
+ */
+ protected function getCountOfGenerator(Generator $generator)
+ {
+ for ($count = 0; $generator->valid(); $generator->next()) {
+ $count += 1;
+ }
+
+ return $count;
+ }
+
+ /**
+ * Returns the description of the failure.
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ return sprintf(
+ 'actual size %d matches expected size %d',
+ $this->getCountOf($other),
+ $this->expectedCount
+ );
+ }
+
+ /**
+ * @return string
+ */
+ public function toString()
+ {
+ return sprintf(
+ 'count matches %d',
+ $this->expectedCount
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php b/vendor/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php
new file mode 100644
index 0000000..c54a58a
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php
@@ -0,0 +1,58 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that checks if the directory(name) that it is evaluated for exists.
+ *
+ * The file path to check is passed as $other in evaluate().
+ */
+class PHPUnit_Framework_Constraint_DirectoryExists extends PHPUnit_Framework_Constraint
+{
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return is_dir($other);
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ return sprintf(
+ 'directory "%s" exists',
+ $other
+ );
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'directory exists';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Exception.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Exception.php
new file mode 100644
index 0000000..7dc798c
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Exception.php
@@ -0,0 +1,85 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Framework_Constraint_Exception extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var string
+ */
+ protected $className;
+
+ /**
+ * @param string $className
+ */
+ public function __construct($className)
+ {
+ parent::__construct();
+ $this->className = $className;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return $other instanceof $this->className;
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ if ($other !== null) {
+ $message = '';
+ if ($other instanceof Exception || $other instanceof Throwable) {
+ $message = '. Message was: "' . $other->getMessage() . '" at'
+ . "\n" . PHPUnit_Util_Filter::getFilteredStacktrace($other);
+ }
+
+ return sprintf(
+ 'exception of type "%s" matches expected exception "%s"%s',
+ get_class($other),
+ $this->className,
+ $message
+ );
+ }
+
+ return sprintf(
+ 'exception of type "%s" is thrown',
+ $this->className
+ );
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return sprintf(
+ 'exception of type "%s"',
+ $this->className
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php b/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php
new file mode 100644
index 0000000..e66c7ac
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php
@@ -0,0 +1,66 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Framework_Constraint_ExceptionCode extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var int
+ */
+ protected $expectedCode;
+
+ /**
+ * @param int $expected
+ */
+ public function __construct($expected)
+ {
+ parent::__construct();
+ $this->expectedCode = $expected;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param Exception $other
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return (string) $other->getCode() == (string) $this->expectedCode;
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ return sprintf(
+ '%s is equal to expected exception code %s',
+ $this->exporter->export($other->getCode()),
+ $this->exporter->export($this->expectedCode)
+ );
+ }
+
+ /**
+ * @return string
+ */
+ public function toString()
+ {
+ return 'exception code is ';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php b/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php
new file mode 100644
index 0000000..d2047e9
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php
@@ -0,0 +1,81 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Framework_Constraint_ExceptionMessage extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var int
+ */
+ protected $expectedMessage;
+
+ /**
+ * @param string $expected
+ */
+ public function __construct($expected)
+ {
+ parent::__construct();
+ $this->expectedMessage = $expected;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param Exception $other
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ if ($this->expectedMessage === '') {
+ return $other->getMessage() === '';
+ }
+
+ return strpos($other->getMessage(), $this->expectedMessage) !== false;
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ if ($this->expectedMessage === '') {
+ return sprintf(
+ "exception message is empty but is '%s'",
+ $other->getMessage()
+ );
+ }
+
+ return sprintf(
+ "exception message '%s' contains '%s'",
+ $other->getMessage(),
+ $this->expectedMessage
+ );
+ }
+
+ /**
+ * @return string
+ */
+ public function toString()
+ {
+ if ($this->expectedMessage === '') {
+ return 'exception message is empty';
+ }
+
+ return 'exception message contains ';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegExp.php b/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegExp.php
new file mode 100644
index 0000000..ea4d4b2
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegExp.php
@@ -0,0 +1,74 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Framework_Constraint_ExceptionMessageRegExp extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var int
+ */
+ protected $expectedMessageRegExp;
+
+ /**
+ * @param string $expected
+ */
+ public function __construct($expected)
+ {
+ parent::__construct();
+ $this->expectedMessageRegExp = $expected;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param Exception $other
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ $match = PHPUnit_Util_Regex::pregMatchSafe($this->expectedMessageRegExp, $other->getMessage());
+
+ if (false === $match) {
+ throw new PHPUnit_Framework_Exception(
+ "Invalid expected exception message regex given: '{$this->expectedMessageRegExp}'"
+ );
+ }
+
+ return 1 === $match;
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ return sprintf(
+ "exception message '%s' matches '%s'",
+ $other->getMessage(),
+ $this->expectedMessageRegExp
+ );
+ }
+
+ /**
+ * @return string
+ */
+ public function toString()
+ {
+ return 'exception message matches ';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/FileExists.php b/vendor/phpunit/phpunit/src/Framework/Constraint/FileExists.php
new file mode 100644
index 0000000..d477c6b
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/FileExists.php
@@ -0,0 +1,58 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that checks if the file(name) that it is evaluated for exists.
+ *
+ * The file path to check is passed as $other in evaluate().
+ */
+class PHPUnit_Framework_Constraint_FileExists extends PHPUnit_Framework_Constraint
+{
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return file_exists($other);
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ return sprintf(
+ 'file "%s" exists',
+ $other
+ );
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'file exists';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php b/vendor/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php
new file mode 100644
index 0000000..d7ecdc4
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php
@@ -0,0 +1,53 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that asserts that the value it is evaluated for is greater
+ * than a given value.
+ */
+class PHPUnit_Framework_Constraint_GreaterThan extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var numeric
+ */
+ protected $value;
+
+ /**
+ * @param numeric $value
+ */
+ public function __construct($value)
+ {
+ parent::__construct();
+ $this->value = $value;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return $this->value < $other;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'is greater than ' . $this->exporter->export($this->value);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsAnything.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsAnything.php
new file mode 100644
index 0000000..baa4cd9
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsAnything.php
@@ -0,0 +1,58 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that accepts any input value.
+ */
+class PHPUnit_Framework_Constraint_IsAnything extends PHPUnit_Framework_Constraint
+{
+ /**
+ * Evaluates the constraint for parameter $other
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @param mixed $other Value or object to evaluate.
+ * @param string $description Additional information about the test
+ * @param bool $returnResult Whether to return a result or throw an exception
+ *
+ * @return mixed
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function evaluate($other, $description = '', $returnResult = false)
+ {
+ return $returnResult ? true : null;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'is anything';
+ }
+
+ /**
+ * Counts the number of constraint elements.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return 0;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php
new file mode 100644
index 0000000..39ce565
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php
@@ -0,0 +1,64 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that checks whether a variable is empty().
+ */
+class PHPUnit_Framework_Constraint_IsEmpty extends PHPUnit_Framework_Constraint
+{
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ if ($other instanceof Countable) {
+ return count($other) === 0;
+ }
+
+ return empty($other);
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'is empty';
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ $type = gettype($other);
+
+ return sprintf(
+ '%s %s %s',
+ $type[0] == 'a' || $type[0] == 'o' ? 'an' : 'a',
+ $type,
+ $this->toString()
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsEqual.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsEqual.php
new file mode 100644
index 0000000..91758a4
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsEqual.php
@@ -0,0 +1,177 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that checks if one value is equal to another.
+ *
+ * Equality is checked with PHP's == operator, the operator is explained in
+ * detail at {@url http://www.php.net/manual/en/types.comparisons.php}.
+ * Two values are equal if they have the same value disregarding type.
+ *
+ * The expected value is passed in the constructor.
+ */
+class PHPUnit_Framework_Constraint_IsEqual extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var mixed
+ */
+ protected $value;
+
+ /**
+ * @var float
+ */
+ protected $delta = 0.0;
+
+ /**
+ * @var int
+ */
+ protected $maxDepth = 10;
+
+ /**
+ * @var bool
+ */
+ protected $canonicalize = false;
+
+ /**
+ * @var bool
+ */
+ protected $ignoreCase = false;
+
+ /**
+ * @var SebastianBergmann\Comparator\ComparisonFailure
+ */
+ protected $lastFailure;
+
+ /**
+ * @param mixed $value
+ * @param float $delta
+ * @param int $maxDepth
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function __construct($value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
+ {
+ parent::__construct();
+
+ if (!is_numeric($delta)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'numeric');
+ }
+
+ if (!is_int($maxDepth)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'integer');
+ }
+
+ if (!is_bool($canonicalize)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(4, 'boolean');
+ }
+
+ if (!is_bool($ignoreCase)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(5, 'boolean');
+ }
+
+ $this->value = $value;
+ $this->delta = $delta;
+ $this->maxDepth = $maxDepth;
+ $this->canonicalize = $canonicalize;
+ $this->ignoreCase = $ignoreCase;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @param mixed $other Value or object to evaluate.
+ * @param string $description Additional information about the test
+ * @param bool $returnResult Whether to return a result or throw an exception
+ *
+ * @return mixed
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function evaluate($other, $description = '', $returnResult = false)
+ {
+ // If $this->value and $other are identical, they are also equal.
+ // This is the most common path and will allow us to skip
+ // initialization of all the comparators.
+ if ($this->value === $other) {
+ return true;
+ }
+
+ $comparatorFactory = SebastianBergmann\Comparator\Factory::getInstance();
+
+ try {
+ $comparator = $comparatorFactory->getComparatorFor(
+ $this->value,
+ $other
+ );
+
+ $comparator->assertEquals(
+ $this->value,
+ $other,
+ $this->delta,
+ $this->canonicalize,
+ $this->ignoreCase
+ );
+ } catch (SebastianBergmann\Comparator\ComparisonFailure $f) {
+ if ($returnResult) {
+ return false;
+ }
+
+ throw new PHPUnit_Framework_ExpectationFailedException(
+ trim($description . "\n" . $f->getMessage()),
+ $f
+ );
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ $delta = '';
+
+ if (is_string($this->value)) {
+ if (strpos($this->value, "\n") !== false) {
+ return 'is equal to <text>';
+ } else {
+ return sprintf(
+ 'is equal to <string:%s>',
+ $this->value
+ );
+ }
+ } else {
+ if ($this->delta != 0) {
+ $delta = sprintf(
+ ' with delta <%F>',
+ $this->delta
+ );
+ }
+
+ return sprintf(
+ 'is equal to %s%s',
+ $this->exporter->export($this->value),
+ $delta
+ );
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsFalse.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsFalse.php
new file mode 100644
index 0000000..391e72a
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsFalse.php
@@ -0,0 +1,38 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that accepts false.
+ */
+class PHPUnit_Framework_Constraint_IsFalse extends PHPUnit_Framework_Constraint
+{
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return $other === false;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'is false';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsFinite.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsFinite.php
new file mode 100644
index 0000000..a32fa6e
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsFinite.php
@@ -0,0 +1,38 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that accepts finite.
+ */
+class PHPUnit_Framework_Constraint_IsFinite extends PHPUnit_Framework_Constraint
+{
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return is_finite($other);
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'is finite';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php
new file mode 100644
index 0000000..f214bc6
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php
@@ -0,0 +1,130 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that asserts that one value is identical to another.
+ *
+ * Identical check is performed with PHP's === operator, the operator is
+ * explained in detail at
+ * {@url http://www.php.net/manual/en/types.comparisons.php}.
+ * Two values are identical if they have the same value and are of the same
+ * type.
+ *
+ * The expected value is passed in the constructor.
+ */
+class PHPUnit_Framework_Constraint_IsIdentical extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var float
+ */
+ const EPSILON = 0.0000000001;
+
+ /**
+ * @var mixed
+ */
+ protected $value;
+
+ /**
+ * @param mixed $value
+ */
+ public function __construct($value)
+ {
+ parent::__construct();
+ $this->value = $value;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @param mixed $other Value or object to evaluate.
+ * @param string $description Additional information about the test
+ * @param bool $returnResult Whether to return a result or throw an exception
+ *
+ * @return mixed
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function evaluate($other, $description = '', $returnResult = false)
+ {
+ if (is_float($this->value) && is_float($other) &&
+ !is_infinite($this->value) && !is_infinite($other) &&
+ !is_nan($this->value) && !is_nan($other)) {
+ $success = abs($this->value - $other) < self::EPSILON;
+ } else {
+ $success = $this->value === $other;
+ }
+
+ if ($returnResult) {
+ return $success;
+ }
+
+ if (!$success) {
+ $f = null;
+
+ // if both values are strings, make sure a diff is generated
+ if (is_string($this->value) && is_string($other)) {
+ $f = new SebastianBergmann\Comparator\ComparisonFailure(
+ $this->value,
+ $other,
+ $this->value,
+ $other
+ );
+ }
+
+ $this->fail($other, $description, $f);
+ }
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ if (is_object($this->value) && is_object($other)) {
+ return 'two variables reference the same object';
+ }
+
+ if (is_string($this->value) && is_string($other)) {
+ return 'two strings are identical';
+ }
+
+ return parent::failureDescription($other);
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ if (is_object($this->value)) {
+ return 'is identical to an object of class "' .
+ get_class($this->value) . '"';
+ } else {
+ return 'is identical to ' .
+ $this->exporter->export($this->value);
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php
new file mode 100644
index 0000000..24f924f
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php
@@ -0,0 +1,38 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that accepts infinite.
+ */
+class PHPUnit_Framework_Constraint_IsInfinite extends PHPUnit_Framework_Constraint
+{
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return is_infinite($other);
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'is infinite';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php
new file mode 100644
index 0000000..5c380a3
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php
@@ -0,0 +1,92 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that asserts that the object it is evaluated for is an instance
+ * of a given class.
+ *
+ * The expected class name is passed in the constructor.
+ */
+class PHPUnit_Framework_Constraint_IsInstanceOf extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var string
+ */
+ protected $className;
+
+ /**
+ * @param string $className
+ */
+ public function __construct($className)
+ {
+ parent::__construct();
+ $this->className = $className;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return ($other instanceof $this->className);
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ return sprintf(
+ '%s is an instance of %s "%s"',
+ $this->exporter->shortenedExport($other),
+ $this->getType(),
+ $this->className
+ );
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return sprintf(
+ 'is instance of %s "%s"',
+ $this->getType(),
+ $this->className
+ );
+ }
+
+ private function getType()
+ {
+ try {
+ $reflection = new ReflectionClass($this->className);
+ if ($reflection->isInterface()) {
+ return 'interface';
+ }
+ } catch (ReflectionException $e) {
+ }
+
+ return 'class';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsJson.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsJson.php
new file mode 100644
index 0000000..315e378
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsJson.php
@@ -0,0 +1,75 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that asserts that a string is valid JSON.
+ */
+class PHPUnit_Framework_Constraint_IsJson extends PHPUnit_Framework_Constraint
+{
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ if ($other === '') {
+ return false;
+ }
+
+ json_decode($other);
+ if (json_last_error()) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ if ($other === '') {
+ return 'an empty string is valid JSON';
+ }
+
+ json_decode($other);
+ $error = PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider::determineJsonError(
+ json_last_error()
+ );
+
+ return sprintf(
+ '%s is valid JSON (%s)',
+ $this->exporter->shortenedExport($other),
+ $error
+ );
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'is valid JSON';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsNan.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsNan.php
new file mode 100644
index 0000000..58c167f
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsNan.php
@@ -0,0 +1,38 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that accepts nan.
+ */
+class PHPUnit_Framework_Constraint_IsNan extends PHPUnit_Framework_Constraint
+{
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return is_nan($other);
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'is nan';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsNull.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsNull.php
new file mode 100644
index 0000000..856d4aa
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsNull.php
@@ -0,0 +1,38 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that accepts null.
+ */
+class PHPUnit_Framework_Constraint_IsNull extends PHPUnit_Framework_Constraint
+{
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return $other === null;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'is null';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsReadable.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsReadable.php
new file mode 100644
index 0000000..403405e
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsReadable.php
@@ -0,0 +1,58 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that checks if the file/dir(name) that it is evaluated for is readable.
+ *
+ * The file path to check is passed as $other in evaluate().
+ */
+class PHPUnit_Framework_Constraint_IsReadable extends PHPUnit_Framework_Constraint
+{
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return is_readable($other);
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ return sprintf(
+ '"%s" is readable',
+ $other
+ );
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'is readable';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsTrue.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsTrue.php
new file mode 100644
index 0000000..d71a722
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsTrue.php
@@ -0,0 +1,38 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that accepts true.
+ */
+class PHPUnit_Framework_Constraint_IsTrue extends PHPUnit_Framework_Constraint
+{
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return $other === true;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'is true';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsType.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsType.php
new file mode 100644
index 0000000..a2b218d
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsType.php
@@ -0,0 +1,141 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that asserts that the value it is evaluated for is of a
+ * specified type.
+ *
+ * The expected value is passed in the constructor.
+ */
+class PHPUnit_Framework_Constraint_IsType extends PHPUnit_Framework_Constraint
+{
+ const TYPE_ARRAY = 'array';
+ const TYPE_BOOL = 'bool';
+ const TYPE_FLOAT = 'float';
+ const TYPE_INT = 'int';
+ const TYPE_NULL = 'null';
+ const TYPE_NUMERIC = 'numeric';
+ const TYPE_OBJECT = 'object';
+ const TYPE_RESOURCE = 'resource';
+ const TYPE_STRING = 'string';
+ const TYPE_SCALAR = 'scalar';
+ const TYPE_CALLABLE = 'callable';
+
+ /**
+ * @var array
+ */
+ protected $types = [
+ 'array' => true,
+ 'boolean' => true,
+ 'bool' => true,
+ 'double' => true,
+ 'float' => true,
+ 'integer' => true,
+ 'int' => true,
+ 'null' => true,
+ 'numeric' => true,
+ 'object' => true,
+ 'real' => true,
+ 'resource' => true,
+ 'string' => true,
+ 'scalar' => true,
+ 'callable' => true
+ ];
+
+ /**
+ * @var string
+ */
+ protected $type;
+
+ /**
+ * @param string $type
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function __construct($type)
+ {
+ parent::__construct();
+
+ if (!isset($this->types[$type])) {
+ throw new PHPUnit_Framework_Exception(
+ sprintf(
+ 'Type specified for PHPUnit_Framework_Constraint_IsType <%s> ' .
+ 'is not a valid type.',
+ $type
+ )
+ );
+ }
+
+ $this->type = $type;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ switch ($this->type) {
+ case 'numeric':
+ return is_numeric($other);
+
+ case 'integer':
+ case 'int':
+ return is_int($other);
+
+ case 'double':
+ case 'float':
+ case 'real':
+ return is_float($other);
+
+ case 'string':
+ return is_string($other);
+
+ case 'boolean':
+ case 'bool':
+ return is_bool($other);
+
+ case 'null':
+ return is_null($other);
+
+ case 'array':
+ return is_array($other);
+
+ case 'object':
+ return is_object($other);
+
+ case 'resource':
+ return is_resource($other) || is_string(@get_resource_type($other));
+
+ case 'scalar':
+ return is_scalar($other);
+
+ case 'callable':
+ return is_callable($other);
+ }
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return sprintf(
+ 'is of type "%s"',
+ $this->type
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsWritable.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsWritable.php
new file mode 100644
index 0000000..b82d86e
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsWritable.php
@@ -0,0 +1,58 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that checks if the file/dir(name) that it is evaluated for is writable.
+ *
+ * The file path to check is passed as $other in evaluate().
+ */
+class PHPUnit_Framework_Constraint_IsWritable extends PHPUnit_Framework_Constraint
+{
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return is_writable($other);
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ return sprintf(
+ '"%s" is writable',
+ $other
+ );
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'is writable';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php b/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php
new file mode 100644
index 0000000..02b8767
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php
@@ -0,0 +1,69 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Asserts whether or not two JSON objects are equal.
+ */
+class PHPUnit_Framework_Constraint_JsonMatches extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var string
+ */
+ protected $value;
+
+ /**
+ * Creates a new constraint.
+ *
+ * @param string $value
+ */
+ public function __construct($value)
+ {
+ parent::__construct();
+ $this->value = $value;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * This method can be overridden to implement the evaluation algorithm.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ $decodedOther = json_decode($other);
+ if (json_last_error()) {
+ return false;
+ }
+
+ $decodedValue = json_decode($this->value);
+ if (json_last_error()) {
+ return false;
+ }
+
+ return $decodedOther == $decodedValue;
+ }
+
+ /**
+ * Returns a string representation of the object.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return sprintf(
+ 'matches JSON string "%s"',
+ $this->value
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches/ErrorMessageProvider.php b/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches/ErrorMessageProvider.php
new file mode 100644
index 0000000..76cc0e7
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches/ErrorMessageProvider.php
@@ -0,0 +1,67 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Provides human readable messages for each JSON error.
+ */
+class PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider
+{
+ /**
+ * Translates JSON error to a human readable string.
+ *
+ * @param string $error
+ * @param string $prefix
+ *
+ * @return string
+ */
+ public static function determineJsonError($error, $prefix = '')
+ {
+ switch ($error) {
+ case JSON_ERROR_NONE:
+ return;
+ case JSON_ERROR_DEPTH:
+ return $prefix . 'Maximum stack depth exceeded';
+ case JSON_ERROR_STATE_MISMATCH:
+ return $prefix . 'Underflow or the modes mismatch';
+ case JSON_ERROR_CTRL_CHAR:
+ return $prefix . 'Unexpected control character found';
+ case JSON_ERROR_SYNTAX:
+ return $prefix . 'Syntax error, malformed JSON';
+ case JSON_ERROR_UTF8:
+ return $prefix . 'Malformed UTF-8 characters, possibly incorrectly encoded';
+ default:
+ return $prefix . 'Unknown error';
+ }
+ }
+
+ /**
+ * Translates a given type to a human readable message prefix.
+ *
+ * @param string $type
+ *
+ * @return string
+ */
+ public static function translateTypeToPrefix($type)
+ {
+ switch (strtolower($type)) {
+ case 'expected':
+ $prefix = 'Expected value JSON decode error - ';
+ break;
+ case 'actual':
+ $prefix = 'Actual value JSON decode error - ';
+ break;
+ default:
+ $prefix = '';
+ break;
+ }
+
+ return $prefix;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/LessThan.php b/vendor/phpunit/phpunit/src/Framework/Constraint/LessThan.php
new file mode 100644
index 0000000..256edc9
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/LessThan.php
@@ -0,0 +1,53 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that asserts that the value it is evaluated for is less than
+ * a given value.
+ */
+class PHPUnit_Framework_Constraint_LessThan extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var numeric
+ */
+ protected $value;
+
+ /**
+ * @param numeric $value
+ */
+ public function __construct($value)
+ {
+ parent::__construct();
+ $this->value = $value;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return $this->value > $other;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'is less than ' . $this->exporter->export($this->value);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Not.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Not.php
new file mode 100644
index 0000000..8b93f77
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Not.php
@@ -0,0 +1,156 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Logical NOT.
+ */
+class PHPUnit_Framework_Constraint_Not extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var PHPUnit_Framework_Constraint
+ */
+ protected $constraint;
+
+ /**
+ * @param PHPUnit_Framework_Constraint $constraint
+ */
+ public function __construct($constraint)
+ {
+ parent::__construct();
+
+ if (!($constraint instanceof PHPUnit_Framework_Constraint)) {
+ $constraint = new PHPUnit_Framework_Constraint_IsEqual($constraint);
+ }
+
+ $this->constraint = $constraint;
+ }
+
+ /**
+ * @param string $string
+ *
+ * @return string
+ */
+ public static function negate($string)
+ {
+ return str_replace(
+ [
+ 'contains ',
+ 'exists',
+ 'has ',
+ 'is ',
+ 'are ',
+ 'matches ',
+ 'starts with ',
+ 'ends with ',
+ 'reference ',
+ 'not not '
+ ],
+ [
+ 'does not contain ',
+ 'does not exist',
+ 'does not have ',
+ 'is not ',
+ 'are not ',
+ 'does not match ',
+ 'starts not with ',
+ 'ends not with ',
+ 'don\'t reference ',
+ 'not '
+ ],
+ $string
+ );
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @param mixed $other Value or object to evaluate.
+ * @param string $description Additional information about the test
+ * @param bool $returnResult Whether to return a result or throw an exception
+ *
+ * @return mixed
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function evaluate($other, $description = '', $returnResult = false)
+ {
+ $success = !$this->constraint->evaluate($other, $description, true);
+
+ if ($returnResult) {
+ return $success;
+ }
+
+ if (!$success) {
+ $this->fail($other, $description);
+ }
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ switch (get_class($this->constraint)) {
+ case 'PHPUnit_Framework_Constraint_And':
+ case 'PHPUnit_Framework_Constraint_Not':
+ case 'PHPUnit_Framework_Constraint_Or':
+ return 'not( ' . $this->constraint->failureDescription($other) . ' )';
+
+ default:
+ return self::negate(
+ $this->constraint->failureDescription($other)
+ );
+ }
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ switch (get_class($this->constraint)) {
+ case 'PHPUnit_Framework_Constraint_And':
+ case 'PHPUnit_Framework_Constraint_Not':
+ case 'PHPUnit_Framework_Constraint_Or':
+ return 'not( ' . $this->constraint->toString() . ' )';
+
+ default:
+ return self::negate(
+ $this->constraint->toString()
+ );
+ }
+ }
+
+ /**
+ * Counts the number of constraint elements.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return count($this->constraint);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php b/vendor/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php
new file mode 100644
index 0000000..3c99b31
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php
@@ -0,0 +1,33 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that asserts that the object it is evaluated for has a given
+ * attribute.
+ *
+ * The attribute name is passed in the constructor.
+ */
+class PHPUnit_Framework_Constraint_ObjectHasAttribute extends PHPUnit_Framework_Constraint_ClassHasAttribute
+{
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ $object = new ReflectionObject($other);
+
+ return $object->hasProperty($this->attributeName);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Or.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Or.php
new file mode 100644
index 0000000..af739aa
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Or.php
@@ -0,0 +1,113 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Logical OR.
+ */
+class PHPUnit_Framework_Constraint_Or extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var PHPUnit_Framework_Constraint[]
+ */
+ protected $constraints = [];
+
+ /**
+ * @param PHPUnit_Framework_Constraint[] $constraints
+ */
+ public function setConstraints(array $constraints)
+ {
+ $this->constraints = [];
+
+ foreach ($constraints as $constraint) {
+ if (!($constraint instanceof PHPUnit_Framework_Constraint)) {
+ $constraint = new PHPUnit_Framework_Constraint_IsEqual(
+ $constraint
+ );
+ }
+
+ $this->constraints[] = $constraint;
+ }
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @param mixed $other Value or object to evaluate.
+ * @param string $description Additional information about the test
+ * @param bool $returnResult Whether to return a result or throw an exception
+ *
+ * @return mixed
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function evaluate($other, $description = '', $returnResult = false)
+ {
+ $success = false;
+ $constraint = null;
+
+ foreach ($this->constraints as $constraint) {
+ if ($constraint->evaluate($other, $description, true)) {
+ $success = true;
+ break;
+ }
+ }
+
+ if ($returnResult) {
+ return $success;
+ }
+
+ if (!$success) {
+ $this->fail($other, $description);
+ }
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ $text = '';
+
+ foreach ($this->constraints as $key => $constraint) {
+ if ($key > 0) {
+ $text .= ' or ';
+ }
+
+ $text .= $constraint->toString();
+ }
+
+ return $text;
+ }
+
+ /**
+ * Counts the number of constraint elements.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ $count = 0;
+
+ foreach ($this->constraints as $constraint) {
+ $count += count($constraint);
+ }
+
+ return $count;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/PCREMatch.php b/vendor/phpunit/phpunit/src/Framework/Constraint/PCREMatch.php
new file mode 100644
index 0000000..c4ea9c8
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/PCREMatch.php
@@ -0,0 +1,61 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that asserts that the string it is evaluated for matches
+ * a regular expression.
+ *
+ * Checks a given value using the Perl Compatible Regular Expression extension
+ * in PHP. The pattern is matched by executing preg_match().
+ *
+ * The pattern string passed in the constructor.
+ */
+class PHPUnit_Framework_Constraint_PCREMatch extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var string
+ */
+ protected $pattern;
+
+ /**
+ * @param string $pattern
+ */
+ public function __construct($pattern)
+ {
+ parent::__construct();
+ $this->pattern = $pattern;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return preg_match($this->pattern, $other) > 0;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return sprintf(
+ 'matches PCRE pattern "%s"',
+ $this->pattern
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/SameSize.php b/vendor/phpunit/phpunit/src/Framework/Constraint/SameSize.php
new file mode 100644
index 0000000..336566a
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/SameSize.php
@@ -0,0 +1,25 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Framework_Constraint_SameSize extends PHPUnit_Framework_Constraint_Count
+{
+ /**
+ * @var int
+ */
+ protected $expectedCount;
+
+ /**
+ * @param int $expected
+ */
+ public function __construct($expected)
+ {
+ parent::__construct($this->getCountOf($expected));
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/StringContains.php b/vendor/phpunit/phpunit/src/Framework/Constraint/StringContains.php
new file mode 100644
index 0000000..7c84743
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/StringContains.php
@@ -0,0 +1,79 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that asserts that the string it is evaluated for contains
+ * a given string.
+ *
+ * Uses mb_strpos() to find the position of the string in the input, if not
+ * found the evaluation fails.
+ *
+ * The sub-string is passed in the constructor.
+ */
+class PHPUnit_Framework_Constraint_StringContains extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var string
+ */
+ protected $string;
+
+ /**
+ * @var bool
+ */
+ protected $ignoreCase;
+
+ /**
+ * @param string $string
+ * @param bool $ignoreCase
+ */
+ public function __construct($string, $ignoreCase = false)
+ {
+ parent::__construct();
+
+ $this->string = $string;
+ $this->ignoreCase = $ignoreCase;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ if ($this->ignoreCase) {
+ return mb_stripos($other, $this->string) !== false;
+ } else {
+ return mb_strpos($other, $this->string) !== false;
+ }
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ if ($this->ignoreCase) {
+ $string = mb_strtolower($this->string);
+ } else {
+ $string = $this->string;
+ }
+
+ return sprintf(
+ 'contains "%s"',
+ $string
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php b/vendor/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php
new file mode 100644
index 0000000..c70c86a
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php
@@ -0,0 +1,53 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that asserts that the string it is evaluated for ends with a given
+ * suffix.
+ */
+class PHPUnit_Framework_Constraint_StringEndsWith extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var string
+ */
+ protected $suffix;
+
+ /**
+ * @param string $suffix
+ */
+ public function __construct($suffix)
+ {
+ parent::__construct();
+ $this->suffix = $suffix;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return substr($other, 0 - strlen($this->suffix)) == $this->suffix;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'ends with "' . $this->suffix . '"';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/StringMatches.php b/vendor/phpunit/phpunit/src/Framework/Constraint/StringMatches.php
new file mode 100644
index 0000000..6027fb6
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/StringMatches.php
@@ -0,0 +1,99 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use SebastianBergmann\Diff\Differ;
+
+/**
+ * ...
+ */
+class PHPUnit_Framework_Constraint_StringMatches extends PHPUnit_Framework_Constraint_PCREMatch
+{
+ /**
+ * @var string
+ */
+ protected $string;
+
+ /**
+ * @param string $string
+ */
+ public function __construct($string)
+ {
+ parent::__construct($string);
+
+ $this->pattern = $this->createPatternFromFormat(
+ preg_replace('/\r\n/', "\n", $string)
+ );
+
+ $this->string = $string;
+ }
+
+ protected function failureDescription($other)
+ {
+ return 'format description matches text';
+ }
+
+ protected function additionalFailureDescription($other)
+ {
+ $from = preg_split('(\r\n|\r|\n)', $this->string);
+ $to = preg_split('(\r\n|\r|\n)', $other);
+
+ foreach ($from as $index => $line) {
+ if (isset($to[$index]) && $line !== $to[$index]) {
+ $line = $this->createPatternFromFormat($line);
+
+ if (preg_match($line, $to[$index]) > 0) {
+ $from[$index] = $to[$index];
+ }
+ }
+ }
+
+ $this->string = implode("\n", $from);
+ $other = implode("\n", $to);
+
+ $differ = new Differ("--- Expected\n+++ Actual\n");
+
+ return $differ->diff($this->string, $other);
+ }
+
+ protected function createPatternFromFormat($string)
+ {
+ $string = str_replace(
+ [
+ '%e',
+ '%s',
+ '%S',
+ '%a',
+ '%A',
+ '%w',
+ '%i',
+ '%d',
+ '%x',
+ '%f',
+ '%c'
+ ],
+ [
+ '\\' . DIRECTORY_SEPARATOR,
+ '[^\r\n]+',
+ '[^\r\n]*',
+ '.+',
+ '.*',
+ '\s*',
+ '[+-]?\d+',
+ '\d+',
+ '[0-9a-fA-F]+',
+ '[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?',
+ '.'
+ ],
+ preg_quote($string, '/')
+ );
+
+ return '/^' . $string . '$/s';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php b/vendor/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php
new file mode 100644
index 0000000..b1f05b5
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php
@@ -0,0 +1,53 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that asserts that the string it is evaluated for begins with a
+ * given prefix.
+ */
+class PHPUnit_Framework_Constraint_StringStartsWith extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var string
+ */
+ protected $prefix;
+
+ /**
+ * @param string $prefix
+ */
+ public function __construct($prefix)
+ {
+ parent::__construct();
+ $this->prefix = $prefix;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ return strpos($other, $this->prefix) === 0;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'starts with "' . $this->prefix . '"';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php b/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php
new file mode 100644
index 0000000..6d28133
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php
@@ -0,0 +1,123 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that asserts that the Traversable it is applied to contains
+ * a given value.
+ */
+class PHPUnit_Framework_Constraint_TraversableContains extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var bool
+ */
+ protected $checkForObjectIdentity;
+
+ /**
+ * @var bool
+ */
+ protected $checkForNonObjectIdentity;
+
+ /**
+ * @var mixed
+ */
+ protected $value;
+
+ /**
+ * @param mixed $value
+ * @param bool $checkForObjectIdentity
+ * @param bool $checkForNonObjectIdentity
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function __construct($value, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
+ {
+ parent::__construct();
+
+ if (!is_bool($checkForObjectIdentity)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'boolean');
+ }
+
+ if (!is_bool($checkForNonObjectIdentity)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'boolean');
+ }
+
+ $this->checkForObjectIdentity = $checkForObjectIdentity;
+ $this->checkForNonObjectIdentity = $checkForNonObjectIdentity;
+ $this->value = $value;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other. Returns true if the
+ * constraint is met, false otherwise.
+ *
+ * @param mixed $other Value or object to evaluate.
+ *
+ * @return bool
+ */
+ protected function matches($other)
+ {
+ if ($other instanceof SplObjectStorage) {
+ return $other->contains($this->value);
+ }
+
+ if (is_object($this->value)) {
+ foreach ($other as $element) {
+ if ($this->checkForObjectIdentity && $element === $this->value) {
+ return true;
+ } elseif (!$this->checkForObjectIdentity && $element == $this->value) {
+ return true;
+ }
+ }
+ } else {
+ foreach ($other as $element) {
+ if ($this->checkForNonObjectIdentity && $element === $this->value) {
+ return true;
+ } elseif (!$this->checkForNonObjectIdentity && $element == $this->value) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ if (is_string($this->value) && strpos($this->value, "\n") !== false) {
+ return 'contains "' . $this->value . '"';
+ } else {
+ return 'contains ' . $this->exporter->export($this->value);
+ }
+ }
+
+ /**
+ * Returns the description of the failure
+ *
+ * The beginning of failure messages is "Failed asserting that" in most
+ * cases. This method should return the second part of that sentence.
+ *
+ * @param mixed $other Evaluated value or object.
+ *
+ * @return string
+ */
+ protected function failureDescription($other)
+ {
+ return sprintf(
+ '%s %s',
+ is_array($other) ? 'an array' : 'a traversable',
+ $this->toString()
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php b/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php
new file mode 100644
index 0000000..30eddf2
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php
@@ -0,0 +1,93 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Constraint that asserts that the Traversable it is applied to contains
+ * only values of a given type.
+ */
+class PHPUnit_Framework_Constraint_TraversableContainsOnly extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var PHPUnit_Framework_Constraint
+ */
+ protected $constraint;
+
+ /**
+ * @var string
+ */
+ protected $type;
+
+ /**
+ * @param string $type
+ * @param bool $isNativeType
+ */
+ public function __construct($type, $isNativeType = true)
+ {
+ parent::__construct();
+
+ if ($isNativeType) {
+ $this->constraint = new PHPUnit_Framework_Constraint_IsType($type);
+ } else {
+ $this->constraint = new PHPUnit_Framework_Constraint_IsInstanceOf(
+ $type
+ );
+ }
+
+ $this->type = $type;
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @param mixed $other Value or object to evaluate.
+ * @param string $description Additional information about the test
+ * @param bool $returnResult Whether to return a result or throw an exception
+ *
+ * @return mixed
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function evaluate($other, $description = '', $returnResult = false)
+ {
+ $success = true;
+
+ foreach ($other as $item) {
+ if (!$this->constraint->evaluate($item, '', true)) {
+ $success = false;
+ break;
+ }
+ }
+
+ if ($returnResult) {
+ return $success;
+ }
+
+ if (!$success) {
+ $this->fail($other, $description);
+ }
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'contains only values of type "' . $this->type . '"';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Xor.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Xor.php
new file mode 100644
index 0000000..2214ecd
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Xor.php
@@ -0,0 +1,118 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Logical XOR.
+ */
+class PHPUnit_Framework_Constraint_Xor extends PHPUnit_Framework_Constraint
+{
+ /**
+ * @var PHPUnit_Framework_Constraint[]
+ */
+ protected $constraints = [];
+
+ /**
+ * @param PHPUnit_Framework_Constraint[] $constraints
+ */
+ public function setConstraints(array $constraints)
+ {
+ $this->constraints = [];
+
+ foreach ($constraints as $constraint) {
+ if (!($constraint instanceof PHPUnit_Framework_Constraint)) {
+ $constraint = new PHPUnit_Framework_Constraint_IsEqual(
+ $constraint
+ );
+ }
+
+ $this->constraints[] = $constraint;
+ }
+ }
+
+ /**
+ * Evaluates the constraint for parameter $other
+ *
+ * If $returnResult is set to false (the default), an exception is thrown
+ * in case of a failure. null is returned otherwise.
+ *
+ * If $returnResult is true, the result of the evaluation is returned as
+ * a boolean value instead: true in case of success, false in case of a
+ * failure.
+ *
+ * @param mixed $other Value or object to evaluate.
+ * @param string $description Additional information about the test
+ * @param bool $returnResult Whether to return a result or throw an exception
+ *
+ * @return mixed
+ *
+ * @throws PHPUnit_Framework_ExpectationFailedException
+ */
+ public function evaluate($other, $description = '', $returnResult = false)
+ {
+ $success = true;
+ $lastResult = null;
+ $constraint = null;
+
+ foreach ($this->constraints as $constraint) {
+ $result = $constraint->evaluate($other, $description, true);
+
+ if ($result === $lastResult) {
+ $success = false;
+ break;
+ }
+
+ $lastResult = $result;
+ }
+
+ if ($returnResult) {
+ return $success;
+ }
+
+ if (!$success) {
+ $this->fail($other, $description);
+ }
+ }
+
+ /**
+ * Returns a string representation of the constraint.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ $text = '';
+
+ foreach ($this->constraints as $key => $constraint) {
+ if ($key > 0) {
+ $text .= ' xor ';
+ }
+
+ $text .= $constraint->toString();
+ }
+
+ return $text;
+ }
+
+ /**
+ * Counts the number of constraint elements.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ $count = 0;
+
+ foreach ($this->constraints as $constraint) {
+ $count += count($constraint);
+ }
+
+ return $count;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php b/vendor/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php
new file mode 100644
index 0000000..c29a1a5
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/CoveredCodeNotExecutedException.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
+ * case of a test that does not execute the code it wants to cover.
+ */
+class PHPUnit_Framework_CoveredCodeNotExecutedException extends PHPUnit_Framework_RiskyTestError
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Error.php b/vendor/phpunit/phpunit/src/Framework/Error.php
new file mode 100644
index 0000000..0844007
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Error.php
@@ -0,0 +1,32 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Wrapper for PHP errors.
+ */
+class PHPUnit_Framework_Error extends PHPUnit_Framework_Exception
+{
+ /**
+ * Constructor.
+ *
+ * @param string $message
+ * @param int $code
+ * @param string $file
+ * @param int $line
+ * @param Exception $previous
+ */
+ public function __construct($message, $code, $file, $line, Exception $previous = null)
+ {
+ parent::__construct($message, $code, $previous);
+
+ $this->file = $file;
+ $this->line = $line;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Error/Deprecated.php b/vendor/phpunit/phpunit/src/Framework/Error/Deprecated.php
new file mode 100644
index 0000000..94f64fa
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Error/Deprecated.php
@@ -0,0 +1,22 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Wrapper for PHP deprecated errors.
+ * You can disable deprecated-to-exception conversion by setting
+ *
+ * <code>
+ * PHPUnit_Framework_Error_Deprecated::$enabled = false;
+ * </code>
+ */
+class PHPUnit_Framework_Error_Deprecated extends PHPUnit_Framework_Error
+{
+ public static $enabled = true;
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Error/Notice.php b/vendor/phpunit/phpunit/src/Framework/Error/Notice.php
new file mode 100644
index 0000000..25a4164
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Error/Notice.php
@@ -0,0 +1,22 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Wrapper for PHP notices.
+ * You can disable notice-to-exception conversion by setting
+ *
+ * <code>
+ * PHPUnit_Framework_Error_Notice::$enabled = false;
+ * </code>
+ */
+class PHPUnit_Framework_Error_Notice extends PHPUnit_Framework_Error
+{
+ public static $enabled = true;
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Error/Warning.php b/vendor/phpunit/phpunit/src/Framework/Error/Warning.php
new file mode 100644
index 0000000..55f1692
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Error/Warning.php
@@ -0,0 +1,22 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Wrapper for PHP warnings.
+ * You can disable notice-to-exception conversion by setting
+ *
+ * <code>
+ * PHPUnit_Framework_Error_Warning::$enabled = false;
+ * </code>
+ */
+class PHPUnit_Framework_Error_Warning extends PHPUnit_Framework_Error
+{
+ public static $enabled = true;
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Exception.php b/vendor/phpunit/phpunit/src/Framework/Exception.php
new file mode 100644
index 0000000..6188617
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Exception.php
@@ -0,0 +1,76 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Base class for all PHPUnit Framework exceptions.
+ *
+ * Ensures that exceptions thrown during a test run do not leave stray
+ * references behind.
+ *
+ * Every Exception contains a stack trace. Each stack frame contains the 'args'
+ * of the called function. The function arguments can contain references to
+ * instantiated objects. The references prevent the objects from being
+ * destructed (until test results are eventually printed), so memory cannot be
+ * freed up.
+ *
+ * With enabled process isolation, test results are serialized in the child
+ * process and unserialized in the parent process. The stack trace of Exceptions
+ * may contain objects that cannot be serialized or unserialized (e.g., PDO
+ * connections). Unserializing user-space objects from the child process into
+ * the parent would break the intended encapsulation of process isolation.
+ *
+ * @see http://fabien.potencier.org/article/9/php-serialization-stack-traces-and-exceptions
+ */
+class PHPUnit_Framework_Exception extends RuntimeException implements PHPUnit_Exception
+{
+ /**
+ * @var array
+ */
+ protected $serializableTrace;
+
+ public function __construct($message = '', $code = 0, Exception $previous = null)
+ {
+ parent::__construct($message, $code, $previous);
+
+ $this->serializableTrace = $this->getTrace();
+ foreach ($this->serializableTrace as $i => $call) {
+ unset($this->serializableTrace[$i]['args']);
+ }
+ }
+
+ /**
+ * Returns the serializable trace (without 'args').
+ *
+ * @return array
+ */
+ public function getSerializableTrace()
+ {
+ return $this->serializableTrace;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ $string = PHPUnit_Framework_TestFailure::exceptionToString($this);
+
+ if ($trace = PHPUnit_Util_Filter::getFilteredStacktrace($this)) {
+ $string .= "\n" . $trace;
+ }
+
+ return $string;
+ }
+
+ public function __sleep()
+ {
+ return array_keys(get_object_vars($this));
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/ExceptionWrapper.php b/vendor/phpunit/phpunit/src/Framework/ExceptionWrapper.php
new file mode 100644
index 0000000..558932a
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/ExceptionWrapper.php
@@ -0,0 +1,89 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Wraps Exceptions thrown by code under test.
+ *
+ * Re-instantiates Exceptions thrown by user-space code to retain their original
+ * class names, properties, and stack traces (but without arguments).
+ *
+ * Unlike PHPUnit_Framework_Exception, the complete stack of previous Exceptions
+ * is processed.
+ */
+class PHPUnit_Framework_ExceptionWrapper extends PHPUnit_Framework_Exception
+{
+ /**
+ * @var string
+ */
+ protected $className;
+
+ /**
+ * @var PHPUnit_Framework_ExceptionWrapper|null
+ */
+ protected $previous;
+
+ /**
+ * @param Throwable|Exception $e
+ */
+ public function __construct($e)
+ {
+ // PDOException::getCode() is a string.
+ // @see http://php.net/manual/en/class.pdoexception.php#95812
+ parent::__construct($e->getMessage(), (int) $e->getCode());
+
+ $this->className = get_class($e);
+ $this->file = $e->getFile();
+ $this->line = $e->getLine();
+
+ $this->serializableTrace = $e->getTrace();
+
+ foreach ($this->serializableTrace as $i => $call) {
+ unset($this->serializableTrace[$i]['args']);
+ }
+
+ if ($e->getPrevious()) {
+ $this->previous = new self($e->getPrevious());
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function getClassName()
+ {
+ return $this->className;
+ }
+
+ /**
+ * @return PHPUnit_Framework_ExceptionWrapper
+ */
+ public function getPreviousWrapped()
+ {
+ return $this->previous;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ $string = PHPUnit_Framework_TestFailure::exceptionToString($this);
+
+ if ($trace = PHPUnit_Util_Filter::getFilteredStacktrace($this)) {
+ $string .= "\n" . $trace;
+ }
+
+ if ($this->previous) {
+ $string .= "\nCaused by\n" . $this->previous;
+ }
+
+ return $string;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/ExpectationFailedException.php b/vendor/phpunit/phpunit/src/Framework/ExpectationFailedException.php
new file mode 100644
index 0000000..67d30ef
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/ExpectationFailedException.php
@@ -0,0 +1,39 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Exception for expectations which failed their check.
+ *
+ * The exception contains the error message and optionally a
+ * SebastianBergmann\Comparator\ComparisonFailure which is used to
+ * generate diff output of the failed expectations.
+ */
+class PHPUnit_Framework_ExpectationFailedException extends PHPUnit_Framework_AssertionFailedError
+{
+ /**
+ * @var SebastianBergmann\Comparator\ComparisonFailure
+ */
+ protected $comparisonFailure;
+
+ public function __construct($message, SebastianBergmann\Comparator\ComparisonFailure $comparisonFailure = null, Exception $previous = null)
+ {
+ $this->comparisonFailure = $comparisonFailure;
+
+ parent::__construct($message, 0, $previous);
+ }
+
+ /**
+ * @return SebastianBergmann\Comparator\ComparisonFailure
+ */
+ public function getComparisonFailure()
+ {
+ return $this->comparisonFailure;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/IncompleteTest.php b/vendor/phpunit/phpunit/src/Framework/IncompleteTest.php
new file mode 100644
index 0000000..6ce0a8a
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/IncompleteTest.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A marker interface for marking any exception/error as result of an unit
+ * test as incomplete implementation or currently not implemented.
+ */
+interface PHPUnit_Framework_IncompleteTest
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/IncompleteTestCase.php b/vendor/phpunit/phpunit/src/Framework/IncompleteTestCase.php
new file mode 100644
index 0000000..7b5179c
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/IncompleteTestCase.php
@@ -0,0 +1,82 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * An incomplete test case
+ */
+class PHPUnit_Framework_IncompleteTestCase extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @var string
+ */
+ protected $message = '';
+
+ /**
+ * @var bool
+ */
+ protected $backupGlobals = false;
+
+ /**
+ * @var bool
+ */
+ protected $backupStaticAttributes = false;
+
+ /**
+ * @var bool
+ */
+ protected $runTestInSeparateProcess = false;
+
+ /**
+ * @var bool
+ */
+ protected $useErrorHandler = false;
+
+ /**
+ * @var bool
+ */
+ protected $useOutputBuffering = false;
+
+ /**
+ * @param string $className
+ * @param string $methodName
+ * @param string $message
+ */
+ public function __construct($className, $methodName, $message = '')
+ {
+ $this->message = $message;
+ parent::__construct($className . '::' . $methodName);
+ }
+
+ /**
+ * @throws PHPUnit_Framework_Exception
+ */
+ protected function runTest()
+ {
+ $this->markTestIncomplete($this->message);
+ }
+
+ /**
+ * @return string
+ */
+ public function getMessage()
+ {
+ return $this->message;
+ }
+
+ /**
+ * Returns a string representation of the test case.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return $this->getName();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/IncompleteTestError.php b/vendor/phpunit/phpunit/src/Framework/IncompleteTestError.php
new file mode 100644
index 0000000..e056c93
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/IncompleteTestError.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
+ * case of an incomplete test.
+ */
+class PHPUnit_Framework_IncompleteTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_IncompleteTest
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php b/vendor/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php
new file mode 100644
index 0000000..8efa6e7
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php
@@ -0,0 +1,13 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Framework_InvalidCoversTargetException extends PHPUnit_Framework_CodeCoverageException
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php b/vendor/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php
new file mode 100644
index 0000000..7d0565c
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/MissingCoversAnnotationException.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Extension to PHPUnit_Framework_AssertionFailedError to mark a test as risky
+ * when it does not have a @covers annotation but is expected to have one.
+ */
+class PHPUnit_Framework_MissingCoversAnnotationException extends PHPUnit_Framework_RiskyTestError
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/OutputError.php b/vendor/phpunit/phpunit/src/Framework/OutputError.php
new file mode 100644
index 0000000..86c0444
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/OutputError.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
+ * case of a test that printed output.
+ */
+class PHPUnit_Framework_OutputError extends PHPUnit_Framework_AssertionFailedError
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/RiskyTest.php b/vendor/phpunit/phpunit/src/Framework/RiskyTest.php
new file mode 100644
index 0000000..6aa56e1
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/RiskyTest.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A marker interface for marking any exception/error as result of an unit
+ * test as risky.
+ */
+interface PHPUnit_Framework_RiskyTest
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/RiskyTestError.php b/vendor/phpunit/phpunit/src/Framework/RiskyTestError.php
new file mode 100644
index 0000000..e7b6c0f
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/RiskyTestError.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
+ * case of a risky test.
+ */
+class PHPUnit_Framework_RiskyTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_RiskyTest
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/SelfDescribing.php b/vendor/phpunit/phpunit/src/Framework/SelfDescribing.php
new file mode 100644
index 0000000..a328628
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/SelfDescribing.php
@@ -0,0 +1,22 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Interface for classes that can return a description of itself.
+ */
+interface PHPUnit_Framework_SelfDescribing
+{
+ /**
+ * Returns a string representation of the object.
+ *
+ * @return string
+ */
+ public function toString();
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/SkippedTest.php b/vendor/phpunit/phpunit/src/Framework/SkippedTest.php
new file mode 100644
index 0000000..14c9cd0
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/SkippedTest.php
@@ -0,0 +1,16 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A marker interface for marking a unit test as being skipped.
+ */
+interface PHPUnit_Framework_SkippedTest
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/SkippedTestCase.php b/vendor/phpunit/phpunit/src/Framework/SkippedTestCase.php
new file mode 100644
index 0000000..5b6cdf8
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/SkippedTestCase.php
@@ -0,0 +1,80 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A skipped test case
+ */
+class PHPUnit_Framework_SkippedTestCase extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @var string
+ */
+ protected $message = '';
+
+ /**
+ * @var bool
+ */
+ protected $backupGlobals = false;
+
+ /**
+ * @var bool
+ */
+ protected $backupStaticAttributes = false;
+
+ /**
+ * @var bool
+ */
+ protected $runTestInSeparateProcess = false;
+
+ /**
+ * @var bool
+ */
+ protected $useErrorHandler = false;
+
+ /**
+ * @var bool
+ */
+ protected $useOutputBuffering = false;
+
+ /**
+ * @param string $message
+ */
+ public function __construct($className, $methodName, $message = '')
+ {
+ $this->message = $message;
+ parent::__construct($className . '::' . $methodName);
+ }
+
+ /**
+ * @throws PHPUnit_Framework_Exception
+ */
+ protected function runTest()
+ {
+ $this->markTestSkipped($this->message);
+ }
+
+ /**
+ * @return string
+ */
+ public function getMessage()
+ {
+ return $this->message;
+ }
+
+ /**
+ * Returns a string representation of the test case.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return $this->getName();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/SkippedTestError.php b/vendor/phpunit/phpunit/src/Framework/SkippedTestError.php
new file mode 100644
index 0000000..7b19cca
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/SkippedTestError.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
+ * case of a skipped test.
+ */
+class PHPUnit_Framework_SkippedTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_SkippedTest
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php b/vendor/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php
new file mode 100644
index 0000000..e5588bd
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
+ * case of a skipped test suite.
+ */
+class PHPUnit_Framework_SkippedTestSuiteError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_SkippedTest
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/SyntheticError.php b/vendor/phpunit/phpunit/src/Framework/SyntheticError.php
new file mode 100644
index 0000000..d7637ee
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/SyntheticError.php
@@ -0,0 +1,78 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Creates a synthetic failed assertion.
+ */
+class PHPUnit_Framework_SyntheticError extends PHPUnit_Framework_AssertionFailedError
+{
+ /**
+ * The synthetic file.
+ *
+ * @var string
+ */
+ protected $syntheticFile = '';
+
+ /**
+ * The synthetic line number.
+ *
+ * @var int
+ */
+ protected $syntheticLine = 0;
+
+ /**
+ * The synthetic trace.
+ *
+ * @var array
+ */
+ protected $syntheticTrace = [];
+
+ /**
+ * Constructor.
+ *
+ * @param string $message
+ * @param int $code
+ * @param string $file
+ * @param int $line
+ * @param array $trace
+ */
+ public function __construct($message, $code, $file, $line, $trace)
+ {
+ parent::__construct($message, $code);
+
+ $this->syntheticFile = $file;
+ $this->syntheticLine = $line;
+ $this->syntheticTrace = $trace;
+ }
+
+ /**
+ * @return string
+ */
+ public function getSyntheticFile()
+ {
+ return $this->syntheticFile;
+ }
+
+ /**
+ * @return int
+ */
+ public function getSyntheticLine()
+ {
+ return $this->syntheticLine;
+ }
+
+ /**
+ * @return array
+ */
+ public function getSyntheticTrace()
+ {
+ return $this->syntheticTrace;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Test.php b/vendor/phpunit/phpunit/src/Framework/Test.php
new file mode 100644
index 0000000..d488c17
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Test.php
@@ -0,0 +1,24 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A Test can be run and collect its results.
+ */
+interface PHPUnit_Framework_Test extends Countable
+{
+ /**
+ * Runs a test and collects its result in a TestResult instance.
+ *
+ * @param PHPUnit_Framework_TestResult $result
+ *
+ * @return PHPUnit_Framework_TestResult
+ */
+ public function run(PHPUnit_Framework_TestResult $result = null);
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/TestCase.php b/vendor/phpunit/phpunit/src/Framework/TestCase.php
new file mode 100644
index 0000000..bb3e870
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/TestCase.php
@@ -0,0 +1,2491 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use SebastianBergmann\GlobalState\Snapshot;
+use SebastianBergmann\GlobalState\Restorer;
+use SebastianBergmann\GlobalState\Blacklist;
+use SebastianBergmann\Diff\Differ;
+use SebastianBergmann\Exporter\Exporter;
+use SebastianBergmann\ObjectEnumerator\Enumerator;
+use Prophecy\Exception\Prediction\PredictionException;
+use Prophecy\Prophet;
+use DeepCopy\DeepCopy;
+
+/**
+ * A TestCase defines the fixture to run multiple tests.
+ *
+ * To define a TestCase
+ *
+ * 1) Implement a subclass of PHPUnit_Framework_TestCase.
+ * 2) Define instance variables that store the state of the fixture.
+ * 3) Initialize the fixture state by overriding setUp().
+ * 4) Clean-up after a test by overriding tearDown().
+ *
+ * Each test runs in its own fixture so there can be no side effects
+ * among test runs.
+ *
+ * Here is an example:
+ *
+ * <code>
+ * <?php
+ * class MathTest extends PHPUnit_Framework_TestCase
+ * {
+ * public $value1;
+ * public $value2;
+ *
+ * protected function setUp()
+ * {
+ * $this->value1 = 2;
+ * $this->value2 = 3;
+ * }
+ * }
+ * ?>
+ * </code>
+ *
+ * For each test implement a method which interacts with the fixture.
+ * Verify the expected results with assertions specified by calling
+ * assert with a boolean.
+ *
+ * <code>
+ * <?php
+ * public function testPass()
+ * {
+ * $this->assertTrue($this->value1 + $this->value2 == 5);
+ * }
+ * ?>
+ * </code>
+ */
+abstract class PHPUnit_Framework_TestCase extends PHPUnit_Framework_Assert implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing
+{
+ /**
+ * Enable or disable the backup and restoration of the $GLOBALS array.
+ * Overwrite this attribute in a child class of TestCase.
+ * Setting this attribute in setUp() has no effect!
+ *
+ * @var bool
+ */
+ protected $backupGlobals = null;
+
+ /**
+ * @var array
+ */
+ protected $backupGlobalsBlacklist = [];
+
+ /**
+ * Enable or disable the backup and restoration of static attributes.
+ * Overwrite this attribute in a child class of TestCase.
+ * Setting this attribute in setUp() has no effect!
+ *
+ * @var bool
+ */
+ protected $backupStaticAttributes = null;
+
+ /**
+ * @var array
+ */
+ protected $backupStaticAttributesBlacklist = [];
+
+ /**
+ * Whether or not this test is to be run in a separate PHP process.
+ *
+ * @var bool
+ */
+ protected $runTestInSeparateProcess = null;
+
+ /**
+ * Whether or not this test should preserve the global state when
+ * running in a separate PHP process.
+ *
+ * @var bool
+ */
+ protected $preserveGlobalState = true;
+
+ /**
+ * Whether or not this test is running in a separate PHP process.
+ *
+ * @var bool
+ */
+ private $inIsolation = false;
+
+ /**
+ * @var array
+ */
+ private $data = [];
+
+ /**
+ * @var string
+ */
+ private $dataName = '';
+
+ /**
+ * @var bool
+ */
+ private $useErrorHandler = null;
+
+ /**
+ * The name of the expected Exception.
+ *
+ * @var string
+ */
+ private $expectedException = null;
+
+ /**
+ * The message of the expected Exception.
+ *
+ * @var string
+ */
+ private $expectedExceptionMessage = null;
+
+ /**
+ * The regex pattern to validate the expected Exception message.
+ *
+ * @var string
+ */
+ private $expectedExceptionMessageRegExp = null;
+
+ /**
+ * The code of the expected Exception.
+ *
+ * @var int|string
+ */
+ private $expectedExceptionCode = null;
+
+ /**
+ * The name of the test case.
+ *
+ * @var string
+ */
+ private $name = null;
+
+ /**
+ * @var array
+ */
+ private $dependencies = [];
+
+ /**
+ * @var array
+ */
+ private $dependencyInput = [];
+
+ /**
+ * @var array
+ */
+ private $iniSettings = [];
+
+ /**
+ * @var array
+ */
+ private $locale = [];
+
+ /**
+ * @var array
+ */
+ private $mockObjects = [];
+
+ /**
+ * @var MockGenerator
+ */
+ private $mockObjectGenerator = null;
+
+ /**
+ * @var int
+ */
+ private $status;
+
+ /**
+ * @var string
+ */
+ private $statusMessage = '';
+
+ /**
+ * @var int
+ */
+ private $numAssertions = 0;
+
+ /**
+ * @var PHPUnit_Framework_TestResult
+ */
+ private $result;
+
+ /**
+ * @var mixed
+ */
+ private $testResult;
+
+ /**
+ * @var string
+ */
+ private $output = '';
+
+ /**
+ * @var string
+ */
+ private $outputExpectedRegex = null;
+
+ /**
+ * @var string
+ */
+ private $outputExpectedString = null;
+
+ /**
+ * @var mixed
+ */
+ private $outputCallback = false;
+
+ /**
+ * @var bool
+ */
+ private $outputBufferingActive = false;
+
+ /**
+ * @var int
+ */
+ private $outputBufferingLevel;
+
+ /**
+ * @var SebastianBergmann\GlobalState\Snapshot
+ */
+ private $snapshot;
+
+ /**
+ * @var Prophecy\Prophet
+ */
+ private $prophet;
+
+ /**
+ * @var bool
+ */
+ private $beStrictAboutChangesToGlobalState = false;
+
+ /**
+ * @var bool
+ */
+ private $registerMockObjectsFromTestArgumentsRecursively = false;
+
+ /**
+ * @var string[]
+ */
+ private $warnings = [];
+
+ /**
+ * @var array
+ */
+ private $groups = [];
+
+ /**
+ * @var bool
+ */
+ private $doesNotPerformAssertions = false;
+
+ /**
+ * Constructs a test case with the given name.
+ *
+ * @param string $name
+ * @param array $data
+ * @param string $dataName
+ */
+ public function __construct($name = null, array $data = [], $dataName = '')
+ {
+ if ($name !== null) {
+ $this->setName($name);
+ }
+
+ $this->data = $data;
+ $this->dataName = $dataName;
+ }
+
+ /**
+ * Returns a string representation of the test case.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ $class = new ReflectionClass($this);
+
+ $buffer = sprintf(
+ '%s::%s',
+ $class->name,
+ $this->getName(false)
+ );
+
+ return $buffer . $this->getDataSetAsString();
+ }
+
+ /**
+ * Counts the number of test cases executed by run(TestResult result).
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return 1;
+ }
+
+ public function getGroups()
+ {
+ return $this->groups;
+ }
+
+ /**
+ * @param array $groups
+ */
+ public function setGroups(array $groups)
+ {
+ $this->groups = $groups;
+ }
+
+ /**
+ * Returns the annotations for this test.
+ *
+ * @return array
+ */
+ public function getAnnotations()
+ {
+ return PHPUnit_Util_Test::parseTestMethodAnnotations(
+ get_class($this),
+ $this->name
+ );
+ }
+
+ /**
+ * Gets the name of a TestCase.
+ *
+ * @param bool $withDataSet
+ *
+ * @return string
+ */
+ public function getName($withDataSet = true)
+ {
+ if ($withDataSet) {
+ return $this->name . $this->getDataSetAsString(false);
+ } else {
+ return $this->name;
+ }
+ }
+
+ /**
+ * Returns the size of the test.
+ *
+ * @return int
+ */
+ public function getSize()
+ {
+ return PHPUnit_Util_Test::getSize(
+ get_class($this),
+ $this->getName(false)
+ );
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasSize()
+ {
+ return $this->getSize() !== PHPUnit_Util_Test::UNKNOWN;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isSmall()
+ {
+ return $this->getSize() === PHPUnit_Util_Test::SMALL;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isMedium()
+ {
+ return $this->getSize() === PHPUnit_Util_Test::MEDIUM;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isLarge()
+ {
+ return $this->getSize() === PHPUnit_Util_Test::LARGE;
+ }
+
+ /**
+ * @return string
+ */
+ public function getActualOutput()
+ {
+ if (!$this->outputBufferingActive) {
+ return $this->output;
+ } else {
+ return ob_get_contents();
+ }
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasOutput()
+ {
+ if (strlen($this->output) === 0) {
+ return false;
+ }
+
+ if ($this->hasExpectationOnOutput()) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * @return bool
+ */
+ public function doesNotPerformAssertions()
+ {
+ return $this->doesNotPerformAssertions;
+ }
+
+ /**
+ * @param string $expectedRegex
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function expectOutputRegex($expectedRegex)
+ {
+ if ($this->outputExpectedString !== null) {
+ throw new PHPUnit_Framework_Exception;
+ }
+
+ if (is_string($expectedRegex) || is_null($expectedRegex)) {
+ $this->outputExpectedRegex = $expectedRegex;
+ }
+ }
+
+ /**
+ * @param string $expectedString
+ */
+ public function expectOutputString($expectedString)
+ {
+ if ($this->outputExpectedRegex !== null) {
+ throw new PHPUnit_Framework_Exception;
+ }
+
+ if (is_string($expectedString) || is_null($expectedString)) {
+ $this->outputExpectedString = $expectedString;
+ }
+ }
+
+ /**
+ * @return bool
+ *
+ * @deprecated Use hasExpectationOnOutput() instead
+ */
+ public function hasPerformedExpectationsOnOutput()
+ {
+ return $this->hasExpectationOnOutput();
+ }
+
+ /**
+ * @return bool
+ */
+ public function hasExpectationOnOutput()
+ {
+ return is_string($this->outputExpectedString) || is_string($this->outputExpectedRegex);
+ }
+
+ /**
+ * @return string
+ */
+ public function getExpectedException()
+ {
+ return $this->expectedException;
+ }
+
+ /**
+ * @param mixed $exception
+ * @param string $message Null means we do not check message at all, string (even empty) means we do. Default: null.
+ * @param int|string $code Null means we do not check code at all, non-null means we do.
+ *
+ * @throws PHPUnit_Framework_Exception
+ *
+ * @deprecated Method deprecated since Release 5.2.0; use expectException() instead
+ */
+ public function setExpectedException($exception, $message = '', $code = null)
+ {
+ if (null !== $message && !is_string($message)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
+ }
+
+ if (func_num_args() < 2) {
+ $message = null;
+ }
+
+ $this->expectedException = $exception;
+
+ if ($message !== null) {
+ $this->expectExceptionMessage($message);
+ }
+
+ if ($code !== null) {
+ $this->expectExceptionCode($code);
+ }
+ }
+
+ /**
+ * @param mixed $exception
+ * @param string $messageRegExp
+ * @param int $code
+ *
+ * @throws PHPUnit_Framework_Exception
+ *
+ * @deprecated Method deprecated since Release 5.6.0; use expectExceptionMessageRegExp() instead
+ */
+ public function setExpectedExceptionRegExp($exception, $messageRegExp = '', $code = null)
+ {
+ if (!is_string($messageRegExp)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
+ }
+
+ $this->expectedException = $exception;
+ $this->expectedExceptionMessageRegExp = $messageRegExp;
+
+ if ($code !== null) {
+ $this->expectExceptionCode($code);
+ }
+ }
+
+ /**
+ * @param string $exception
+ */
+ public function expectException($exception)
+ {
+ if (!is_string($exception)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ $this->expectedException = $exception;
+ }
+
+ /**
+ * @param int|string $code
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function expectExceptionCode($code)
+ {
+ if (!$this->expectedException) {
+ $this->expectedException = \Exception::class;
+ }
+
+ if (!is_int($code) && !is_string($code)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer or string');
+ }
+
+ $this->expectedExceptionCode = $code;
+ }
+
+ /**
+ * @param string $message
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function expectExceptionMessage($message)
+ {
+ if (!$this->expectedException) {
+ $this->expectedException = \Exception::class;
+ }
+
+ if (!is_string($message)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ $this->expectedExceptionMessage = $message;
+ }
+
+ /**
+ * @param string $messageRegExp
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function expectExceptionMessageRegExp($messageRegExp)
+ {
+ if (!is_string($messageRegExp)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ $this->expectedExceptionMessageRegExp = $messageRegExp;
+ }
+
+ /**
+ * @param bool $flag
+ */
+ public function setRegisterMockObjectsFromTestArgumentsRecursively($flag)
+ {
+ if (!is_bool($flag)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+
+ $this->registerMockObjectsFromTestArgumentsRecursively = $flag;
+ }
+
+ protected function setExpectedExceptionFromAnnotation()
+ {
+ try {
+ $expectedException = PHPUnit_Util_Test::getExpectedException(
+ get_class($this),
+ $this->name
+ );
+
+ if ($expectedException !== false) {
+ $this->expectException($expectedException['class']);
+
+ if ($expectedException['code'] !== null) {
+ $this->expectExceptionCode($expectedException['code']);
+ }
+
+ if ($expectedException['message'] !== '') {
+ $this->expectExceptionMessage($expectedException['message']);
+ } elseif ($expectedException['message_regex'] !== '') {
+ $this->expectExceptionMessageRegExp($expectedException['message_regex']);
+ }
+ }
+ } catch (ReflectionException $e) {
+ }
+ }
+
+ /**
+ * @param bool $useErrorHandler
+ */
+ public function setUseErrorHandler($useErrorHandler)
+ {
+ $this->useErrorHandler = $useErrorHandler;
+ }
+
+ protected function setUseErrorHandlerFromAnnotation()
+ {
+ try {
+ $useErrorHandler = PHPUnit_Util_Test::getErrorHandlerSettings(
+ get_class($this),
+ $this->name
+ );
+
+ if ($useErrorHandler !== null) {
+ $this->setUseErrorHandler($useErrorHandler);
+ }
+ } catch (ReflectionException $e) {
+ }
+ }
+
+ protected function checkRequirements()
+ {
+ if (!$this->name || !method_exists($this, $this->name)) {
+ return;
+ }
+
+ $missingRequirements = PHPUnit_Util_Test::getMissingRequirements(
+ get_class($this),
+ $this->name
+ );
+
+ if (!empty($missingRequirements)) {
+ $this->markTestSkipped(implode(PHP_EOL, $missingRequirements));
+ }
+ }
+
+ /**
+ * Returns the status of this test.
+ *
+ * @return int
+ */
+ public function getStatus()
+ {
+ return $this->status;
+ }
+
+ public function markAsRisky()
+ {
+ $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_RISKY;
+ }
+
+ /**
+ * Returns the status message of this test.
+ *
+ * @return string
+ */
+ public function getStatusMessage()
+ {
+ return $this->statusMessage;
+ }
+
+ /**
+ * Returns whether or not this test has failed.
+ *
+ * @return bool
+ */
+ public function hasFailed()
+ {
+ $status = $this->getStatus();
+
+ return $status == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE ||
+ $status == PHPUnit_Runner_BaseTestRunner::STATUS_ERROR;
+ }
+
+ /**
+ * Runs the test case and collects the results in a TestResult object.
+ * If no TestResult object is passed a new one will be created.
+ *
+ * @param PHPUnit_Framework_TestResult $result
+ *
+ * @return PHPUnit_Framework_TestResult
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function run(PHPUnit_Framework_TestResult $result = null)
+ {
+ if ($result === null) {
+ $result = $this->createResult();
+ }
+
+ if (!$this instanceof PHPUnit_Framework_WarningTestCase) {
+ $this->setTestResultObject($result);
+ $this->setUseErrorHandlerFromAnnotation();
+ }
+
+ if ($this->useErrorHandler !== null) {
+ $oldErrorHandlerSetting = $result->getConvertErrorsToExceptions();
+ $result->convertErrorsToExceptions($this->useErrorHandler);
+ }
+
+ if (!$this instanceof PHPUnit_Framework_WarningTestCase &&
+ !$this instanceof PHPUnit_Framework_SkippedTestCase &&
+ !$this->handleDependencies()) {
+ return;
+ }
+
+ if ($this->runTestInSeparateProcess === true &&
+ $this->inIsolation !== true &&
+ !$this instanceof PHPUnit_Extensions_PhptTestCase) {
+ $class = new ReflectionClass($this);
+
+ $template = new Text_Template(
+ __DIR__ . '/../Util/PHP/Template/TestCaseMethod.tpl'
+ );
+
+ if ($this->preserveGlobalState) {
+ $constants = PHPUnit_Util_GlobalState::getConstantsAsString();
+ $globals = PHPUnit_Util_GlobalState::getGlobalsAsString();
+ $includedFiles = PHPUnit_Util_GlobalState::getIncludedFilesAsString();
+ $iniSettings = PHPUnit_Util_GlobalState::getIniSettingsAsString();
+ } else {
+ $constants = '';
+ if (!empty($GLOBALS['__PHPUNIT_BOOTSTRAP'])) {
+ $globals = '$GLOBALS[\'__PHPUNIT_BOOTSTRAP\'] = ' . var_export($GLOBALS['__PHPUNIT_BOOTSTRAP'], true) . ";\n";
+ } else {
+ $globals = '';
+ }
+ $includedFiles = '';
+ $iniSettings = '';
+ }
+
+ $coverage = $result->getCollectCodeCoverageInformation() ? 'true' : 'false';
+ $isStrictAboutTestsThatDoNotTestAnything = $result->isStrictAboutTestsThatDoNotTestAnything() ? 'true' : 'false';
+ $isStrictAboutOutputDuringTests = $result->isStrictAboutOutputDuringTests() ? 'true' : 'false';
+ $enforcesTimeLimit = $result->enforcesTimeLimit() ? 'true' : 'false';
+ $isStrictAboutTodoAnnotatedTests = $result->isStrictAboutTodoAnnotatedTests() ? 'true' : 'false';
+ $isStrictAboutResourceUsageDuringSmallTests = $result->isStrictAboutResourceUsageDuringSmallTests() ? 'true' : 'false';
+
+ if (defined('PHPUNIT_COMPOSER_INSTALL')) {
+ $composerAutoload = var_export(PHPUNIT_COMPOSER_INSTALL, true);
+ } else {
+ $composerAutoload = '\'\'';
+ }
+
+ if (defined('__PHPUNIT_PHAR__')) {
+ $phar = var_export(__PHPUNIT_PHAR__, true);
+ } else {
+ $phar = '\'\'';
+ }
+
+ if ($result->getCodeCoverage()) {
+ $codeCoverageFilter = $result->getCodeCoverage()->filter();
+ } else {
+ $codeCoverageFilter = null;
+ }
+
+ $data = var_export(serialize($this->data), true);
+ $dataName = var_export($this->dataName, true);
+ $dependencyInput = var_export(serialize($this->dependencyInput), true);
+ $includePath = var_export(get_include_path(), true);
+ $codeCoverageFilter = var_export(serialize($codeCoverageFilter), true);
+ // must do these fixes because TestCaseMethod.tpl has unserialize('{data}') in it, and we can't break BC
+ // the lines above used to use addcslashes() rather than var_export(), which breaks null byte escape sequences
+ $data = "'." . $data . ".'";
+ $dataName = "'.(" . $dataName . ").'";
+ $dependencyInput = "'." . $dependencyInput . ".'";
+ $includePath = "'." . $includePath . ".'";
+ $codeCoverageFilter = "'." . $codeCoverageFilter . ".'";
+
+ $configurationFilePath = (isset($GLOBALS['__PHPUNIT_CONFIGURATION_FILE']) ? $GLOBALS['__PHPUNIT_CONFIGURATION_FILE'] : '');
+
+ $template->setVar(
+ [
+ 'composerAutoload' => $composerAutoload,
+ 'phar' => $phar,
+ 'filename' => $class->getFileName(),
+ 'className' => $class->getName(),
+ 'methodName' => $this->name,
+ 'collectCodeCoverageInformation' => $coverage,
+ 'data' => $data,
+ 'dataName' => $dataName,
+ 'dependencyInput' => $dependencyInput,
+ 'constants' => $constants,
+ 'globals' => $globals,
+ 'include_path' => $includePath,
+ 'included_files' => $includedFiles,
+ 'iniSettings' => $iniSettings,
+ 'isStrictAboutTestsThatDoNotTestAnything' => $isStrictAboutTestsThatDoNotTestAnything,
+ 'isStrictAboutOutputDuringTests' => $isStrictAboutOutputDuringTests,
+ 'enforcesTimeLimit' => $enforcesTimeLimit,
+ 'isStrictAboutTodoAnnotatedTests' => $isStrictAboutTodoAnnotatedTests,
+ 'isStrictAboutResourceUsageDuringSmallTests' => $isStrictAboutResourceUsageDuringSmallTests,
+ 'codeCoverageFilter' => $codeCoverageFilter,
+ 'configurationFilePath' => $configurationFilePath
+ ]
+ );
+
+ $this->prepareTemplate($template);
+
+ $php = PHPUnit_Util_PHP::factory();
+ $php->runTestJob($template->render(), $this, $result);
+ } else {
+ $result->run($this);
+ }
+
+ if (isset($oldErrorHandlerSetting)) {
+ $result->convertErrorsToExceptions($oldErrorHandlerSetting);
+ }
+
+ $this->result = null;
+
+ return $result;
+ }
+
+ /**
+ * Runs the bare test sequence.
+ */
+ public function runBare()
+ {
+ $this->numAssertions = 0;
+
+ $this->snapshotGlobalState();
+ $this->startOutputBuffering();
+ clearstatcache();
+ $currentWorkingDirectory = getcwd();
+
+ $hookMethods = PHPUnit_Util_Test::getHookMethods(get_class($this));
+
+ try {
+ $hasMetRequirements = false;
+ $this->checkRequirements();
+ $hasMetRequirements = true;
+
+ if ($this->inIsolation) {
+ foreach ($hookMethods['beforeClass'] as $method) {
+ $this->$method();
+ }
+ }
+
+ $this->setExpectedExceptionFromAnnotation();
+ $this->setDoesNotPerformAssertionsFromAnnotation();
+
+ foreach ($hookMethods['before'] as $method) {
+ $this->$method();
+ }
+
+ $this->assertPreConditions();
+ $this->testResult = $this->runTest();
+ $this->verifyMockObjects();
+ $this->assertPostConditions();
+
+ if (!empty($this->warnings)) {
+ throw new PHPUnit_Framework_Warning(
+ implode(
+ "\n",
+ array_unique($this->warnings)
+ )
+ );
+ }
+
+ $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_PASSED;
+ } catch (PHPUnit_Framework_IncompleteTest $e) {
+ $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE;
+ $this->statusMessage = $e->getMessage();
+ } catch (PHPUnit_Framework_SkippedTest $e) {
+ $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED;
+ $this->statusMessage = $e->getMessage();
+ } catch (PHPUnit_Framework_Warning $e) {
+ $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_WARNING;
+ $this->statusMessage = $e->getMessage();
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE;
+ $this->statusMessage = $e->getMessage();
+ } catch (PredictionException $e) {
+ $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE;
+ $this->statusMessage = $e->getMessage();
+ } catch (Throwable $_e) {
+ $e = $_e;
+ } catch (Exception $_e) {
+ $e = $_e;
+ }
+
+ // Clean up the mock objects.
+ $this->mockObjects = [];
+ $this->prophet = null;
+
+ // Tear down the fixture. An exception raised in tearDown() will be
+ // caught and passed on when no exception was raised before.
+ try {
+ if ($hasMetRequirements) {
+ foreach ($hookMethods['after'] as $method) {
+ $this->$method();
+ }
+
+ if ($this->inIsolation) {
+ foreach ($hookMethods['afterClass'] as $method) {
+ $this->$method();
+ }
+ }
+ }
+ } catch (Throwable $_e) {
+ if (!isset($e)) {
+ $e = $_e;
+ }
+ } catch (Exception $_e) {
+ if (!isset($e)) {
+ $e = $_e;
+ }
+ }
+
+ try {
+ $this->stopOutputBuffering();
+ } catch (PHPUnit_Framework_RiskyTestError $_e) {
+ if (!isset($e)) {
+ $e = $_e;
+ }
+ }
+
+ if (isset($_e)) {
+ $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_ERROR;
+ $this->statusMessage = $_e->getMessage();
+ }
+
+ clearstatcache();
+
+ if ($currentWorkingDirectory != getcwd()) {
+ chdir($currentWorkingDirectory);
+ }
+
+ $this->restoreGlobalState();
+
+ // Clean up INI settings.
+ foreach ($this->iniSettings as $varName => $oldValue) {
+ ini_set($varName, $oldValue);
+ }
+
+ $this->iniSettings = [];
+
+ // Clean up locale settings.
+ foreach ($this->locale as $category => $locale) {
+ setlocale($category, $locale);
+ }
+
+ // Perform assertion on output.
+ if (!isset($e)) {
+ try {
+ if ($this->outputExpectedRegex !== null) {
+ $this->assertRegExp($this->outputExpectedRegex, $this->output);
+ } elseif ($this->outputExpectedString !== null) {
+ $this->assertEquals($this->outputExpectedString, $this->output);
+ }
+ } catch (Throwable $_e) {
+ $e = $_e;
+ } catch (Exception $_e) {
+ $e = $_e;
+ }
+ }
+
+ // Workaround for missing "finally".
+ if (isset($e)) {
+ if ($e instanceof PredictionException) {
+ $e = new PHPUnit_Framework_AssertionFailedError($e->getMessage());
+ }
+
+ $this->onNotSuccessfulTest($e);
+ }
+ }
+
+ /**
+ * Override to run the test and assert its state.
+ *
+ * @return mixed
+ *
+ * @throws Exception|PHPUnit_Framework_Exception
+ * @throws PHPUnit_Framework_Exception
+ */
+ protected function runTest()
+ {
+ if ($this->name === null) {
+ throw new PHPUnit_Framework_Exception(
+ 'PHPUnit_Framework_TestCase::$name must not be null.'
+ );
+ }
+
+ try {
+ $class = new ReflectionClass($this);
+ $method = $class->getMethod($this->name);
+ } catch (ReflectionException $e) {
+ $this->fail($e->getMessage());
+ }
+
+ $testArguments = array_merge($this->data, $this->dependencyInput);
+
+ $this->registerMockObjectsFromTestArguments($testArguments);
+
+ try {
+ $testResult = $method->invokeArgs($this, $testArguments);
+ } catch (Throwable $_e) {
+ $e = $_e;
+ } catch (Exception $_e) {
+ $e = $_e;
+ }
+
+ if (isset($e)) {
+ $checkException = false;
+
+ if (!($e instanceof PHPUnit_Framework_SkippedTestError) && is_string($this->expectedException)) {
+ $checkException = true;
+
+ if ($e instanceof PHPUnit_Framework_Exception) {
+ $checkException = false;
+ }
+
+ $reflector = new ReflectionClass($this->expectedException);
+
+ if ($this->expectedException === 'PHPUnit_Framework_Exception' ||
+ $this->expectedException === '\PHPUnit_Framework_Exception' ||
+ $reflector->isSubclassOf('PHPUnit_Framework_Exception')) {
+ $checkException = true;
+ }
+ }
+
+ if ($checkException) {
+ $this->assertThat(
+ $e,
+ new PHPUnit_Framework_Constraint_Exception(
+ $this->expectedException
+ )
+ );
+
+ if ($this->expectedExceptionMessage !== null) {
+ $this->assertThat(
+ $e,
+ new PHPUnit_Framework_Constraint_ExceptionMessage(
+ $this->expectedExceptionMessage
+ )
+ );
+ }
+
+ if ($this->expectedExceptionMessageRegExp !== null) {
+ $this->assertThat(
+ $e,
+ new PHPUnit_Framework_Constraint_ExceptionMessageRegExp(
+ $this->expectedExceptionMessageRegExp
+ )
+ );
+ }
+
+ if ($this->expectedExceptionCode !== null) {
+ $this->assertThat(
+ $e,
+ new PHPUnit_Framework_Constraint_ExceptionCode(
+ $this->expectedExceptionCode
+ )
+ );
+ }
+
+ return;
+ } else {
+ throw $e;
+ }
+ }
+
+ if ($this->expectedException !== null) {
+ $this->assertThat(
+ null,
+ new PHPUnit_Framework_Constraint_Exception(
+ $this->expectedException
+ )
+ );
+ }
+
+ return $testResult;
+ }
+
+ /**
+ * Verifies the mock object expectations.
+ */
+ protected function verifyMockObjects()
+ {
+ foreach ($this->mockObjects as $mockObject) {
+ if ($mockObject->__phpunit_hasMatchers()) {
+ $this->numAssertions++;
+ }
+
+ $mockObject->__phpunit_verify(
+ $this->shouldInvocationMockerBeReset($mockObject)
+ );
+ }
+
+ if ($this->prophet !== null) {
+ try {
+ $this->prophet->checkPredictions();
+ } catch (Throwable $t) {
+ /* Intentionally left empty */
+ } catch (Exception $t) {
+ /* Intentionally left empty */
+ }
+
+ foreach ($this->prophet->getProphecies() as $objectProphecy) {
+ foreach ($objectProphecy->getMethodProphecies() as $methodProphecies) {
+ foreach ($methodProphecies as $methodProphecy) {
+ $this->numAssertions += count($methodProphecy->getCheckedPredictions());
+ }
+ }
+ }
+
+ if (isset($t)) {
+ throw $t;
+ }
+ }
+ }
+
+ /**
+ * Sets the name of a TestCase.
+ *
+ * @param string
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * Sets the dependencies of a TestCase.
+ *
+ * @param array $dependencies
+ */
+ public function setDependencies(array $dependencies)
+ {
+ $this->dependencies = $dependencies;
+ }
+
+ /**
+ * Returns true if the tests has dependencies
+ *
+ * @return bool
+ */
+ public function hasDependencies()
+ {
+ return count($this->dependencies) > 0;
+ }
+
+ /**
+ * Sets
+ *
+ * @param array $dependencyInput
+ */
+ public function setDependencyInput(array $dependencyInput)
+ {
+ $this->dependencyInput = $dependencyInput;
+ }
+
+ /**
+ * @param bool $beStrictAboutChangesToGlobalState
+ */
+ public function setBeStrictAboutChangesToGlobalState($beStrictAboutChangesToGlobalState)
+ {
+ $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState;
+ }
+
+ /**
+ * Calling this method in setUp() has no effect!
+ *
+ * @param bool $backupGlobals
+ */
+ public function setBackupGlobals($backupGlobals)
+ {
+ if (is_null($this->backupGlobals) && is_bool($backupGlobals)) {
+ $this->backupGlobals = $backupGlobals;
+ }
+ }
+
+ /**
+ * Calling this method in setUp() has no effect!
+ *
+ * @param bool $backupStaticAttributes
+ */
+ public function setBackupStaticAttributes($backupStaticAttributes)
+ {
+ if (is_null($this->backupStaticAttributes) &&
+ is_bool($backupStaticAttributes)) {
+ $this->backupStaticAttributes = $backupStaticAttributes;
+ }
+ }
+
+ /**
+ * @param bool $runTestInSeparateProcess
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function setRunTestInSeparateProcess($runTestInSeparateProcess)
+ {
+ if (is_bool($runTestInSeparateProcess)) {
+ if ($this->runTestInSeparateProcess === null) {
+ $this->runTestInSeparateProcess = $runTestInSeparateProcess;
+ }
+ } else {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+ }
+
+ /**
+ * @param bool $preserveGlobalState
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function setPreserveGlobalState($preserveGlobalState)
+ {
+ if (is_bool($preserveGlobalState)) {
+ $this->preserveGlobalState = $preserveGlobalState;
+ } else {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+ }
+
+ /**
+ * @param bool $inIsolation
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function setInIsolation($inIsolation)
+ {
+ if (is_bool($inIsolation)) {
+ $this->inIsolation = $inIsolation;
+ } else {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+ }
+
+ /**
+ * @return bool
+ */
+ public function isInIsolation()
+ {
+ return $this->inIsolation;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getResult()
+ {
+ return $this->testResult;
+ }
+
+ /**
+ * @param mixed $result
+ */
+ public function setResult($result)
+ {
+ $this->testResult = $result;
+ }
+
+ /**
+ * @param callable $callback
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function setOutputCallback($callback)
+ {
+ if (!is_callable($callback)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'callback');
+ }
+
+ $this->outputCallback = $callback;
+ }
+
+ /**
+ * @return PHPUnit_Framework_TestResult
+ */
+ public function getTestResultObject()
+ {
+ return $this->result;
+ }
+
+ /**
+ * @param PHPUnit_Framework_TestResult $result
+ */
+ public function setTestResultObject(PHPUnit_Framework_TestResult $result)
+ {
+ $this->result = $result;
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_MockObject $mockObject
+ */
+ public function registerMockObject(PHPUnit_Framework_MockObject_MockObject $mockObject)
+ {
+ $this->mockObjects[] = $mockObject;
+ }
+
+ /**
+ * This method is a wrapper for the ini_set() function that automatically
+ * resets the modified php.ini setting to its original value after the
+ * test is run.
+ *
+ * @param string $varName
+ * @param string $newValue
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ protected function iniSet($varName, $newValue)
+ {
+ if (!is_string($varName)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ $currentValue = ini_set($varName, $newValue);
+
+ if ($currentValue !== false) {
+ $this->iniSettings[$varName] = $currentValue;
+ } else {
+ throw new PHPUnit_Framework_Exception(
+ sprintf(
+ 'INI setting "%s" could not be set to "%s".',
+ $varName,
+ $newValue
+ )
+ );
+ }
+ }
+
+ /**
+ * This method is a wrapper for the setlocale() function that automatically
+ * resets the locale to its original value after the test is run.
+ *
+ * @param int $category
+ * @param string $locale
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ protected function setLocale()
+ {
+ $args = func_get_args();
+
+ if (count($args) < 2) {
+ throw new PHPUnit_Framework_Exception;
+ }
+
+ $category = $args[0];
+ $locale = $args[1];
+
+ $categories = [
+ LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME
+ ];
+
+ if (defined('LC_MESSAGES')) {
+ $categories[] = LC_MESSAGES;
+ }
+
+ if (!in_array($category, $categories)) {
+ throw new PHPUnit_Framework_Exception;
+ }
+
+ if (!is_array($locale) && !is_string($locale)) {
+ throw new PHPUnit_Framework_Exception;
+ }
+
+ $this->locale[$category] = setlocale($category, 0);
+
+ $result = call_user_func_array('setlocale', $args);
+
+ if ($result === false) {
+ throw new PHPUnit_Framework_Exception(
+ 'The locale functionality is not implemented on your platform, ' .
+ 'the specified locale does not exist or the category name is ' .
+ 'invalid.'
+ );
+ }
+ }
+
+ /**
+ * Returns a builder object to create mock objects using a fluent interface.
+ *
+ * @param string|string[] $className
+ *
+ * @return PHPUnit_Framework_MockObject_MockBuilder
+ */
+ public function getMockBuilder($className)
+ {
+ return new PHPUnit_Framework_MockObject_MockBuilder($this, $className);
+ }
+
+ /**
+ * Returns a test double for the specified class.
+ *
+ * @param string $originalClassName
+ *
+ * @return PHPUnit_Framework_MockObject_MockObject
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ protected function createMock($originalClassName)
+ {
+ return $this->getMockBuilder($originalClassName)
+ ->disableOriginalConstructor()
+ ->disableOriginalClone()
+ ->disableArgumentCloning()
+ ->disallowMockingUnknownTypes()
+ ->getMock();
+ }
+
+ /**
+ * Returns a configured test double for the specified class.
+ *
+ * @param string $originalClassName
+ * @param array $configuration
+ *
+ * @return PHPUnit_Framework_MockObject_MockObject
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ protected function createConfiguredMock($originalClassName, array $configuration)
+ {
+ $o = $this->createMock($originalClassName);
+
+ foreach ($configuration as $method => $return) {
+ $o->method($method)->willReturn($return);
+ }
+
+ return $o;
+ }
+
+ /**
+ * Returns a partial test double for the specified class.
+ *
+ * @param string $originalClassName
+ * @param array $methods
+ *
+ * @return PHPUnit_Framework_MockObject_MockObject
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ protected function createPartialMock($originalClassName, array $methods)
+ {
+ return $this->getMockBuilder($originalClassName)
+ ->disableOriginalConstructor()
+ ->disableOriginalClone()
+ ->disableArgumentCloning()
+ ->disallowMockingUnknownTypes()
+ ->setMethods(empty($methods) ? null : $methods)
+ ->getMock();
+ }
+
+ /**
+ * Returns a mock object for the specified class.
+ *
+ * @param string $originalClassName Name of the class to mock.
+ * @param array|null $methods When provided, only methods whose names are in the array
+ * are replaced with a configurable test double. The behavior
+ * of the other methods is not changed.
+ * Providing null means that no methods will be replaced.
+ * @param array $arguments Parameters to pass to the original class' constructor.
+ * @param string $mockClassName Class name for the generated test double class.
+ * @param bool $callOriginalConstructor Can be used to disable the call to the original class' constructor.
+ * @param bool $callOriginalClone Can be used to disable the call to the original class' clone constructor.
+ * @param bool $callAutoload Can be used to disable __autoload() during the generation of the test double class.
+ * @param bool $cloneArguments
+ * @param bool $callOriginalMethods
+ * @param object $proxyTarget
+ *
+ * @return PHPUnit_Framework_MockObject_MockObject
+ *
+ * @throws PHPUnit_Framework_Exception
+ *
+ * @deprecated Method deprecated since Release 5.4.0; use createMock() or getMockBuilder() instead
+ */
+ protected function getMock($originalClassName, $methods = [], array $arguments = [], $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $cloneArguments = false, $callOriginalMethods = false, $proxyTarget = null)
+ {
+ $this->warnings[] = 'PHPUnit_Framework_TestCase::getMock() is deprecated, use PHPUnit_Framework_TestCase::createMock() or PHPUnit_Framework_TestCase::getMockBuilder() instead';
+
+ $mockObject = $this->getMockObjectGenerator()->getMock(
+ $originalClassName,
+ $methods,
+ $arguments,
+ $mockClassName,
+ $callOriginalConstructor,
+ $callOriginalClone,
+ $callAutoload,
+ $cloneArguments,
+ $callOriginalMethods,
+ $proxyTarget
+ );
+
+ $this->registerMockObject($mockObject);
+
+ return $mockObject;
+ }
+
+ /**
+ * Returns a mock with disabled constructor object for the specified class.
+ *
+ * @param string $originalClassName
+ *
+ * @return PHPUnit_Framework_MockObject_MockObject
+ *
+ * @throws PHPUnit_Framework_Exception
+ *
+ * @deprecated Method deprecated since Release 5.4.0; use createMock() instead
+ */
+ protected function getMockWithoutInvokingTheOriginalConstructor($originalClassName)
+ {
+ $this->warnings[] = 'PHPUnit_Framework_TestCase::getMockWithoutInvokingTheOriginalConstructor() is deprecated, use PHPUnit_Framework_TestCase::createMock() instead';
+
+ return $this->getMockBuilder($originalClassName)
+ ->disableOriginalConstructor()
+ ->getMock();
+ }
+
+ /**
+ * Mocks the specified class and returns the name of the mocked class.
+ *
+ * @param string $originalClassName
+ * @param array $methods
+ * @param array $arguments
+ * @param string $mockClassName
+ * @param bool $callOriginalConstructor
+ * @param bool $callOriginalClone
+ * @param bool $callAutoload
+ * @param bool $cloneArguments
+ *
+ * @return string
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ protected function getMockClass($originalClassName, $methods = [], array $arguments = [], $mockClassName = '', $callOriginalConstructor = false, $callOriginalClone = true, $callAutoload = true, $cloneArguments = false)
+ {
+ $mock = $this->getMockObjectGenerator()->getMock(
+ $originalClassName,
+ $methods,
+ $arguments,
+ $mockClassName,
+ $callOriginalConstructor,
+ $callOriginalClone,
+ $callAutoload,
+ $cloneArguments
+ );
+
+ return get_class($mock);
+ }
+
+ /**
+ * Returns a mock object for the specified abstract class with all abstract
+ * methods of the class mocked. Concrete methods are not mocked by default.
+ * To mock concrete methods, use the 7th parameter ($mockedMethods).
+ *
+ * @param string $originalClassName
+ * @param array $arguments
+ * @param string $mockClassName
+ * @param bool $callOriginalConstructor
+ * @param bool $callOriginalClone
+ * @param bool $callAutoload
+ * @param array $mockedMethods
+ * @param bool $cloneArguments
+ *
+ * @return PHPUnit_Framework_MockObject_MockObject
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ protected function getMockForAbstractClass($originalClassName, array $arguments = [], $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = [], $cloneArguments = false)
+ {
+ $mockObject = $this->getMockObjectGenerator()->getMockForAbstractClass(
+ $originalClassName,
+ $arguments,
+ $mockClassName,
+ $callOriginalConstructor,
+ $callOriginalClone,
+ $callAutoload,
+ $mockedMethods,
+ $cloneArguments
+ );
+
+ $this->registerMockObject($mockObject);
+
+ return $mockObject;
+ }
+
+ /**
+ * Returns a mock object based on the given WSDL file.
+ *
+ * @param string $wsdlFile
+ * @param string $originalClassName
+ * @param string $mockClassName
+ * @param array $methods
+ * @param bool $callOriginalConstructor
+ * @param array $options An array of options passed to SOAPClient::_construct
+ *
+ * @return PHPUnit_Framework_MockObject_MockObject
+ */
+ protected function getMockFromWsdl($wsdlFile, $originalClassName = '', $mockClassName = '', array $methods = [], $callOriginalConstructor = true, array $options = [])
+ {
+ if ($originalClassName === '') {
+ $originalClassName = pathinfo(basename(parse_url($wsdlFile)['path']), PATHINFO_FILENAME);
+ }
+
+ if (!class_exists($originalClassName)) {
+ eval(
+ $this->getMockObjectGenerator()->generateClassFromWsdl(
+ $wsdlFile,
+ $originalClassName,
+ $methods,
+ $options
+ )
+ );
+ }
+
+ $mockObject = $this->getMockObjectGenerator()->getMock(
+ $originalClassName,
+ $methods,
+ ['', $options],
+ $mockClassName,
+ $callOriginalConstructor,
+ false,
+ false
+ );
+
+ $this->registerMockObject($mockObject);
+
+ return $mockObject;
+ }
+
+ /**
+ * Returns a mock object for the specified trait with all abstract methods
+ * of the trait mocked. Concrete methods to mock can be specified with the
+ * `$mockedMethods` parameter.
+ *
+ * @param string $traitName
+ * @param array $arguments
+ * @param string $mockClassName
+ * @param bool $callOriginalConstructor
+ * @param bool $callOriginalClone
+ * @param bool $callAutoload
+ * @param array $mockedMethods
+ * @param bool $cloneArguments
+ *
+ * @return PHPUnit_Framework_MockObject_MockObject
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ protected function getMockForTrait($traitName, array $arguments = [], $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = [], $cloneArguments = false)
+ {
+ $mockObject = $this->getMockObjectGenerator()->getMockForTrait(
+ $traitName,
+ $arguments,
+ $mockClassName,
+ $callOriginalConstructor,
+ $callOriginalClone,
+ $callAutoload,
+ $mockedMethods,
+ $cloneArguments
+ );
+
+ $this->registerMockObject($mockObject);
+
+ return $mockObject;
+ }
+
+ /**
+ * Returns an object for the specified trait.
+ *
+ * @param string $traitName
+ * @param array $arguments
+ * @param string $traitClassName
+ * @param bool $callOriginalConstructor
+ * @param bool $callOriginalClone
+ * @param bool $callAutoload
+ * @param bool $cloneArguments
+ *
+ * @return object
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ protected function getObjectForTrait($traitName, array $arguments = [], $traitClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $cloneArguments = false)
+ {
+ return $this->getMockObjectGenerator()->getObjectForTrait(
+ $traitName,
+ $arguments,
+ $traitClassName,
+ $callOriginalConstructor,
+ $callOriginalClone,
+ $callAutoload,
+ $cloneArguments
+ );
+ }
+
+ /**
+ * @param string|null $classOrInterface
+ *
+ * @return \Prophecy\Prophecy\ObjectProphecy
+ *
+ * @throws \LogicException
+ */
+ protected function prophesize($classOrInterface = null)
+ {
+ return $this->getProphet()->prophesize($classOrInterface);
+ }
+
+ /**
+ * Adds a value to the assertion counter.
+ *
+ * @param int $count
+ */
+ public function addToAssertionCount($count)
+ {
+ $this->numAssertions += $count;
+ }
+
+ /**
+ * Returns the number of assertions performed by this test.
+ *
+ * @return int
+ */
+ public function getNumAssertions()
+ {
+ return $this->numAssertions;
+ }
+
+ /**
+ * Returns a matcher that matches when the method is executed
+ * zero or more times.
+ *
+ * @return PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount
+ */
+ public static function any()
+ {
+ return new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
+ }
+
+ /**
+ * Returns a matcher that matches when the method is never executed.
+ *
+ * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
+ */
+ public static function never()
+ {
+ return new PHPUnit_Framework_MockObject_Matcher_InvokedCount(0);
+ }
+
+ /**
+ * Returns a matcher that matches when the method is executed
+ * at least N times.
+ *
+ * @param int $requiredInvocations
+ *
+ * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount
+ */
+ public static function atLeast($requiredInvocations)
+ {
+ return new PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount(
+ $requiredInvocations
+ );
+ }
+
+ /**
+ * Returns a matcher that matches when the method is executed at least once.
+ *
+ * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce
+ */
+ public static function atLeastOnce()
+ {
+ return new PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce;
+ }
+
+ /**
+ * Returns a matcher that matches when the method is executed exactly once.
+ *
+ * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
+ */
+ public static function once()
+ {
+ return new PHPUnit_Framework_MockObject_Matcher_InvokedCount(1);
+ }
+
+ /**
+ * Returns a matcher that matches when the method is executed
+ * exactly $count times.
+ *
+ * @param int $count
+ *
+ * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
+ */
+ public static function exactly($count)
+ {
+ return new PHPUnit_Framework_MockObject_Matcher_InvokedCount($count);
+ }
+
+ /**
+ * Returns a matcher that matches when the method is executed
+ * at most N times.
+ *
+ * @param int $allowedInvocations
+ *
+ * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount
+ */
+ public static function atMost($allowedInvocations)
+ {
+ return new PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount(
+ $allowedInvocations
+ );
+ }
+
+ /**
+ * Returns a matcher that matches when the method is executed
+ * at the given index.
+ *
+ * @param int $index
+ *
+ * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex
+ */
+ public static function at($index)
+ {
+ return new PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex($index);
+ }
+
+ /**
+ * @param mixed $value
+ *
+ * @return PHPUnit_Framework_MockObject_Stub_Return
+ */
+ public static function returnValue($value)
+ {
+ return new PHPUnit_Framework_MockObject_Stub_Return($value);
+ }
+
+ /**
+ * @param array $valueMap
+ *
+ * @return PHPUnit_Framework_MockObject_Stub_ReturnValueMap
+ */
+ public static function returnValueMap(array $valueMap)
+ {
+ return new PHPUnit_Framework_MockObject_Stub_ReturnValueMap($valueMap);
+ }
+
+ /**
+ * @param int $argumentIndex
+ *
+ * @return PHPUnit_Framework_MockObject_Stub_ReturnArgument
+ */
+ public static function returnArgument($argumentIndex)
+ {
+ return new PHPUnit_Framework_MockObject_Stub_ReturnArgument(
+ $argumentIndex
+ );
+ }
+
+ /**
+ * @param mixed $callback
+ *
+ * @return PHPUnit_Framework_MockObject_Stub_ReturnCallback
+ */
+ public static function returnCallback($callback)
+ {
+ return new PHPUnit_Framework_MockObject_Stub_ReturnCallback($callback);
+ }
+
+ /**
+ * Returns the current object.
+ *
+ * This method is useful when mocking a fluent interface.
+ *
+ * @return PHPUnit_Framework_MockObject_Stub_ReturnSelf
+ */
+ public static function returnSelf()
+ {
+ return new PHPUnit_Framework_MockObject_Stub_ReturnSelf();
+ }
+
+ /**
+ * @param Throwable|Exception $exception
+ *
+ * @return PHPUnit_Framework_MockObject_Stub_Exception
+ *
+ * @todo Add type declaration when support for PHP 5 is dropped
+ */
+ public static function throwException($exception)
+ {
+ return new PHPUnit_Framework_MockObject_Stub_Exception($exception);
+ }
+
+ /**
+ * @param mixed $value, ...
+ *
+ * @return PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls
+ */
+ public static function onConsecutiveCalls()
+ {
+ $args = func_get_args();
+
+ return new PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls($args);
+ }
+
+ /**
+ * @return bool
+ */
+ public function usesDataProvider()
+ {
+ return !empty($this->data);
+ }
+
+ /**
+ * @return string
+ */
+ public function dataDescription()
+ {
+ return is_string($this->dataName) ? $this->dataName : '';
+ }
+
+ /**
+ * Gets the data set description of a TestCase.
+ *
+ * @param bool $includeData
+ *
+ * @return string
+ */
+ protected function getDataSetAsString($includeData = true)
+ {
+ $buffer = '';
+
+ if (!empty($this->data)) {
+ if (is_int($this->dataName)) {
+ $buffer .= sprintf(' with data set #%d', $this->dataName);
+ } else {
+ $buffer .= sprintf(' with data set "%s"', $this->dataName);
+ }
+
+ $exporter = new Exporter;
+
+ if ($includeData) {
+ $buffer .= sprintf(' (%s)', $exporter->shortenedRecursiveExport($this->data));
+ }
+ }
+
+ return $buffer;
+ }
+
+ /**
+ * Gets the data set of a TestCase.
+ *
+ * @return array
+ */
+ protected function getProvidedData()
+ {
+ return $this->data;
+ }
+
+ /**
+ * Creates a default TestResult object.
+ *
+ * @return PHPUnit_Framework_TestResult
+ */
+ protected function createResult()
+ {
+ return new PHPUnit_Framework_TestResult;
+ }
+
+ protected function handleDependencies()
+ {
+ if (!empty($this->dependencies) && !$this->inIsolation) {
+ $className = get_class($this);
+ $passed = $this->result->passed();
+ $passedKeys = array_keys($passed);
+ $numKeys = count($passedKeys);
+
+ for ($i = 0; $i < $numKeys; $i++) {
+ $pos = strpos($passedKeys[$i], ' with data set');
+
+ if ($pos !== false) {
+ $passedKeys[$i] = substr($passedKeys[$i], 0, $pos);
+ }
+ }
+
+ $passedKeys = array_flip(array_unique($passedKeys));
+
+ foreach ($this->dependencies as $dependency) {
+ $clone = false;
+
+ if (strpos($dependency, 'clone ') === 0) {
+ $clone = true;
+ $dependency = substr($dependency, strlen('clone '));
+ } elseif (strpos($dependency, '!clone ') === 0) {
+ $clone = false;
+ $dependency = substr($dependency, strlen('!clone '));
+ }
+
+ if (strpos($dependency, '::') === false) {
+ $dependency = $className . '::' . $dependency;
+ }
+
+ if (!isset($passedKeys[$dependency])) {
+ $this->result->startTest($this);
+ $this->result->addError(
+ $this,
+ new PHPUnit_Framework_SkippedTestError(
+ sprintf(
+ 'This test depends on "%s" to pass.',
+ $dependency
+ )
+ ),
+ 0
+ );
+ $this->result->endTest($this, 0);
+
+ return false;
+ }
+
+ if (isset($passed[$dependency])) {
+ if ($passed[$dependency]['size'] != PHPUnit_Util_Test::UNKNOWN &&
+ $this->getSize() != PHPUnit_Util_Test::UNKNOWN &&
+ $passed[$dependency]['size'] > $this->getSize()) {
+ $this->result->addError(
+ $this,
+ new PHPUnit_Framework_SkippedTestError(
+ 'This test depends on a test that is larger than itself.'
+ ),
+ 0
+ );
+
+ return false;
+ }
+
+ if ($clone) {
+ $deepCopy = new DeepCopy;
+ $deepCopy->skipUncloneable(false);
+
+ $this->dependencyInput[$dependency] = $deepCopy->copy($passed[$dependency]['result']);
+ } else {
+ $this->dependencyInput[$dependency] = $passed[$dependency]['result'];
+ }
+ } else {
+ $this->dependencyInput[$dependency] = null;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * This method is called before the first test of this test class is run.
+ */
+ public static function setUpBeforeClass()
+ {
+ }
+
+ /**
+ * Sets up the fixture, for example, open a network connection.
+ * This method is called before a test is executed.
+ */
+ protected function setUp()
+ {
+ }
+
+ /**
+ * Performs assertions shared by all tests of a test case.
+ *
+ * This method is called before the execution of a test starts
+ * and after setUp() is called.
+ */
+ protected function assertPreConditions()
+ {
+ }
+
+ /**
+ * Performs assertions shared by all tests of a test case.
+ *
+ * This method is called after the execution of a test ends
+ * and before tearDown() is called.
+ */
+ protected function assertPostConditions()
+ {
+ }
+
+ /**
+ * Tears down the fixture, for example, close a network connection.
+ * This method is called after a test is executed.
+ */
+ protected function tearDown()
+ {
+ }
+
+ /**
+ * This method is called after the last test of this test class is run.
+ */
+ public static function tearDownAfterClass()
+ {
+ }
+
+ /**
+ * This method is called when a test method did not execute successfully.
+ *
+ * @param Exception|Throwable $e
+ *
+ * @throws Exception|Throwable
+ */
+ protected function onNotSuccessfulTest($e)
+ {
+ $expected = PHP_MAJOR_VERSION >= 7 ? 'Throwable' : 'Exception';
+
+ if ($e instanceof $expected) {
+ throw $e;
+ }
+
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 1,
+ 'Throwable or Exception'
+ );
+ }
+
+ /**
+ * Performs custom preparations on the process isolation template.
+ *
+ * @param Text_Template $template
+ */
+ protected function prepareTemplate(Text_Template $template)
+ {
+ }
+
+ /**
+ * Get the mock object generator, creating it if it doesn't exist.
+ *
+ * @return PHPUnit_Framework_MockObject_Generator
+ */
+ protected function getMockObjectGenerator()
+ {
+ if (null === $this->mockObjectGenerator) {
+ $this->mockObjectGenerator = new PHPUnit_Framework_MockObject_Generator;
+ }
+
+ return $this->mockObjectGenerator;
+ }
+
+ private function startOutputBuffering()
+ {
+ ob_start();
+
+ $this->outputBufferingActive = true;
+ $this->outputBufferingLevel = ob_get_level();
+ }
+
+ private function stopOutputBuffering()
+ {
+ if (ob_get_level() != $this->outputBufferingLevel) {
+ while (ob_get_level() >= $this->outputBufferingLevel) {
+ ob_end_clean();
+ }
+
+ throw new PHPUnit_Framework_RiskyTestError(
+ 'Test code or tested code did not (only) close its own output buffers'
+ );
+ }
+
+ $output = ob_get_contents();
+
+ if ($this->outputCallback === false) {
+ $this->output = $output;
+ } else {
+ $this->output = call_user_func_array(
+ $this->outputCallback,
+ [$output]
+ );
+ }
+
+ ob_end_clean();
+
+ $this->outputBufferingActive = false;
+ $this->outputBufferingLevel = ob_get_level();
+ }
+
+ private function snapshotGlobalState()
+ {
+ $backupGlobals = $this->backupGlobals === null || $this->backupGlobals === true;
+
+ if ($this->runTestInSeparateProcess ||
+ $this->inIsolation ||
+ (!$backupGlobals && !$this->backupStaticAttributes)) {
+ return;
+ }
+
+ $this->snapshot = $this->createGlobalStateSnapshot($backupGlobals);
+ }
+
+ private function restoreGlobalState()
+ {
+ if (!$this->snapshot instanceof Snapshot) {
+ return;
+ }
+
+ $backupGlobals = $this->backupGlobals === null || $this->backupGlobals === true;
+
+ if ($this->beStrictAboutChangesToGlobalState) {
+ try {
+ $this->compareGlobalStateSnapshots(
+ $this->snapshot,
+ $this->createGlobalStateSnapshot($backupGlobals)
+ );
+ } catch (PHPUnit_Framework_RiskyTestError $rte) {
+ // Intentionally left empty
+ }
+ }
+
+ $restorer = new Restorer;
+
+ if ($backupGlobals) {
+ $restorer->restoreGlobalVariables($this->snapshot);
+ }
+
+ if ($this->backupStaticAttributes) {
+ $restorer->restoreStaticAttributes($this->snapshot);
+ }
+
+ $this->snapshot = null;
+
+ if (isset($rte)) {
+ throw $rte;
+ }
+ }
+
+ /**
+ * @param bool $backupGlobals
+ *
+ * @return Snapshot
+ */
+ private function createGlobalStateSnapshot($backupGlobals)
+ {
+ $blacklist = new Blacklist;
+
+ foreach ($this->backupGlobalsBlacklist as $globalVariable) {
+ $blacklist->addGlobalVariable($globalVariable);
+ }
+
+ if (!defined('PHPUNIT_TESTSUITE')) {
+ $blacklist->addClassNamePrefix('PHPUnit');
+ $blacklist->addClassNamePrefix('File_Iterator');
+ $blacklist->addClassNamePrefix('SebastianBergmann\CodeCoverage');
+ $blacklist->addClassNamePrefix('PHP_Invoker');
+ $blacklist->addClassNamePrefix('PHP_Timer');
+ $blacklist->addClassNamePrefix('PHP_Token');
+ $blacklist->addClassNamePrefix('Symfony');
+ $blacklist->addClassNamePrefix('Text_Template');
+ $blacklist->addClassNamePrefix('Doctrine\Instantiator');
+ $blacklist->addClassNamePrefix('Prophecy');
+
+ foreach ($this->backupStaticAttributesBlacklist as $class => $attributes) {
+ foreach ($attributes as $attribute) {
+ $blacklist->addStaticAttribute($class, $attribute);
+ }
+ }
+ }
+
+ return new Snapshot(
+ $blacklist,
+ $backupGlobals,
+ (bool) $this->backupStaticAttributes,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false
+ );
+ }
+
+ /**
+ * @param Snapshot $before
+ * @param Snapshot $after
+ *
+ * @throws PHPUnit_Framework_RiskyTestError
+ */
+ private function compareGlobalStateSnapshots(Snapshot $before, Snapshot $after)
+ {
+ $backupGlobals = $this->backupGlobals === null || $this->backupGlobals === true;
+
+ if ($backupGlobals) {
+ $this->compareGlobalStateSnapshotPart(
+ $before->globalVariables(),
+ $after->globalVariables(),
+ "--- Global variables before the test\n+++ Global variables after the test\n"
+ );
+
+ $this->compareGlobalStateSnapshotPart(
+ $before->superGlobalVariables(),
+ $after->superGlobalVariables(),
+ "--- Super-global variables before the test\n+++ Super-global variables after the test\n"
+ );
+ }
+
+ if ($this->backupStaticAttributes) {
+ $this->compareGlobalStateSnapshotPart(
+ $before->staticAttributes(),
+ $after->staticAttributes(),
+ "--- Static attributes before the test\n+++ Static attributes after the test\n"
+ );
+ }
+ }
+
+ /**
+ * @param array $before
+ * @param array $after
+ * @param string $header
+ *
+ * @throws PHPUnit_Framework_RiskyTestError
+ */
+ private function compareGlobalStateSnapshotPart(array $before, array $after, $header)
+ {
+ if ($before != $after) {
+ $differ = new Differ($header);
+ $exporter = new Exporter;
+
+ $diff = $differ->diff(
+ $exporter->export($before),
+ $exporter->export($after)
+ );
+
+ throw new PHPUnit_Framework_RiskyTestError(
+ $diff
+ );
+ }
+ }
+
+ /**
+ * @return Prophecy\Prophet
+ */
+ private function getProphet()
+ {
+ if ($this->prophet === null) {
+ $this->prophet = new Prophet;
+ }
+
+ return $this->prophet;
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_MockObject $mock
+ *
+ * @return bool
+ */
+ private function shouldInvocationMockerBeReset(PHPUnit_Framework_MockObject_MockObject $mock)
+ {
+ $enumerator = new Enumerator;
+
+ foreach ($enumerator->enumerate($this->dependencyInput) as $object) {
+ if ($mock === $object) {
+ return false;
+ }
+ }
+
+ if (!is_array($this->testResult) && !is_object($this->testResult)) {
+ return true;
+ }
+
+ foreach ($enumerator->enumerate($this->testResult) as $object) {
+ if ($mock === $object) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * @param array $testArguments
+ * @param array $originalTestArguments
+ */
+ private function registerMockObjectsFromTestArguments(array $testArguments, array &$visited = [])
+ {
+ if ($this->registerMockObjectsFromTestArgumentsRecursively) {
+ $enumerator = new Enumerator;
+
+ foreach ($enumerator->enumerate($testArguments) as $object) {
+ if ($object instanceof PHPUnit_Framework_MockObject_MockObject) {
+ $this->registerMockObject($object);
+ }
+ }
+ } else {
+ foreach ($testArguments as $testArgument) {
+ if ($testArgument instanceof PHPUnit_Framework_MockObject_MockObject) {
+ if ($this->isCloneable($testArgument)) {
+ $testArgument = clone $testArgument;
+ }
+
+ $this->registerMockObject($testArgument);
+ } elseif (is_array($testArgument) && !in_array($testArgument, $visited, true)) {
+ $visited[] = $testArgument;
+
+ $this->registerMockObjectsFromTestArguments(
+ $testArgument,
+ $visited
+ );
+ }
+ }
+ }
+ }
+
+ private function setDoesNotPerformAssertionsFromAnnotation()
+ {
+ $annotations = $this->getAnnotations();
+
+ if (isset($annotations['method']['doesNotPerformAssertions'])) {
+ $this->doesNotPerformAssertions = true;
+ }
+ }
+
+ /**
+ * @param PHPUnit_Framework_MockObject_MockObject $testArgument
+ *
+ * @return bool
+ */
+ private function isCloneable(PHPUnit_Framework_MockObject_MockObject $testArgument)
+ {
+ $reflector = new ReflectionObject($testArgument);
+
+ if (!$reflector->isCloneable()) {
+ return false;
+ }
+
+ if ($reflector->hasMethod('__clone') &&
+ $reflector->getMethod('__clone')->isPublic()) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/TestFailure.php b/vendor/phpunit/phpunit/src/Framework/TestFailure.php
new file mode 100644
index 0000000..a53e7e5
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/TestFailure.php
@@ -0,0 +1,161 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A TestFailure collects a failed test together with the caught exception.
+ */
+class PHPUnit_Framework_TestFailure
+{
+ /**
+ * @var string
+ */
+ private $testName;
+
+ /**
+ * @var PHPUnit_Framework_Test|null
+ */
+ protected $failedTest;
+
+ /**
+ * @var Exception
+ */
+ protected $thrownException;
+
+ /**
+ * Constructs a TestFailure with the given test and exception.
+ *
+ * @param PHPUnit_Framework_Test $failedTest
+ * @param Throwable $t
+ */
+ public function __construct(PHPUnit_Framework_Test $failedTest, $t)
+ {
+ if ($failedTest instanceof PHPUnit_Framework_SelfDescribing) {
+ $this->testName = $failedTest->toString();
+ } else {
+ $this->testName = get_class($failedTest);
+ }
+
+ if (!$failedTest instanceof PHPUnit_Framework_TestCase || !$failedTest->isInIsolation()) {
+ $this->failedTest = $failedTest;
+ }
+
+ $this->thrownException = $t;
+ }
+
+ /**
+ * Returns a short description of the failure.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return sprintf(
+ '%s: %s',
+ $this->testName,
+ $this->thrownException->getMessage()
+ );
+ }
+
+ /**
+ * Returns a description for the thrown exception.
+ *
+ * @return string
+ */
+ public function getExceptionAsString()
+ {
+ return self::exceptionToString($this->thrownException);
+ }
+
+ /**
+ * Returns a description for an exception.
+ *
+ * @param Exception $e
+ *
+ * @return string
+ */
+ public static function exceptionToString(Exception $e)
+ {
+ if ($e instanceof PHPUnit_Framework_SelfDescribing) {
+ $buffer = $e->toString();
+
+ if ($e instanceof PHPUnit_Framework_ExpectationFailedException && $e->getComparisonFailure()) {
+ $buffer = $buffer . $e->getComparisonFailure()->getDiff();
+ }
+
+ if (!empty($buffer)) {
+ $buffer = trim($buffer) . "\n";
+ }
+ } elseif ($e instanceof PHPUnit_Framework_Error) {
+ $buffer = $e->getMessage() . "\n";
+ } elseif ($e instanceof PHPUnit_Framework_ExceptionWrapper) {
+ $buffer = $e->getClassName() . ': ' . $e->getMessage() . "\n";
+ } else {
+ $buffer = get_class($e) . ': ' . $e->getMessage() . "\n";
+ }
+
+ return $buffer;
+ }
+
+ /**
+ * Returns the name of the failing test (including data set, if any).
+ *
+ * @return string
+ */
+ public function getTestName()
+ {
+ return $this->testName;
+ }
+
+ /**
+ * Returns the failing test.
+ *
+ * Note: The test object is not set when the test is executed in process
+ * isolation.
+ *
+ * @see PHPUnit_Framework_Exception
+ *
+ * @return PHPUnit_Framework_Test|null
+ */
+ public function failedTest()
+ {
+ return $this->failedTest;
+ }
+
+ /**
+ * Gets the thrown exception.
+ *
+ * @return Exception
+ */
+ public function thrownException()
+ {
+ return $this->thrownException;
+ }
+
+ /**
+ * Returns the exception's message.
+ *
+ * @return string
+ */
+ public function exceptionMessage()
+ {
+ return $this->thrownException()->getMessage();
+ }
+
+ /**
+ * Returns true if the thrown exception
+ * is of type AssertionFailedError.
+ *
+ * @return bool
+ */
+ public function isFailure()
+ {
+ return ($this->thrownException() instanceof PHPUnit_Framework_AssertionFailedError);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/TestListener.php b/vendor/phpunit/phpunit/src/Framework/TestListener.php
new file mode 100644
index 0000000..1f46d22
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/TestListener.php
@@ -0,0 +1,102 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A Listener for test progress.
+ */
+interface PHPUnit_Framework_TestListener
+{
+ /**
+ * An error occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addError(PHPUnit_Framework_Test $test, Exception $e, $time);
+
+ /**
+ * A warning occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_Warning $e
+ * @param float $time
+ *
+ * @todo Uncomment in time for PHPUnit 6.0.0
+ *
+ * @see https://github.com/sebastianbergmann/phpunit/pull/1840#issuecomment-162535997
+ */
+// public function addWarning(PHPUnit_Framework_Test $test, PHPUnit_Framework_Warning $e, $time);
+
+ /**
+ * A failure occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_AssertionFailedError $e
+ * @param float $time
+ */
+ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time);
+
+ /**
+ * Incomplete test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time);
+
+ /**
+ * Risky test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time);
+
+ /**
+ * Skipped test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time);
+
+ /**
+ * A test suite started.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function startTestSuite(PHPUnit_Framework_TestSuite $suite);
+
+ /**
+ * A test suite ended.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function endTestSuite(PHPUnit_Framework_TestSuite $suite);
+
+ /**
+ * A test started.
+ *
+ * @param PHPUnit_Framework_Test $test
+ */
+ public function startTest(PHPUnit_Framework_Test $test);
+
+ /**
+ * A test ended.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param float $time
+ */
+ public function endTest(PHPUnit_Framework_Test $test, $time);
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/TestResult.php b/vendor/phpunit/phpunit/src/Framework/TestResult.php
new file mode 100644
index 0000000..057973c
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/TestResult.php
@@ -0,0 +1,1310 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use SebastianBergmann\CodeCoverage\CodeCoverage;
+use SebastianBergmann\CodeCoverage\Exception as CodeCoverageException;
+use SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException;
+use SebastianBergmann\CodeCoverage\MissingCoversAnnotationException;
+use SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException;
+use SebastianBergmann\ResourceOperations\ResourceOperations;
+
+/**
+ * A TestResult collects the results of executing a test case.
+ */
+class PHPUnit_Framework_TestResult implements Countable
+{
+ /**
+ * @var array
+ */
+ protected $passed = [];
+
+ /**
+ * @var array
+ */
+ protected $errors = [];
+
+ /**
+ * @var array
+ */
+ protected $failures = [];
+
+ /**
+ * @var array
+ */
+ protected $warnings = [];
+
+ /**
+ * @var array
+ */
+ protected $notImplemented = [];
+
+ /**
+ * @var array
+ */
+ protected $risky = [];
+
+ /**
+ * @var array
+ */
+ protected $skipped = [];
+
+ /**
+ * @var array
+ */
+ protected $listeners = [];
+
+ /**
+ * @var int
+ */
+ protected $runTests = 0;
+
+ /**
+ * @var float
+ */
+ protected $time = 0;
+
+ /**
+ * @var PHPUnit_Framework_TestSuite
+ */
+ protected $topTestSuite = null;
+
+ /**
+ * Code Coverage information.
+ *
+ * @var CodeCoverage
+ */
+ protected $codeCoverage;
+
+ /**
+ * @var bool
+ */
+ protected $convertErrorsToExceptions = true;
+
+ /**
+ * @var bool
+ */
+ protected $stop = false;
+
+ /**
+ * @var bool
+ */
+ protected $stopOnError = false;
+
+ /**
+ * @var bool
+ */
+ protected $stopOnFailure = false;
+
+ /**
+ * @var bool
+ */
+ protected $stopOnWarning = false;
+
+ /**
+ * @var bool
+ */
+ protected $beStrictAboutTestsThatDoNotTestAnything = false;
+
+ /**
+ * @var bool
+ */
+ protected $beStrictAboutOutputDuringTests = false;
+
+ /**
+ * @var bool
+ */
+ protected $beStrictAboutTodoAnnotatedTests = false;
+
+ /**
+ * @var bool
+ */
+ protected $beStrictAboutResourceUsageDuringSmallTests = false;
+
+ /**
+ * @var bool
+ */
+ protected $enforceTimeLimit = false;
+
+ /**
+ * @var int
+ */
+ protected $timeoutForSmallTests = 1;
+
+ /**
+ * @var int
+ */
+ protected $timeoutForMediumTests = 10;
+
+ /**
+ * @var int
+ */
+ protected $timeoutForLargeTests = 60;
+
+ /**
+ * @var bool
+ */
+ protected $stopOnRisky = false;
+
+ /**
+ * @var bool
+ */
+ protected $stopOnIncomplete = false;
+
+ /**
+ * @var bool
+ */
+ protected $stopOnSkipped = false;
+
+ /**
+ * @var bool
+ */
+ protected $lastTestFailed = false;
+
+ /**
+ * @var bool
+ */
+ private $registerMockObjectsFromTestArgumentsRecursively = false;
+
+ /**
+ * Registers a TestListener.
+ *
+ * @param PHPUnit_Framework_TestListener
+ */
+ public function addListener(PHPUnit_Framework_TestListener $listener)
+ {
+ $this->listeners[] = $listener;
+ }
+
+ /**
+ * Unregisters a TestListener.
+ *
+ * @param PHPUnit_Framework_TestListener $listener
+ */
+ public function removeListener(PHPUnit_Framework_TestListener $listener)
+ {
+ foreach ($this->listeners as $key => $_listener) {
+ if ($listener === $_listener) {
+ unset($this->listeners[$key]);
+ }
+ }
+ }
+
+ /**
+ * Flushes all flushable TestListeners.
+ */
+ public function flushListeners()
+ {
+ foreach ($this->listeners as $listener) {
+ if ($listener instanceof PHPUnit_Util_Printer) {
+ $listener->flush();
+ }
+ }
+ }
+
+ /**
+ * Adds an error to the list of errors.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Throwable $t
+ * @param float $time
+ */
+ public function addError(PHPUnit_Framework_Test $test, $t, $time)
+ {
+ if ($t instanceof PHPUnit_Framework_RiskyTest) {
+ $this->risky[] = new PHPUnit_Framework_TestFailure($test, $t);
+ $notifyMethod = 'addRiskyTest';
+
+ if ($test instanceof PHPUnit_Framework_TestCase) {
+ $test->markAsRisky();
+ }
+
+ if ($this->stopOnRisky) {
+ $this->stop();
+ }
+ } elseif ($t instanceof PHPUnit_Framework_IncompleteTest) {
+ $this->notImplemented[] = new PHPUnit_Framework_TestFailure($test, $t);
+ $notifyMethod = 'addIncompleteTest';
+
+ if ($this->stopOnIncomplete) {
+ $this->stop();
+ }
+ } elseif ($t instanceof PHPUnit_Framework_SkippedTest) {
+ $this->skipped[] = new PHPUnit_Framework_TestFailure($test, $t);
+ $notifyMethod = 'addSkippedTest';
+
+ if ($this->stopOnSkipped) {
+ $this->stop();
+ }
+ } else {
+ $this->errors[] = new PHPUnit_Framework_TestFailure($test, $t);
+ $notifyMethod = 'addError';
+
+ if ($this->stopOnError || $this->stopOnFailure) {
+ $this->stop();
+ }
+ }
+
+ // @see https://github.com/sebastianbergmann/phpunit/issues/1953
+ if ($t instanceof Error) {
+ $t = new PHPUnit_Framework_ExceptionWrapper($t);
+ }
+
+ foreach ($this->listeners as $listener) {
+ $listener->$notifyMethod($test, $t, $time);
+ }
+
+ $this->lastTestFailed = true;
+ $this->time += $time;
+ }
+
+ /**
+ * Adds a warning to the list of warnings.
+ * The passed in exception caused the warning.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_Warning $e
+ * @param float $time
+ */
+ public function addWarning(PHPUnit_Framework_Test $test, PHPUnit_Framework_Warning $e, $time)
+ {
+ if ($this->stopOnWarning) {
+ $this->stop();
+ }
+
+ $this->warnings[] = new PHPUnit_Framework_TestFailure($test, $e);
+
+ foreach ($this->listeners as $listener) {
+ // @todo Remove check for PHPUnit 6.0.0
+ // @see https://github.com/sebastianbergmann/phpunit/pull/1840#issuecomment-162535997
+ if (method_exists($listener, 'addWarning')) {
+ $listener->addWarning($test, $e, $time);
+ }
+ }
+
+ $this->time += $time;
+ }
+
+ /**
+ * Adds a failure to the list of failures.
+ * The passed in exception caused the failure.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_AssertionFailedError $e
+ * @param float $time
+ */
+ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
+ {
+ if ($e instanceof PHPUnit_Framework_RiskyTest ||
+ $e instanceof PHPUnit_Framework_OutputError) {
+ $this->risky[] = new PHPUnit_Framework_TestFailure($test, $e);
+ $notifyMethod = 'addRiskyTest';
+
+ if ($test instanceof PHPUnit_Framework_TestCase) {
+ $test->markAsRisky();
+ }
+
+ if ($this->stopOnRisky) {
+ $this->stop();
+ }
+ } elseif ($e instanceof PHPUnit_Framework_IncompleteTest) {
+ $this->notImplemented[] = new PHPUnit_Framework_TestFailure($test, $e);
+ $notifyMethod = 'addIncompleteTest';
+
+ if ($this->stopOnIncomplete) {
+ $this->stop();
+ }
+ } elseif ($e instanceof PHPUnit_Framework_SkippedTest) {
+ $this->skipped[] = new PHPUnit_Framework_TestFailure($test, $e);
+ $notifyMethod = 'addSkippedTest';
+
+ if ($this->stopOnSkipped) {
+ $this->stop();
+ }
+ } else {
+ $this->failures[] = new PHPUnit_Framework_TestFailure($test, $e);
+ $notifyMethod = 'addFailure';
+
+ if ($this->stopOnFailure) {
+ $this->stop();
+ }
+ }
+
+ foreach ($this->listeners as $listener) {
+ $listener->$notifyMethod($test, $e, $time);
+ }
+
+ $this->lastTestFailed = true;
+ $this->time += $time;
+ }
+
+ /**
+ * Informs the result that a testsuite will be started.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ if ($this->topTestSuite === null) {
+ $this->topTestSuite = $suite;
+ }
+
+ foreach ($this->listeners as $listener) {
+ $listener->startTestSuite($suite);
+ }
+ }
+
+ /**
+ * Informs the result that a testsuite was completed.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ foreach ($this->listeners as $listener) {
+ $listener->endTestSuite($suite);
+ }
+ }
+
+ /**
+ * Informs the result that a test will be started.
+ *
+ * @param PHPUnit_Framework_Test $test
+ */
+ public function startTest(PHPUnit_Framework_Test $test)
+ {
+ $this->lastTestFailed = false;
+ $this->runTests += count($test);
+
+ foreach ($this->listeners as $listener) {
+ $listener->startTest($test);
+ }
+ }
+
+ /**
+ * Informs the result that a test was completed.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param float $time
+ */
+ public function endTest(PHPUnit_Framework_Test $test, $time)
+ {
+ foreach ($this->listeners as $listener) {
+ $listener->endTest($test, $time);
+ }
+
+ if (!$this->lastTestFailed && $test instanceof PHPUnit_Framework_TestCase) {
+ $class = get_class($test);
+ $key = $class . '::' . $test->getName();
+
+ $this->passed[$key] = [
+ 'result' => $test->getResult(),
+ 'size' => PHPUnit_Util_Test::getSize(
+ $class,
+ $test->getName(false)
+ )
+ ];
+
+ $this->time += $time;
+ }
+ }
+
+ /**
+ * Returns true if no risky test occurred.
+ *
+ * @return bool
+ */
+ public function allHarmless()
+ {
+ return $this->riskyCount() == 0;
+ }
+
+ /**
+ * Gets the number of risky tests.
+ *
+ * @return int
+ */
+ public function riskyCount()
+ {
+ return count($this->risky);
+ }
+
+ /**
+ * Returns true if no incomplete test occurred.
+ *
+ * @return bool
+ */
+ public function allCompletelyImplemented()
+ {
+ return $this->notImplementedCount() == 0;
+ }
+
+ /**
+ * Gets the number of incomplete tests.
+ *
+ * @return int
+ */
+ public function notImplementedCount()
+ {
+ return count($this->notImplemented);
+ }
+
+ /**
+ * Returns an Enumeration for the risky tests.
+ *
+ * @return array
+ */
+ public function risky()
+ {
+ return $this->risky;
+ }
+
+ /**
+ * Returns an Enumeration for the incomplete tests.
+ *
+ * @return array
+ */
+ public function notImplemented()
+ {
+ return $this->notImplemented;
+ }
+
+ /**
+ * Returns true if no test has been skipped.
+ *
+ * @return bool
+ */
+ public function noneSkipped()
+ {
+ return $this->skippedCount() == 0;
+ }
+
+ /**
+ * Gets the number of skipped tests.
+ *
+ * @return int
+ */
+ public function skippedCount()
+ {
+ return count($this->skipped);
+ }
+
+ /**
+ * Returns an Enumeration for the skipped tests.
+ *
+ * @return array
+ */
+ public function skipped()
+ {
+ return $this->skipped;
+ }
+
+ /**
+ * Gets the number of detected errors.
+ *
+ * @return int
+ */
+ public function errorCount()
+ {
+ return count($this->errors);
+ }
+
+ /**
+ * Returns an Enumeration for the errors.
+ *
+ * @return array
+ */
+ public function errors()
+ {
+ return $this->errors;
+ }
+
+ /**
+ * Gets the number of detected failures.
+ *
+ * @return int
+ */
+ public function failureCount()
+ {
+ return count($this->failures);
+ }
+
+ /**
+ * Returns an Enumeration for the failures.
+ *
+ * @return array
+ */
+ public function failures()
+ {
+ return $this->failures;
+ }
+
+ /**
+ * Gets the number of detected warnings.
+ *
+ * @return int
+ */
+ public function warningCount()
+ {
+ return count($this->warnings);
+ }
+
+ /**
+ * Returns an Enumeration for the warnings.
+ *
+ * @return array
+ */
+ public function warnings()
+ {
+ return $this->warnings;
+ }
+
+ /**
+ * Returns the names of the tests that have passed.
+ *
+ * @return array
+ */
+ public function passed()
+ {
+ return $this->passed;
+ }
+
+ /**
+ * Returns the (top) test suite.
+ *
+ * @return PHPUnit_Framework_TestSuite
+ */
+ public function topTestSuite()
+ {
+ return $this->topTestSuite;
+ }
+
+ /**
+ * Returns whether code coverage information should be collected.
+ *
+ * @return bool If code coverage should be collected
+ */
+ public function getCollectCodeCoverageInformation()
+ {
+ return $this->codeCoverage !== null;
+ }
+
+ /**
+ * Runs a TestCase.
+ *
+ * @param PHPUnit_Framework_Test $test
+ */
+ public function run(PHPUnit_Framework_Test $test)
+ {
+ PHPUnit_Framework_Assert::resetCount();
+
+ $coversNothing = false;
+
+ if ($test instanceof PHPUnit_Framework_TestCase) {
+ $test->setRegisterMockObjectsFromTestArgumentsRecursively(
+ $this->registerMockObjectsFromTestArgumentsRecursively
+ );
+
+ $annotations = $test->getAnnotations();
+
+ if (isset($annotations['class']['coversNothing']) || isset($annotations['method']['coversNothing'])) {
+ $coversNothing = true;
+ }
+ }
+
+ $error = false;
+ $failure = false;
+ $warning = false;
+ $incomplete = false;
+ $risky = false;
+ $skipped = false;
+
+ $this->startTest($test);
+
+ $errorHandlerSet = false;
+
+ if ($this->convertErrorsToExceptions) {
+ $oldErrorHandler = set_error_handler(
+ ['PHPUnit_Util_ErrorHandler', 'handleError'],
+ E_ALL | E_STRICT
+ );
+
+ if ($oldErrorHandler === null) {
+ $errorHandlerSet = true;
+ } else {
+ restore_error_handler();
+ }
+ }
+
+ $collectCodeCoverage = $this->codeCoverage !== null &&
+ !$test instanceof PHPUnit_Framework_WarningTestCase &&
+ !$coversNothing;
+
+ if ($collectCodeCoverage) {
+ $this->codeCoverage->start($test);
+ }
+
+ $monitorFunctions = $this->beStrictAboutResourceUsageDuringSmallTests &&
+ !$test instanceof PHPUnit_Framework_WarningTestCase &&
+ $test->getSize() == PHPUnit_Util_Test::SMALL &&
+ function_exists('xdebug_start_function_monitor');
+
+ if ($monitorFunctions) {
+ xdebug_start_function_monitor(ResourceOperations::getFunctions());
+ }
+
+ PHP_Timer::start();
+
+ try {
+ if (!$test instanceof PHPUnit_Framework_WarningTestCase &&
+ $test->getSize() != PHPUnit_Util_Test::UNKNOWN &&
+ $this->enforceTimeLimit &&
+ extension_loaded('pcntl') && class_exists('PHP_Invoker')) {
+ switch ($test->getSize()) {
+ case PHPUnit_Util_Test::SMALL:
+ $_timeout = $this->timeoutForSmallTests;
+ break;
+
+ case PHPUnit_Util_Test::MEDIUM:
+ $_timeout = $this->timeoutForMediumTests;
+ break;
+
+ case PHPUnit_Util_Test::LARGE:
+ $_timeout = $this->timeoutForLargeTests;
+ break;
+ }
+
+ $invoker = new PHP_Invoker;
+ $invoker->invoke([$test, 'runBare'], [], $_timeout);
+ } else {
+ $test->runBare();
+ }
+ } catch (PHP_Invoker_TimeoutException $e) {
+ $this->addFailure(
+ $test,
+ new PHPUnit_Framework_RiskyTestError(
+ $e->getMessage()
+ ),
+ $_timeout
+ );
+
+ $risky = true;
+ } catch (PHPUnit_Framework_MockObject_Exception $e) {
+ $e = new PHPUnit_Framework_Warning(
+ $e->getMessage()
+ );
+
+ $warning = true;
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ $failure = true;
+
+ if ($e instanceof PHPUnit_Framework_RiskyTestError) {
+ $risky = true;
+ } elseif ($e instanceof PHPUnit_Framework_IncompleteTestError) {
+ $incomplete = true;
+ } elseif ($e instanceof PHPUnit_Framework_SkippedTestError) {
+ $skipped = true;
+ }
+ } catch (PHPUnit_Framework_Warning $e) {
+ $warning = true;
+ } catch (PHPUnit_Framework_Exception $e) {
+ $error = true;
+ } catch (Throwable $e) {
+ // @see https://github.com/sebastianbergmann/phpunit/issues/2394
+ if (PHP_MAJOR_VERSION === 7 && $e instanceof \AssertionError) {
+ $test->addToAssertionCount(1);
+
+ $failure = true;
+ $frame = $e->getTrace()[0];
+
+ $e = new PHPUnit_Framework_AssertionFailedError(
+ sprintf(
+ '%s in %s:%s',
+ $e->getMessage(),
+ $frame['file'],
+ $frame['line']
+ )
+ );
+ } else {
+ $e = new PHPUnit_Framework_ExceptionWrapper($e);
+ $error = true;
+ }
+ } catch (Exception $e) {
+ $e = new PHPUnit_Framework_ExceptionWrapper($e);
+ $error = true;
+ }
+
+ $time = PHP_Timer::stop();
+ $test->addToAssertionCount(PHPUnit_Framework_Assert::getCount());
+
+ if ($monitorFunctions) {
+ $blacklist = new PHPUnit_Util_Blacklist;
+ $functions = xdebug_get_monitored_functions();
+ xdebug_stop_function_monitor();
+
+ foreach ($functions as $function) {
+ if (!$blacklist->isBlacklisted($function['filename'])) {
+ $this->addFailure(
+ $test,
+ new PHPUnit_Framework_RiskyTestError(
+ sprintf(
+ '%s() used in %s:%s',
+ $function['function'],
+ $function['filename'],
+ $function['lineno']
+ )
+ ),
+ $time
+ );
+ }
+ }
+ }
+
+ if ($this->beStrictAboutTestsThatDoNotTestAnything &&
+ $test->getNumAssertions() == 0) {
+ $risky = true;
+ }
+
+ if ($collectCodeCoverage) {
+ $append = !$risky && !$incomplete && !$skipped;
+ $linesToBeCovered = [];
+ $linesToBeUsed = [];
+
+ if ($append && $test instanceof PHPUnit_Framework_TestCase) {
+ try {
+ $linesToBeCovered = PHPUnit_Util_Test::getLinesToBeCovered(
+ get_class($test),
+ $test->getName(false)
+ );
+
+ $linesToBeUsed = PHPUnit_Util_Test::getLinesToBeUsed(
+ get_class($test),
+ $test->getName(false)
+ );
+ } catch (PHPUnit_Framework_InvalidCoversTargetException $cce) {
+ $this->addWarning(
+ $test,
+ new PHPUnit_Framework_Warning(
+ $cce->getMessage()
+ ),
+ $time
+ );
+ }
+ }
+
+ try {
+ $this->codeCoverage->stop(
+ $append,
+ $linesToBeCovered,
+ $linesToBeUsed
+ );
+ } catch (UnintentionallyCoveredCodeException $cce) {
+ $this->addFailure(
+ $test,
+ new PHPUnit_Framework_UnintentionallyCoveredCodeError(
+ 'This test executed code that is not listed as code to be covered or used:' .
+ PHP_EOL . $cce->getMessage()
+ ),
+ $time
+ );
+ } catch (CoveredCodeNotExecutedException $cce) {
+ $this->addFailure(
+ $test,
+ new PHPUnit_Framework_CoveredCodeNotExecutedException(
+ 'This test did not execute all the code that is listed as code to be covered:' .
+ PHP_EOL . $cce->getMessage()
+ ),
+ $time
+ );
+ } catch (MissingCoversAnnotationException $cce) {
+ if ($linesToBeCovered !== false) {
+ $this->addFailure(
+ $test,
+ new PHPUnit_Framework_MissingCoversAnnotationException(
+ 'This test does not have a @covers annotation but is expected to have one'
+ ),
+ $time
+ );
+ }
+ } catch (CodeCoverageException $cce) {
+ $error = true;
+
+ if (!isset($e)) {
+ $e = $cce;
+ }
+ }
+ }
+
+ if ($errorHandlerSet === true) {
+ restore_error_handler();
+ }
+
+ if ($error === true) {
+ $this->addError($test, $e, $time);
+ } elseif ($failure === true) {
+ $this->addFailure($test, $e, $time);
+ } elseif ($warning === true) {
+ $this->addWarning($test, $e, $time);
+ } elseif ($this->beStrictAboutTestsThatDoNotTestAnything &&
+ !$test->doesNotPerformAssertions() &&
+ $test->getNumAssertions() == 0) {
+ $this->addFailure(
+ $test,
+ new PHPUnit_Framework_RiskyTestError(
+ 'This test did not perform any assertions'
+ ),
+ $time
+ );
+ } elseif ($this->beStrictAboutOutputDuringTests && $test->hasOutput()) {
+ $this->addFailure(
+ $test,
+ new PHPUnit_Framework_OutputError(
+ sprintf(
+ 'This test printed output: %s',
+ $test->getActualOutput()
+ )
+ ),
+ $time
+ );
+ } elseif ($this->beStrictAboutTodoAnnotatedTests && $test instanceof PHPUnit_Framework_TestCase) {
+ $annotations = $test->getAnnotations();
+
+ if (isset($annotations['method']['todo'])) {
+ $this->addFailure(
+ $test,
+ new PHPUnit_Framework_RiskyTestError(
+ 'Test method is annotated with @todo'
+ ),
+ $time
+ );
+ }
+ }
+
+ $this->endTest($test, $time);
+ }
+
+ /**
+ * Gets the number of run tests.
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return $this->runTests;
+ }
+
+ /**
+ * Checks whether the test run should stop.
+ *
+ * @return bool
+ */
+ public function shouldStop()
+ {
+ return $this->stop;
+ }
+
+ /**
+ * Marks that the test run should stop.
+ */
+ public function stop()
+ {
+ $this->stop = true;
+ }
+
+ /**
+ * Returns the code coverage object.
+ *
+ * @return CodeCoverage
+ */
+ public function getCodeCoverage()
+ {
+ return $this->codeCoverage;
+ }
+
+ /**
+ * Sets the code coverage object.
+ *
+ * @param CodeCoverage $codeCoverage
+ */
+ public function setCodeCoverage(CodeCoverage $codeCoverage)
+ {
+ $this->codeCoverage = $codeCoverage;
+ }
+
+ /**
+ * Enables or disables the error-to-exception conversion.
+ *
+ * @param bool $flag
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function convertErrorsToExceptions($flag)
+ {
+ if (!is_bool($flag)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+
+ $this->convertErrorsToExceptions = $flag;
+ }
+
+ /**
+ * Returns the error-to-exception conversion setting.
+ *
+ * @return bool
+ */
+ public function getConvertErrorsToExceptions()
+ {
+ return $this->convertErrorsToExceptions;
+ }
+
+ /**
+ * Enables or disables the stopping when an error occurs.
+ *
+ * @param bool $flag
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function stopOnError($flag)
+ {
+ if (!is_bool($flag)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+
+ $this->stopOnError = $flag;
+ }
+
+ /**
+ * Enables or disables the stopping when a failure occurs.
+ *
+ * @param bool $flag
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function stopOnFailure($flag)
+ {
+ if (!is_bool($flag)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+
+ $this->stopOnFailure = $flag;
+ }
+
+ /**
+ * Enables or disables the stopping when a warning occurs.
+ *
+ * @param bool $flag
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function stopOnWarning($flag)
+ {
+ if (!is_bool($flag)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+
+ $this->stopOnWarning = $flag;
+ }
+
+ /**
+ * @param bool $flag
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function beStrictAboutTestsThatDoNotTestAnything($flag)
+ {
+ if (!is_bool($flag)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+
+ $this->beStrictAboutTestsThatDoNotTestAnything = $flag;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isStrictAboutTestsThatDoNotTestAnything()
+ {
+ return $this->beStrictAboutTestsThatDoNotTestAnything;
+ }
+
+ /**
+ * @param bool $flag
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function beStrictAboutOutputDuringTests($flag)
+ {
+ if (!is_bool($flag)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+
+ $this->beStrictAboutOutputDuringTests = $flag;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isStrictAboutOutputDuringTests()
+ {
+ return $this->beStrictAboutOutputDuringTests;
+ }
+
+ /**
+ * @param bool $flag
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function beStrictAboutResourceUsageDuringSmallTests($flag)
+ {
+ if (!is_bool($flag)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+
+ $this->beStrictAboutResourceUsageDuringSmallTests = $flag;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isStrictAboutResourceUsageDuringSmallTests()
+ {
+ return $this->beStrictAboutResourceUsageDuringSmallTests;
+ }
+
+ /**
+ * @param bool $flag
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function enforceTimeLimit($flag)
+ {
+ if (!is_bool($flag)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+
+ $this->enforceTimeLimit = $flag;
+ }
+
+ /**
+ * @return bool
+ */
+ public function enforcesTimeLimit()
+ {
+ return $this->enforceTimeLimit;
+ }
+
+ /**
+ * @param bool $flag
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function beStrictAboutTodoAnnotatedTests($flag)
+ {
+ if (!is_bool($flag)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+
+ $this->beStrictAboutTodoAnnotatedTests = $flag;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isStrictAboutTodoAnnotatedTests()
+ {
+ return $this->beStrictAboutTodoAnnotatedTests;
+ }
+
+ /**
+ * Enables or disables the stopping for risky tests.
+ *
+ * @param bool $flag
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function stopOnRisky($flag)
+ {
+ if (!is_bool($flag)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+
+ $this->stopOnRisky = $flag;
+ }
+
+ /**
+ * Enables or disables the stopping for incomplete tests.
+ *
+ * @param bool $flag
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function stopOnIncomplete($flag)
+ {
+ if (!is_bool($flag)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+
+ $this->stopOnIncomplete = $flag;
+ }
+
+ /**
+ * Enables or disables the stopping for skipped tests.
+ *
+ * @param bool $flag
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function stopOnSkipped($flag)
+ {
+ if (!is_bool($flag)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+
+ $this->stopOnSkipped = $flag;
+ }
+
+ /**
+ * Returns the time spent running the tests.
+ *
+ * @return float
+ */
+ public function time()
+ {
+ return $this->time;
+ }
+
+ /**
+ * Returns whether the entire test was successful or not.
+ *
+ * @param bool $includeWarnings
+ *
+ * @return bool
+ */
+ public function wasSuccessful($includeWarnings = true)
+ {
+ if ($includeWarnings) {
+ return empty($this->errors) && empty($this->failures) && empty($this->warnings);
+ } else {
+ return empty($this->errors) && empty($this->failures);
+ }
+ }
+
+ /**
+ * Sets the timeout for small tests.
+ *
+ * @param int $timeout
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function setTimeoutForSmallTests($timeout)
+ {
+ if (!is_int($timeout)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
+ }
+
+ $this->timeoutForSmallTests = $timeout;
+ }
+
+ /**
+ * Sets the timeout for medium tests.
+ *
+ * @param int $timeout
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function setTimeoutForMediumTests($timeout)
+ {
+ if (!is_int($timeout)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
+ }
+
+ $this->timeoutForMediumTests = $timeout;
+ }
+
+ /**
+ * Sets the timeout for large tests.
+ *
+ * @param int $timeout
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function setTimeoutForLargeTests($timeout)
+ {
+ if (!is_int($timeout)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
+ }
+
+ $this->timeoutForLargeTests = $timeout;
+ }
+
+ /**
+ * Returns the set timeout for large tests.
+ *
+ * @return int
+ */
+ public function getTimeoutForLargeTests()
+ {
+ return $this->timeoutForLargeTests;
+ }
+
+ /**
+ * @param bool $flag
+ */
+ public function setRegisterMockObjectsFromTestArgumentsRecursively($flag)
+ {
+ if (!is_bool($flag)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+
+ $this->registerMockObjectsFromTestArgumentsRecursively = $flag;
+ }
+
+ /**
+ * Returns the class hierarchy for a given class.
+ *
+ * @param string $className
+ * @param bool $asReflectionObjects
+ *
+ * @return array
+ */
+ protected function getHierarchy($className, $asReflectionObjects = false)
+ {
+ if ($asReflectionObjects) {
+ $classes = [new ReflectionClass($className)];
+ } else {
+ $classes = [$className];
+ }
+
+ $done = false;
+
+ while (!$done) {
+ if ($asReflectionObjects) {
+ $class = new ReflectionClass(
+ $classes[count($classes) - 1]->getName()
+ );
+ } else {
+ $class = new ReflectionClass($classes[count($classes) - 1]);
+ }
+
+ $parent = $class->getParentClass();
+
+ if ($parent !== false) {
+ if ($asReflectionObjects) {
+ $classes[] = $parent;
+ } else {
+ $classes[] = $parent->getName();
+ }
+ } else {
+ $done = true;
+ }
+ }
+
+ return $classes;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/TestSuite.php b/vendor/phpunit/phpunit/src/Framework/TestSuite.php
new file mode 100644
index 0000000..0ed6be4
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/TestSuite.php
@@ -0,0 +1,1000 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A TestSuite is a composite of Tests. It runs a collection of test cases.
+ */
+class PHPUnit_Framework_TestSuite implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing, IteratorAggregate
+{
+ /**
+ * Last count of tests in this suite.
+ *
+ * @var int|null
+ */
+ private $cachedNumTests;
+
+ /**
+ * Enable or disable the backup and restoration of the $GLOBALS array.
+ *
+ * @var bool
+ */
+ protected $backupGlobals = null;
+
+ /**
+ * Enable or disable the backup and restoration of static attributes.
+ *
+ * @var bool
+ */
+ protected $backupStaticAttributes = null;
+
+ /**
+ * @var bool
+ */
+ private $beStrictAboutChangesToGlobalState = null;
+
+ /**
+ * @var bool
+ */
+ protected $runTestInSeparateProcess = false;
+
+ /**
+ * The name of the test suite.
+ *
+ * @var string
+ */
+ protected $name = '';
+
+ /**
+ * The test groups of the test suite.
+ *
+ * @var array
+ */
+ protected $groups = [];
+
+ /**
+ * The tests in the test suite.
+ *
+ * @var array
+ */
+ protected $tests = [];
+
+ /**
+ * The number of tests in the test suite.
+ *
+ * @var int
+ */
+ protected $numTests = -1;
+
+ /**
+ * @var bool
+ */
+ protected $testCase = false;
+
+ /**
+ * @var array
+ */
+ protected $foundClasses = [];
+
+ /**
+ * @var PHPUnit_Runner_Filter_Factory
+ */
+ private $iteratorFilter = null;
+
+ /**
+ * @var string[]
+ */
+ private $declaredClasses;
+
+ /**
+ * Constructs a new TestSuite:
+ *
+ * - PHPUnit_Framework_TestSuite() constructs an empty TestSuite.
+ *
+ * - PHPUnit_Framework_TestSuite(ReflectionClass) constructs a
+ * TestSuite from the given class.
+ *
+ * - PHPUnit_Framework_TestSuite(ReflectionClass, String)
+ * constructs a TestSuite from the given class with the given
+ * name.
+ *
+ * - PHPUnit_Framework_TestSuite(String) either constructs a
+ * TestSuite from the given class (if the passed string is the
+ * name of an existing class) or constructs an empty TestSuite
+ * with the given name.
+ *
+ * @param mixed $theClass
+ * @param string $name
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function __construct($theClass = '', $name = '')
+ {
+ $this->declaredClasses = get_declared_classes();
+
+ $argumentsValid = false;
+
+ if (is_object($theClass) &&
+ $theClass instanceof ReflectionClass) {
+ $argumentsValid = true;
+ } elseif (is_string($theClass) &&
+ $theClass !== '' &&
+ class_exists($theClass, false)) {
+ $argumentsValid = true;
+
+ if ($name == '') {
+ $name = $theClass;
+ }
+
+ $theClass = new ReflectionClass($theClass);
+ } elseif (is_string($theClass)) {
+ $this->setName($theClass);
+
+ return;
+ }
+
+ if (!$argumentsValid) {
+ throw new PHPUnit_Framework_Exception;
+ }
+
+ if (!$theClass->isSubclassOf('PHPUnit_Framework_TestCase')) {
+ throw new PHPUnit_Framework_Exception(
+ 'Class "' . $theClass->name . '" does not extend PHPUnit_Framework_TestCase.'
+ );
+ }
+
+ if ($name != '') {
+ $this->setName($name);
+ } else {
+ $this->setName($theClass->getName());
+ }
+
+ $constructor = $theClass->getConstructor();
+
+ if ($constructor !== null &&
+ !$constructor->isPublic()) {
+ $this->addTest(
+ self::warning(
+ sprintf(
+ 'Class "%s" has no public constructor.',
+ $theClass->getName()
+ )
+ )
+ );
+
+ return;
+ }
+
+ foreach ($theClass->getMethods() as $method) {
+ $this->addTestMethod($theClass, $method);
+ }
+
+ if (empty($this->tests)) {
+ $this->addTest(
+ self::warning(
+ sprintf(
+ 'No tests found in class "%s".',
+ $theClass->getName()
+ )
+ )
+ );
+ }
+
+ $this->testCase = true;
+ }
+
+ /**
+ * Returns a string representation of the test suite.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return $this->getName();
+ }
+
+ /**
+ * Adds a test to the suite.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param array $groups
+ */
+ public function addTest(PHPUnit_Framework_Test $test, $groups = [])
+ {
+ $class = new ReflectionClass($test);
+
+ if (!$class->isAbstract()) {
+ $this->tests[] = $test;
+ $this->numTests = -1;
+
+ if ($test instanceof self &&
+ empty($groups)) {
+ $groups = $test->getGroups();
+ }
+
+ if (empty($groups)) {
+ $groups = ['default'];
+ }
+
+ foreach ($groups as $group) {
+ if (!isset($this->groups[$group])) {
+ $this->groups[$group] = [$test];
+ } else {
+ $this->groups[$group][] = $test;
+ }
+ }
+
+ if ($test instanceof PHPUnit_Framework_TestCase) {
+ $test->setGroups($groups);
+ }
+ }
+ }
+
+ /**
+ * Adds the tests from the given class to the suite.
+ *
+ * @param mixed $testClass
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function addTestSuite($testClass)
+ {
+ if (is_string($testClass) && class_exists($testClass)) {
+ $testClass = new ReflectionClass($testClass);
+ }
+
+ if (!is_object($testClass)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 1,
+ 'class name or object'
+ );
+ }
+
+ if ($testClass instanceof self) {
+ $this->addTest($testClass);
+ } elseif ($testClass instanceof ReflectionClass) {
+ $suiteMethod = false;
+
+ if (!$testClass->isAbstract()) {
+ if ($testClass->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) {
+ $method = $testClass->getMethod(
+ PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME
+ );
+
+ if ($method->isStatic()) {
+ $this->addTest(
+ $method->invoke(null, $testClass->getName())
+ );
+
+ $suiteMethod = true;
+ }
+ }
+ }
+
+ if (!$suiteMethod && !$testClass->isAbstract() && $testClass->isSubclassOf(PHPUnit_Framework_TestCase::class)) {
+ $this->addTest(new self($testClass));
+ }
+ } else {
+ throw new PHPUnit_Framework_Exception;
+ }
+ }
+
+ /**
+ * Wraps both <code>addTest()</code> and <code>addTestSuite</code>
+ * as well as the separate import statements for the user's convenience.
+ *
+ * If the named file cannot be read or there are no new tests that can be
+ * added, a <code>PHPUnit_Framework_WarningTestCase</code> will be created instead,
+ * leaving the current test run untouched.
+ *
+ * @param string $filename
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function addTestFile($filename)
+ {
+ if (!is_string($filename)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
+ }
+
+ if (file_exists($filename) && substr($filename, -5) == '.phpt') {
+ $this->addTest(
+ new PHPUnit_Extensions_PhptTestCase($filename)
+ );
+
+ return;
+ }
+
+ // The given file may contain further stub classes in addition to the
+ // test class itself. Figure out the actual test class.
+ $filename = PHPUnit_Util_Fileloader::checkAndLoad($filename);
+ $newClasses = array_diff(get_declared_classes(), $this->declaredClasses);
+
+ // The diff is empty in case a parent class (with test methods) is added
+ // AFTER a child class that inherited from it. To account for that case,
+ // cumulate all discovered classes, so the parent class may be found in
+ // a later invocation.
+ if (!empty($newClasses)) {
+ // On the assumption that test classes are defined first in files,
+ // process discovered classes in approximate LIFO order, so as to
+ // avoid unnecessary reflection.
+ $this->foundClasses = array_merge($newClasses, $this->foundClasses);
+ $this->declaredClasses = get_declared_classes();
+ }
+
+ // The test class's name must match the filename, either in full, or as
+ // a PEAR/PSR-0 prefixed shortname ('NameSpace_ShortName'), or as a
+ // PSR-1 local shortname ('NameSpace\ShortName'). The comparison must be
+ // anchored to prevent false-positive matches (e.g., 'OtherShortName').
+ $shortname = basename($filename, '.php');
+ $shortnameRegEx = '/(?:^|_|\\\\)' . preg_quote($shortname, '/') . '$/';
+
+ foreach ($this->foundClasses as $i => $className) {
+ if (preg_match($shortnameRegEx, $className)) {
+ $class = new ReflectionClass($className);
+
+ if ($class->getFileName() == $filename) {
+ $newClasses = [$className];
+ unset($this->foundClasses[$i]);
+ break;
+ }
+ }
+ }
+
+ foreach ($newClasses as $className) {
+ if (strpos($className, 'PHPUnit_Framework') === 0) {
+ continue;
+ }
+
+ $class = new ReflectionClass($className);
+
+ if (!$class->isAbstract()) {
+ if ($class->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) {
+ $method = $class->getMethod(
+ PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME
+ );
+
+ if ($method->isStatic()) {
+ $this->addTest($method->invoke(null, $className));
+ }
+ } elseif ($class->implementsInterface('PHPUnit_Framework_Test')) {
+ $this->addTestSuite($class);
+ }
+ }
+ }
+
+ $this->numTests = -1;
+ }
+
+ /**
+ * Wrapper for addTestFile() that adds multiple test files.
+ *
+ * @param array|Iterator $filenames
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function addTestFiles($filenames)
+ {
+ if (!(is_array($filenames) ||
+ (is_object($filenames) && $filenames instanceof Iterator))) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 1,
+ 'array or iterator'
+ );
+ }
+
+ foreach ($filenames as $filename) {
+ $this->addTestFile((string) $filename);
+ }
+ }
+
+ /**
+ * Counts the number of test cases that will be run by this test.
+ *
+ * @param bool $preferCache Indicates if cache is preferred.
+ *
+ * @return int
+ */
+ public function count($preferCache = false)
+ {
+ if ($preferCache && $this->cachedNumTests !== null) {
+ $numTests = $this->cachedNumTests;
+ } else {
+ $numTests = 0;
+
+ foreach ($this as $test) {
+ $numTests += count($test);
+ }
+
+ $this->cachedNumTests = $numTests;
+ }
+
+ return $numTests;
+ }
+
+ /**
+ * @param ReflectionClass $theClass
+ * @param string $name
+ *
+ * @return PHPUnit_Framework_Test
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public static function createTest(ReflectionClass $theClass, $name)
+ {
+ $className = $theClass->getName();
+
+ if (!$theClass->isInstantiable()) {
+ return self::warning(
+ sprintf('Cannot instantiate class "%s".', $className)
+ );
+ }
+
+ $backupSettings = PHPUnit_Util_Test::getBackupSettings(
+ $className,
+ $name
+ );
+
+ $preserveGlobalState = PHPUnit_Util_Test::getPreserveGlobalStateSettings(
+ $className,
+ $name
+ );
+
+ $runTestInSeparateProcess = PHPUnit_Util_Test::getProcessIsolationSettings(
+ $className,
+ $name
+ );
+
+ $constructor = $theClass->getConstructor();
+
+ if ($constructor !== null) {
+ $parameters = $constructor->getParameters();
+
+ // TestCase() or TestCase($name)
+ if (count($parameters) < 2) {
+ $test = new $className;
+ } // TestCase($name, $data)
+ else {
+ try {
+ $data = PHPUnit_Util_Test::getProvidedData(
+ $className,
+ $name
+ );
+ } catch (PHPUnit_Framework_IncompleteTestError $e) {
+ $message = sprintf(
+ 'Test for %s::%s marked incomplete by data provider',
+ $className,
+ $name
+ );
+
+ $_message = $e->getMessage();
+
+ if (!empty($_message)) {
+ $message .= "\n" . $_message;
+ }
+
+ $data = self::incompleteTest($className, $name, $message);
+ } catch (PHPUnit_Framework_SkippedTestError $e) {
+ $message = sprintf(
+ 'Test for %s::%s skipped by data provider',
+ $className,
+ $name
+ );
+
+ $_message = $e->getMessage();
+
+ if (!empty($_message)) {
+ $message .= "\n" . $_message;
+ }
+
+ $data = self::skipTest($className, $name, $message);
+ } catch (Throwable $_t) {
+ $t = $_t;
+ } catch (Exception $_t) {
+ $t = $_t;
+ }
+
+ if (isset($t)) {
+ $message = sprintf(
+ 'The data provider specified for %s::%s is invalid.',
+ $className,
+ $name
+ );
+
+ $_message = $t->getMessage();
+
+ if (!empty($_message)) {
+ $message .= "\n" . $_message;
+ }
+
+ $data = self::warning($message);
+ }
+
+ // Test method with @dataProvider.
+ if (isset($data)) {
+ $test = new PHPUnit_Framework_TestSuite_DataProvider(
+ $className . '::' . $name
+ );
+
+ if (empty($data)) {
+ $data = self::warning(
+ sprintf(
+ 'No tests found in suite "%s".',
+ $test->getName()
+ )
+ );
+ }
+
+ $groups = PHPUnit_Util_Test::getGroups($className, $name);
+
+ if ($data instanceof PHPUnit_Framework_WarningTestCase ||
+ $data instanceof PHPUnit_Framework_SkippedTestCase ||
+ $data instanceof PHPUnit_Framework_IncompleteTestCase) {
+ $test->addTest($data, $groups);
+ } else {
+ foreach ($data as $_dataName => $_data) {
+ $_test = new $className($name, $_data, $_dataName);
+
+ if ($runTestInSeparateProcess) {
+ $_test->setRunTestInSeparateProcess(true);
+
+ if ($preserveGlobalState !== null) {
+ $_test->setPreserveGlobalState($preserveGlobalState);
+ }
+ }
+
+ if ($backupSettings['backupGlobals'] !== null) {
+ $_test->setBackupGlobals(
+ $backupSettings['backupGlobals']
+ );
+ }
+
+ if ($backupSettings['backupStaticAttributes'] !== null) {
+ $_test->setBackupStaticAttributes(
+ $backupSettings['backupStaticAttributes']
+ );
+ }
+
+ $test->addTest($_test, $groups);
+ }
+ }
+ } else {
+ $test = new $className;
+ }
+ }
+ }
+
+ if (!isset($test)) {
+ throw new PHPUnit_Framework_Exception('No valid test provided.');
+ }
+
+ if ($test instanceof PHPUnit_Framework_TestCase) {
+ $test->setName($name);
+
+ if ($runTestInSeparateProcess) {
+ $test->setRunTestInSeparateProcess(true);
+
+ if ($preserveGlobalState !== null) {
+ $test->setPreserveGlobalState($preserveGlobalState);
+ }
+ }
+
+ if ($backupSettings['backupGlobals'] !== null) {
+ $test->setBackupGlobals($backupSettings['backupGlobals']);
+ }
+
+ if ($backupSettings['backupStaticAttributes'] !== null) {
+ $test->setBackupStaticAttributes(
+ $backupSettings['backupStaticAttributes']
+ );
+ }
+ }
+
+ return $test;
+ }
+
+ /**
+ * Creates a default TestResult object.
+ *
+ * @return PHPUnit_Framework_TestResult
+ */
+ protected function createResult()
+ {
+ return new PHPUnit_Framework_TestResult;
+ }
+
+ /**
+ * Returns the name of the suite.
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Returns the test groups of the suite.
+ *
+ * @return array
+ */
+ public function getGroups()
+ {
+ return array_keys($this->groups);
+ }
+
+ public function getGroupDetails()
+ {
+ return $this->groups;
+ }
+
+ /**
+ * Set tests groups of the test case
+ *
+ * @param array $groups
+ */
+ public function setGroupDetails(array $groups)
+ {
+ $this->groups = $groups;
+ }
+
+ /**
+ * Runs the tests and collects their result in a TestResult.
+ *
+ * @param PHPUnit_Framework_TestResult $result
+ *
+ * @return PHPUnit_Framework_TestResult
+ */
+ public function run(PHPUnit_Framework_TestResult $result = null)
+ {
+ if ($result === null) {
+ $result = $this->createResult();
+ }
+
+ if (count($this) == 0) {
+ return $result;
+ }
+
+ $hookMethods = PHPUnit_Util_Test::getHookMethods($this->name);
+
+ $result->startTestSuite($this);
+
+ try {
+ $this->setUp();
+
+ foreach ($hookMethods['beforeClass'] as $beforeClassMethod) {
+ if ($this->testCase === true &&
+ class_exists($this->name, false) &&
+ method_exists($this->name, $beforeClassMethod)) {
+ if ($missingRequirements = PHPUnit_Util_Test::getMissingRequirements($this->name, $beforeClassMethod)) {
+ $this->markTestSuiteSkipped(implode(PHP_EOL, $missingRequirements));
+ }
+
+ call_user_func([$this->name, $beforeClassMethod]);
+ }
+ }
+ } catch (PHPUnit_Framework_SkippedTestSuiteError $e) {
+ $numTests = count($this);
+
+ for ($i = 0; $i < $numTests; $i++) {
+ $result->startTest($this);
+ $result->addFailure($this, $e, 0);
+ $result->endTest($this, 0);
+ }
+
+ $this->tearDown();
+ $result->endTestSuite($this);
+
+ return $result;
+ } catch (Throwable $_t) {
+ $t = $_t;
+ } catch (Exception $_t) {
+ $t = $_t;
+ }
+
+ if (isset($t)) {
+ $numTests = count($this);
+
+ for ($i = 0; $i < $numTests; $i++) {
+ if ($result->shouldStop()) {
+ break;
+ }
+
+ $result->startTest($this);
+ $result->addError($this, $t, 0);
+ $result->endTest($this, 0);
+ }
+
+ $this->tearDown();
+ $result->endTestSuite($this);
+
+ return $result;
+ }
+
+ foreach ($this as $test) {
+ if ($result->shouldStop()) {
+ break;
+ }
+
+ if ($test instanceof PHPUnit_Framework_TestCase ||
+ $test instanceof self) {
+ $test->setBeStrictAboutChangesToGlobalState($this->beStrictAboutChangesToGlobalState);
+ $test->setBackupGlobals($this->backupGlobals);
+ $test->setBackupStaticAttributes($this->backupStaticAttributes);
+ $test->setRunTestInSeparateProcess($this->runTestInSeparateProcess);
+ }
+
+ $test->run($result);
+ }
+
+ foreach ($hookMethods['afterClass'] as $afterClassMethod) {
+ if ($this->testCase === true && class_exists($this->name, false) && method_exists($this->name, $afterClassMethod)) {
+ call_user_func([$this->name, $afterClassMethod]);
+ }
+ }
+
+ $this->tearDown();
+
+ $result->endTestSuite($this);
+
+ return $result;
+ }
+
+ /**
+ * @param bool $runTestInSeparateProcess
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function setRunTestInSeparateProcess($runTestInSeparateProcess)
+ {
+ if (is_bool($runTestInSeparateProcess)) {
+ $this->runTestInSeparateProcess = $runTestInSeparateProcess;
+ } else {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+ }
+
+ /**
+ * Runs a test.
+ *
+ * @deprecated
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_TestResult $result
+ */
+ public function runTest(PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result)
+ {
+ $test->run($result);
+ }
+
+ /**
+ * Sets the name of the suite.
+ *
+ * @param string
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * Returns the test at the given index.
+ *
+ * @param int|false
+ *
+ * @return PHPUnit_Framework_Test
+ */
+ public function testAt($index)
+ {
+ if (isset($this->tests[$index])) {
+ return $this->tests[$index];
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the tests as an enumeration.
+ *
+ * @return array
+ */
+ public function tests()
+ {
+ return $this->tests;
+ }
+
+ /**
+ * Set tests of the test suite
+ *
+ * @param array $tests
+ */
+ public function setTests(array $tests)
+ {
+ $this->tests = $tests;
+ }
+
+ /**
+ * Mark the test suite as skipped.
+ *
+ * @param string $message
+ *
+ * @throws PHPUnit_Framework_SkippedTestSuiteError
+ */
+ public function markTestSuiteSkipped($message = '')
+ {
+ throw new PHPUnit_Framework_SkippedTestSuiteError($message);
+ }
+
+ /**
+ * @param ReflectionClass $class
+ * @param ReflectionMethod $method
+ */
+ protected function addTestMethod(ReflectionClass $class, ReflectionMethod $method)
+ {
+ if (!$this->isTestMethod($method)) {
+ return;
+ }
+
+ $name = $method->getName();
+
+ if (!$method->isPublic()) {
+ $this->addTest(
+ self::warning(
+ sprintf(
+ 'Test method "%s" in test class "%s" is not public.',
+ $name,
+ $class->getName()
+ )
+ )
+ );
+
+ return;
+ }
+
+ $test = self::createTest($class, $name);
+
+ if ($test instanceof PHPUnit_Framework_TestCase ||
+ $test instanceof PHPUnit_Framework_TestSuite_DataProvider) {
+ $test->setDependencies(
+ PHPUnit_Util_Test::getDependencies($class->getName(), $name)
+ );
+ }
+
+ $this->addTest(
+ $test,
+ PHPUnit_Util_Test::getGroups($class->getName(), $name)
+ );
+ }
+
+ /**
+ * @param ReflectionMethod $method
+ *
+ * @return bool
+ */
+ public static function isTestMethod(ReflectionMethod $method)
+ {
+ if (strpos($method->name, 'test') === 0) {
+ return true;
+ }
+
+ // @scenario on TestCase::testMethod()
+ // @test on TestCase::testMethod()
+ $docComment = $method->getDocComment();
+
+ return strpos($docComment, '@test') !== false ||
+ strpos($docComment, '@scenario') !== false;
+ }
+
+ /**
+ * @param string $message
+ *
+ * @return PHPUnit_Framework_WarningTestCase
+ */
+ protected static function warning($message)
+ {
+ return new PHPUnit_Framework_WarningTestCase($message);
+ }
+
+ /**
+ * @param string $class
+ * @param string $methodName
+ * @param string $message
+ *
+ * @return PHPUnit_Framework_SkippedTestCase
+ */
+ protected static function skipTest($class, $methodName, $message)
+ {
+ return new PHPUnit_Framework_SkippedTestCase($class, $methodName, $message);
+ }
+
+ /**
+ * @param string $class
+ * @param string $methodName
+ * @param string $message
+ *
+ * @return PHPUnit_Framework_IncompleteTestCase
+ */
+ protected static function incompleteTest($class, $methodName, $message)
+ {
+ return new PHPUnit_Framework_IncompleteTestCase($class, $methodName, $message);
+ }
+
+ /**
+ * @param bool $beStrictAboutChangesToGlobalState
+ */
+ public function setBeStrictAboutChangesToGlobalState($beStrictAboutChangesToGlobalState)
+ {
+ if (is_null($this->beStrictAboutChangesToGlobalState) && is_bool($beStrictAboutChangesToGlobalState)) {
+ $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState;
+ }
+ }
+
+ /**
+ * @param bool $backupGlobals
+ */
+ public function setBackupGlobals($backupGlobals)
+ {
+ if (is_null($this->backupGlobals) && is_bool($backupGlobals)) {
+ $this->backupGlobals = $backupGlobals;
+ }
+ }
+
+ /**
+ * @param bool $backupStaticAttributes
+ */
+ public function setBackupStaticAttributes($backupStaticAttributes)
+ {
+ if (is_null($this->backupStaticAttributes) &&
+ is_bool($backupStaticAttributes)) {
+ $this->backupStaticAttributes = $backupStaticAttributes;
+ }
+ }
+
+ /**
+ * Returns an iterator for this test suite.
+ *
+ * @return RecursiveIteratorIterator
+ */
+ public function getIterator()
+ {
+ $iterator = new PHPUnit_Util_TestSuiteIterator($this);
+
+ if ($this->iteratorFilter !== null) {
+ $iterator = $this->iteratorFilter->factory($iterator, $this);
+ }
+
+ return $iterator;
+ }
+
+ public function injectFilter(PHPUnit_Runner_Filter_Factory $filter)
+ {
+ $this->iteratorFilter = $filter;
+ foreach ($this as $test) {
+ if ($test instanceof self) {
+ $test->injectFilter($filter);
+ }
+ }
+ }
+
+ /**
+ * Template Method that is called before the tests
+ * of this test suite are run.
+ */
+ protected function setUp()
+ {
+ }
+
+ /**
+ * Template Method that is called after the tests
+ * of this test suite have finished running.
+ */
+ protected function tearDown()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/TestSuite/DataProvider.php b/vendor/phpunit/phpunit/src/Framework/TestSuite/DataProvider.php
new file mode 100644
index 0000000..2f4d748
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/TestSuite/DataProvider.php
@@ -0,0 +1,24 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Framework_TestSuite_DataProvider extends PHPUnit_Framework_TestSuite
+{
+ /**
+ * Sets the dependencies of a TestCase.
+ *
+ * @param array $dependencies
+ */
+ public function setDependencies(array $dependencies)
+ {
+ foreach ($this->tests as $test) {
+ $test->setDependencies($dependencies);
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php b/vendor/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php
new file mode 100644
index 0000000..8cdd7f8
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
+ * case of a test that unintentionally covers code.
+ */
+class PHPUnit_Framework_UnintentionallyCoveredCodeError extends PHPUnit_Framework_RiskyTestError
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/Warning.php b/vendor/phpunit/phpunit/src/Framework/Warning.php
new file mode 100644
index 0000000..70ccf9a
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/Warning.php
@@ -0,0 +1,25 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Thrown when there is a warning.
+ */
+class PHPUnit_Framework_Warning extends PHPUnit_Framework_Exception implements PHPUnit_Framework_SelfDescribing
+{
+ /**
+ * Wrapper for getMessage() which is declared as final.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return $this->getMessage();
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Framework/WarningTestCase.php b/vendor/phpunit/phpunit/src/Framework/WarningTestCase.php
new file mode 100644
index 0000000..8ba2cce
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Framework/WarningTestCase.php
@@ -0,0 +1,75 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A warning.
+ */
+class PHPUnit_Framework_WarningTestCase extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @var string
+ */
+ protected $message = '';
+
+ /**
+ * @var bool
+ */
+ protected $backupGlobals = false;
+
+ /**
+ * @var bool
+ */
+ protected $backupStaticAttributes = false;
+
+ /**
+ * @var bool
+ */
+ protected $runTestInSeparateProcess = false;
+
+ /**
+ * @var bool
+ */
+ protected $useErrorHandler = false;
+
+ /**
+ * @param string $message
+ */
+ public function __construct($message = '')
+ {
+ $this->message = $message;
+ parent::__construct('Warning');
+ }
+
+ /**
+ * @throws PHPUnit_Framework_Exception
+ */
+ protected function runTest()
+ {
+ throw new PHPUnit_Framework_Warning($this->message);
+ }
+
+ /**
+ * @return string
+ */
+ public function getMessage()
+ {
+ return $this->message;
+ }
+
+ /**
+ * Returns a string representation of the test case.
+ *
+ * @return string
+ */
+ public function toString()
+ {
+ return 'Warning';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Runner/BaseTestRunner.php b/vendor/phpunit/phpunit/src/Runner/BaseTestRunner.php
new file mode 100644
index 0000000..789b90b
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Runner/BaseTestRunner.php
@@ -0,0 +1,139 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Base class for all test runners.
+ */
+abstract class PHPUnit_Runner_BaseTestRunner
+{
+ const STATUS_PASSED = 0;
+ const STATUS_SKIPPED = 1;
+ const STATUS_INCOMPLETE = 2;
+ const STATUS_FAILURE = 3;
+ const STATUS_ERROR = 4;
+ const STATUS_RISKY = 5;
+ const STATUS_WARNING = 6;
+ const SUITE_METHODNAME = 'suite';
+
+ /**
+ * Returns the loader to be used.
+ *
+ * @return PHPUnit_Runner_TestSuiteLoader
+ */
+ public function getLoader()
+ {
+ return new PHPUnit_Runner_StandardTestSuiteLoader;
+ }
+
+ /**
+ * Returns the Test corresponding to the given suite.
+ * This is a template method, subclasses override
+ * the runFailed() and clearStatus() methods.
+ *
+ * @param string $suiteClassName
+ * @param string $suiteClassFile
+ * @param mixed $suffixes
+ *
+ * @return PHPUnit_Framework_Test
+ */
+ public function getTest($suiteClassName, $suiteClassFile = '', $suffixes = '')
+ {
+ if (is_dir($suiteClassName) &&
+ !is_file($suiteClassName . '.php') && empty($suiteClassFile)) {
+ $facade = new File_Iterator_Facade;
+ $files = $facade->getFilesAsArray(
+ $suiteClassName,
+ $suffixes
+ );
+
+ $suite = new PHPUnit_Framework_TestSuite($suiteClassName);
+ $suite->addTestFiles($files);
+
+ return $suite;
+ }
+
+ try {
+ $testClass = $this->loadSuiteClass(
+ $suiteClassName,
+ $suiteClassFile
+ );
+ } catch (PHPUnit_Framework_Exception $e) {
+ $this->runFailed($e->getMessage());
+
+ return;
+ }
+
+ try {
+ $suiteMethod = $testClass->getMethod(self::SUITE_METHODNAME);
+
+ if (!$suiteMethod->isStatic()) {
+ $this->runFailed(
+ 'suite() method must be static.'
+ );
+
+ return;
+ }
+
+ try {
+ $test = $suiteMethod->invoke(null, $testClass->getName());
+ } catch (ReflectionException $e) {
+ $this->runFailed(
+ sprintf(
+ "Failed to invoke suite() method.\n%s",
+ $e->getMessage()
+ )
+ );
+
+ return;
+ }
+ } catch (ReflectionException $e) {
+ try {
+ $test = new PHPUnit_Framework_TestSuite($testClass);
+ } catch (PHPUnit_Framework_Exception $e) {
+ $test = new PHPUnit_Framework_TestSuite;
+ $test->setName($suiteClassName);
+ }
+ }
+
+ $this->clearStatus();
+
+ return $test;
+ }
+
+ /**
+ * Returns the loaded ReflectionClass for a suite name.
+ *
+ * @param string $suiteClassName
+ * @param string $suiteClassFile
+ *
+ * @return ReflectionClass
+ */
+ protected function loadSuiteClass($suiteClassName, $suiteClassFile = '')
+ {
+ $loader = $this->getLoader();
+
+ return $loader->load($suiteClassName, $suiteClassFile);
+ }
+
+ /**
+ * Clears the status message.
+ */
+ protected function clearStatus()
+ {
+ }
+
+ /**
+ * Override to define how to handle a failed loading of
+ * a test suite.
+ *
+ * @param string $message
+ */
+ abstract protected function runFailed($message);
+}
diff --git a/vendor/phpunit/phpunit/src/Runner/Exception.php b/vendor/phpunit/phpunit/src/Runner/Exception.php
new file mode 100644
index 0000000..9eef43f
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Runner/Exception.php
@@ -0,0 +1,13 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Runner_Exception extends RuntimeException implements PHPUnit_Exception
+{
+}
diff --git a/vendor/phpunit/phpunit/src/Runner/Filter/Factory.php b/vendor/phpunit/phpunit/src/Runner/Filter/Factory.php
new file mode 100644
index 0000000..b841ac6
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Runner/Filter/Factory.php
@@ -0,0 +1,48 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Runner_Filter_Factory
+{
+ /**
+ * @var array
+ */
+ private $filters = [];
+
+ /**
+ * @param ReflectionClass $filter
+ * @param mixed $args
+ */
+ public function addFilter(ReflectionClass $filter, $args)
+ {
+ if (!$filter->isSubclassOf('RecursiveFilterIterator')) {
+ throw new InvalidArgumentException(
+ sprintf(
+ 'Class "%s" does not extend RecursiveFilterIterator',
+ $filter->name
+ )
+ );
+ }
+
+ $this->filters[] = [$filter, $args];
+ }
+
+ /**
+ * @return FilterIterator
+ */
+ public function factory(Iterator $iterator, PHPUnit_Framework_TestSuite $suite)
+ {
+ foreach ($this->filters as $filter) {
+ list($class, $args) = $filter;
+ $iterator = $class->newInstance($iterator, $args, $suite);
+ }
+
+ return $iterator;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Runner/Filter/Group.php b/vendor/phpunit/phpunit/src/Runner/Filter/Group.php
new file mode 100644
index 0000000..23a8f86
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Runner/Filter/Group.php
@@ -0,0 +1,56 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+abstract class PHPUnit_Runner_Filter_GroupFilterIterator extends RecursiveFilterIterator
+{
+ /**
+ * @var array
+ */
+ protected $groupTests = [];
+
+ /**
+ * @param RecursiveIterator $iterator
+ * @param array $groups
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function __construct(RecursiveIterator $iterator, array $groups, PHPUnit_Framework_TestSuite $suite)
+ {
+ parent::__construct($iterator);
+
+ foreach ($suite->getGroupDetails() as $group => $tests) {
+ if (in_array($group, $groups)) {
+ $testHashes = array_map(
+ function ($test) {
+ return spl_object_hash($test);
+ },
+ $tests
+ );
+
+ $this->groupTests = array_merge($this->groupTests, $testHashes);
+ }
+ }
+ }
+
+ /**
+ * @return bool
+ */
+ public function accept()
+ {
+ $test = $this->getInnerIterator()->current();
+
+ if ($test instanceof PHPUnit_Framework_TestSuite) {
+ return true;
+ }
+
+ return $this->doAccept(spl_object_hash($test));
+ }
+
+ abstract protected function doAccept($hash);
+}
diff --git a/vendor/phpunit/phpunit/src/Runner/Filter/Group/Exclude.php b/vendor/phpunit/phpunit/src/Runner/Filter/Group/Exclude.php
new file mode 100644
index 0000000..e07a4f9
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Runner/Filter/Group/Exclude.php
@@ -0,0 +1,22 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Runner_Filter_Group_Exclude extends PHPUnit_Runner_Filter_GroupFilterIterator
+{
+ /**
+ * @param string $hash
+ *
+ * @return bool
+ */
+ protected function doAccept($hash)
+ {
+ return !in_array($hash, $this->groupTests);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Runner/Filter/Group/Include.php b/vendor/phpunit/phpunit/src/Runner/Filter/Group/Include.php
new file mode 100644
index 0000000..3193842
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Runner/Filter/Group/Include.php
@@ -0,0 +1,22 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Runner_Filter_Group_Include extends PHPUnit_Runner_Filter_GroupFilterIterator
+{
+ /**
+ * @param string $hash
+ *
+ * @return bool
+ */
+ protected function doAccept($hash)
+ {
+ return in_array($hash, $this->groupTests);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Runner/Filter/Test.php b/vendor/phpunit/phpunit/src/Runner/Filter/Test.php
new file mode 100644
index 0000000..99ceb76
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Runner/Filter/Test.php
@@ -0,0 +1,117 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Runner_Filter_Test extends RecursiveFilterIterator
+{
+ /**
+ * @var string
+ */
+ protected $filter = null;
+
+ /**
+ * @var int
+ */
+ protected $filterMin;
+ /**
+ * @var int
+ */
+ protected $filterMax;
+
+ /**
+ * @param RecursiveIterator $iterator
+ * @param string $filter
+ */
+ public function __construct(RecursiveIterator $iterator, $filter)
+ {
+ parent::__construct($iterator);
+ $this->setFilter($filter);
+ }
+
+ /**
+ * @param string $filter
+ */
+ protected function setFilter($filter)
+ {
+ if (PHPUnit_Util_Regex::pregMatchSafe($filter, '') === false) {
+ // Handles:
+ // * testAssertEqualsSucceeds#4
+ // * testAssertEqualsSucceeds#4-8
+ if (preg_match('/^(.*?)#(\d+)(?:-(\d+))?$/', $filter, $matches)) {
+ if (isset($matches[3]) && $matches[2] < $matches[3]) {
+ $filter = sprintf(
+ '%s.*with data set #(\d+)$',
+ $matches[1]
+ );
+
+ $this->filterMin = $matches[2];
+ $this->filterMax = $matches[3];
+ } else {
+ $filter = sprintf(
+ '%s.*with data set #%s$',
+ $matches[1],
+ $matches[2]
+ );
+ }
+ } // Handles:
+ // * testDetermineJsonError@JSON_ERROR_NONE
+ // * testDetermineJsonError@JSON.*
+ elseif (preg_match('/^(.*?)@(.+)$/', $filter, $matches)) {
+ $filter = sprintf(
+ '%s.*with data set "%s"$',
+ $matches[1],
+ $matches[2]
+ );
+ }
+
+ // Escape delimiters in regular expression. Do NOT use preg_quote,
+ // to keep magic characters.
+ $filter = sprintf('/%s/', str_replace(
+ '/',
+ '\\/',
+ $filter
+ ));
+ }
+
+ $this->filter = $filter;
+ }
+
+ /**
+ * @return bool
+ */
+ public function accept()
+ {
+ $test = $this->getInnerIterator()->current();
+
+ if ($test instanceof PHPUnit_Framework_TestSuite) {
+ return true;
+ }
+
+ if ($test instanceof PHPUnit_Framework_WarningTestCase) {
+ $name = $test->getMessage();
+ } else {
+ $tmp = PHPUnit_Util_Test::describe($test, false);
+
+ if ($tmp[0] != '') {
+ $name = implode('::', $tmp);
+ } else {
+ $name = $tmp[1];
+ }
+ }
+
+ $accepted = @preg_match($this->filter, $name, $matches);
+
+ if ($accepted && isset($this->filterMax)) {
+ $set = end($matches);
+ $accepted = $set >= $this->filterMin && $set <= $this->filterMax;
+ }
+
+ return $accepted;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php b/vendor/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php
new file mode 100644
index 0000000..79a9203
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php
@@ -0,0 +1,116 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * The standard test suite loader.
+ */
+class PHPUnit_Runner_StandardTestSuiteLoader implements PHPUnit_Runner_TestSuiteLoader
+{
+ /**
+ * @param string $suiteClassName
+ * @param string $suiteClassFile
+ *
+ * @return ReflectionClass
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function load($suiteClassName, $suiteClassFile = '')
+ {
+ $suiteClassName = str_replace('.php', '', $suiteClassName);
+
+ if (empty($suiteClassFile)) {
+ $suiteClassFile = PHPUnit_Util_Filesystem::classNameToFilename(
+ $suiteClassName
+ );
+ }
+
+ if (!class_exists($suiteClassName, false)) {
+ $loadedClasses = get_declared_classes();
+
+ $filename = PHPUnit_Util_Fileloader::checkAndLoad($suiteClassFile);
+
+ $loadedClasses = array_values(
+ array_diff(get_declared_classes(), $loadedClasses)
+ );
+ }
+
+ if (!class_exists($suiteClassName, false) && !empty($loadedClasses)) {
+ $offset = 0 - strlen($suiteClassName);
+
+ foreach ($loadedClasses as $loadedClass) {
+ $class = new ReflectionClass($loadedClass);
+ if (substr($loadedClass, $offset) === $suiteClassName &&
+ $class->getFileName() == $filename) {
+ $suiteClassName = $loadedClass;
+ break;
+ }
+ }
+ }
+
+ if (!class_exists($suiteClassName, false) && !empty($loadedClasses)) {
+ $testCaseClass = 'PHPUnit_Framework_TestCase';
+
+ foreach ($loadedClasses as $loadedClass) {
+ $class = new ReflectionClass($loadedClass);
+ $classFile = $class->getFileName();
+
+ if ($class->isSubclassOf($testCaseClass) &&
+ !$class->isAbstract()) {
+ $suiteClassName = $loadedClass;
+ $testCaseClass = $loadedClass;
+
+ if ($classFile == realpath($suiteClassFile)) {
+ break;
+ }
+ }
+
+ if ($class->hasMethod('suite')) {
+ $method = $class->getMethod('suite');
+
+ if (!$method->isAbstract() &&
+ $method->isPublic() &&
+ $method->isStatic()) {
+ $suiteClassName = $loadedClass;
+
+ if ($classFile == realpath($suiteClassFile)) {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (class_exists($suiteClassName, false)) {
+ $class = new ReflectionClass($suiteClassName);
+
+ if ($class->getFileName() == realpath($suiteClassFile)) {
+ return $class;
+ }
+ }
+
+ throw new PHPUnit_Framework_Exception(
+ sprintf(
+ "Class '%s' could not be found in '%s'.",
+ $suiteClassName,
+ $suiteClassFile
+ )
+ );
+ }
+
+ /**
+ * @param ReflectionClass $aClass
+ *
+ * @return ReflectionClass
+ */
+ public function reload(ReflectionClass $aClass)
+ {
+ return $aClass;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Runner/TestSuiteLoader.php b/vendor/phpunit/phpunit/src/Runner/TestSuiteLoader.php
new file mode 100644
index 0000000..338486b
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Runner/TestSuiteLoader.php
@@ -0,0 +1,30 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * An interface to define how a test suite should be loaded.
+ */
+interface PHPUnit_Runner_TestSuiteLoader
+{
+ /**
+ * @param string $suiteClassName
+ * @param string $suiteClassFile
+ *
+ * @return ReflectionClass
+ */
+ public function load($suiteClassName, $suiteClassFile = '');
+
+ /**
+ * @param ReflectionClass $aClass
+ *
+ * @return ReflectionClass
+ */
+ public function reload(ReflectionClass $aClass);
+}
diff --git a/vendor/phpunit/phpunit/src/Runner/Version.php b/vendor/phpunit/phpunit/src/Runner/Version.php
new file mode 100644
index 0000000..9fe325e
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Runner/Version.php
@@ -0,0 +1,73 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use SebastianBergmann\Version;
+
+/**
+ * This class defines the current version of PHPUnit.
+ */
+class PHPUnit_Runner_Version
+{
+ private static $pharVersion;
+ private static $version;
+
+ /**
+ * Returns the current version of PHPUnit.
+ *
+ * @return string
+ */
+ public static function id()
+ {
+ if (self::$pharVersion !== null) {
+ return self::$pharVersion;
+ }
+
+ if (self::$version === null) {
+ $version = new Version('5.7.27', dirname(dirname(__DIR__)));
+ self::$version = $version->getVersion();
+ }
+
+ return self::$version;
+ }
+
+ /**
+ * @return string
+ */
+ public static function series()
+ {
+ if (strpos(self::id(), '-')) {
+ $version = explode('-', self::id())[0];
+ } else {
+ $version = self::id();
+ }
+
+ return implode('.', array_slice(explode('.', $version), 0, 2));
+ }
+
+ /**
+ * @return string
+ */
+ public static function getVersionString()
+ {
+ return 'PHPUnit ' . self::id() . ' by Sebastian Bergmann and contributors.';
+ }
+
+ /**
+ * @return string
+ */
+ public static function getReleaseChannel()
+ {
+ if (strpos(self::$pharVersion, '-') !== false) {
+ return '-nightly';
+ }
+
+ return '';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/TextUI/Command.php b/vendor/phpunit/phpunit/src/TextUI/Command.php
new file mode 100644
index 0000000..1bed290
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/TextUI/Command.php
@@ -0,0 +1,1172 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A TestRunner for the Command Line Interface (CLI)
+ * PHP SAPI Module.
+ */
+class PHPUnit_TextUI_Command
+{
+ /**
+ * @var array
+ */
+ protected $arguments = [
+ 'listGroups' => false,
+ 'listSuites' => false,
+ 'loader' => null,
+ 'useDefaultConfiguration' => true,
+ 'loadedExtensions' => [],
+ 'notLoadedExtensions' => []
+ ];
+
+ /**
+ * @var array
+ */
+ protected $options = [];
+
+ /**
+ * @var array
+ */
+ protected $longOptions = [
+ 'atleast-version=' => null,
+ 'bootstrap=' => null,
+ 'colors==' => null,
+ 'columns=' => null,
+ 'configuration=' => null,
+ 'coverage-clover=' => null,
+ 'coverage-crap4j=' => null,
+ 'coverage-html=' => null,
+ 'coverage-php=' => null,
+ 'coverage-text==' => null,
+ 'coverage-xml=' => null,
+ 'debug' => null,
+ 'disallow-test-output' => null,
+ 'disallow-resource-usage' => null,
+ 'disallow-todo-tests' => null,
+ 'enforce-time-limit' => null,
+ 'exclude-group=' => null,
+ 'filter=' => null,
+ 'generate-configuration' => null,
+ 'group=' => null,
+ 'help' => null,
+ 'include-path=' => null,
+ 'list-groups' => null,
+ 'list-suites' => null,
+ 'loader=' => null,
+ 'log-json=' => null,
+ 'log-junit=' => null,
+ 'log-tap=' => null,
+ 'log-teamcity=' => null,
+ 'no-configuration' => null,
+ 'no-coverage' => null,
+ 'no-extensions' => null,
+ 'no-globals-backup' => null,
+ 'printer=' => null,
+ 'process-isolation' => null,
+ 'repeat=' => null,
+ 'report-useless-tests' => null,
+ 'reverse-list' => null,
+ 'static-backup' => null,
+ 'stderr' => null,
+ 'stop-on-error' => null,
+ 'stop-on-failure' => null,
+ 'stop-on-warning' => null,
+ 'stop-on-incomplete' => null,
+ 'stop-on-risky' => null,
+ 'stop-on-skipped' => null,
+ 'fail-on-warning' => null,
+ 'fail-on-risky' => null,
+ 'strict-coverage' => null,
+ 'disable-coverage-ignore' => null,
+ 'strict-global-state' => null,
+ 'tap' => null,
+ 'teamcity' => null,
+ 'testdox' => null,
+ 'testdox-group=' => null,
+ 'testdox-exclude-group=' => null,
+ 'testdox-html=' => null,
+ 'testdox-text=' => null,
+ 'testdox-xml=' => null,
+ 'test-suffix=' => null,
+ 'testsuite=' => null,
+ 'verbose' => null,
+ 'version' => null,
+ 'whitelist=' => null
+ ];
+
+ /**
+ * @var bool
+ */
+ private $versionStringPrinted = false;
+
+ /**
+ * @param bool $exit
+ */
+ public static function main($exit = true)
+ {
+ $command = new static;
+
+ return $command->run($_SERVER['argv'], $exit);
+ }
+
+ /**
+ * @param array $argv
+ * @param bool $exit
+ *
+ * @return int
+ */
+ public function run(array $argv, $exit = true)
+ {
+ $this->handleArguments($argv);
+
+ $runner = $this->createRunner();
+
+ if (is_object($this->arguments['test']) &&
+ $this->arguments['test'] instanceof PHPUnit_Framework_Test) {
+ $suite = $this->arguments['test'];
+ } else {
+ $suite = $runner->getTest(
+ $this->arguments['test'],
+ $this->arguments['testFile'],
+ $this->arguments['testSuffixes']
+ );
+ }
+
+ if ($this->arguments['listGroups']) {
+ $this->printVersionString();
+
+ print "Available test group(s):\n";
+
+ $groups = $suite->getGroups();
+ sort($groups);
+
+ foreach ($groups as $group) {
+ print " - $group\n";
+ }
+
+ if ($exit) {
+ exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
+ } else {
+ return PHPUnit_TextUI_TestRunner::SUCCESS_EXIT;
+ }
+ }
+
+ if ($this->arguments['listSuites']) {
+ $this->printVersionString();
+
+ print "Available test suite(s):\n";
+
+ $configuration = PHPUnit_Util_Configuration::getInstance(
+ $this->arguments['configuration']
+ );
+
+ $suiteNames = $configuration->getTestSuiteNames();
+ foreach ($suiteNames as $suiteName) {
+ print " - $suiteName\n";
+ }
+
+ if ($exit) {
+ exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
+ } else {
+ return PHPUnit_TextUI_TestRunner::SUCCESS_EXIT;
+ }
+ }
+
+ unset($this->arguments['test']);
+ unset($this->arguments['testFile']);
+
+ try {
+ $result = $runner->doRun($suite, $this->arguments, $exit);
+ } catch (PHPUnit_Framework_Exception $e) {
+ print $e->getMessage() . "\n";
+ }
+
+ $return = PHPUnit_TextUI_TestRunner::FAILURE_EXIT;
+
+ if (isset($result) && $result->wasSuccessful(false)) {
+ $return = PHPUnit_TextUI_TestRunner::SUCCESS_EXIT;
+ } elseif (!isset($result) || $result->errorCount() > 0) {
+ $return = PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT;
+ }
+
+ if ($exit) {
+ exit($return);
+ }
+
+ return $return;
+ }
+
+ /**
+ * Create a TestRunner, override in subclasses.
+ *
+ * @return PHPUnit_TextUI_TestRunner
+ */
+ protected function createRunner()
+ {
+ return new PHPUnit_TextUI_TestRunner($this->arguments['loader']);
+ }
+
+ /**
+ * Handles the command-line arguments.
+ *
+ * A child class of PHPUnit_TextUI_Command can hook into the argument
+ * parsing by adding the switch(es) to the $longOptions array and point to a
+ * callback method that handles the switch(es) in the child class like this
+ *
+ * <code>
+ * <?php
+ * class MyCommand extends PHPUnit_TextUI_Command
+ * {
+ * public function __construct()
+ * {
+ * // my-switch won't accept a value, it's an on/off
+ * $this->longOptions['my-switch'] = 'myHandler';
+ * // my-secondswitch will accept a value - note the equals sign
+ * $this->longOptions['my-secondswitch='] = 'myOtherHandler';
+ * }
+ *
+ * // --my-switch -> myHandler()
+ * protected function myHandler()
+ * {
+ * }
+ *
+ * // --my-secondswitch foo -> myOtherHandler('foo')
+ * protected function myOtherHandler ($value)
+ * {
+ * }
+ *
+ * // You will also need this - the static keyword in the
+ * // PHPUnit_TextUI_Command will mean that it'll be
+ * // PHPUnit_TextUI_Command that gets instantiated,
+ * // not MyCommand
+ * public static function main($exit = true)
+ * {
+ * $command = new static;
+ *
+ * return $command->run($_SERVER['argv'], $exit);
+ * }
+ *
+ * }
+ * </code>
+ *
+ * @param array $argv
+ */
+ protected function handleArguments(array $argv)
+ {
+ if (defined('__PHPUNIT_PHAR__')) {
+ $this->longOptions['check-version'] = null;
+ $this->longOptions['selfupdate'] = null;
+ $this->longOptions['self-update'] = null;
+ $this->longOptions['selfupgrade'] = null;
+ $this->longOptions['self-upgrade'] = null;
+ }
+
+ try {
+ $this->options = PHPUnit_Util_Getopt::getopt(
+ $argv,
+ 'd:c:hv',
+ array_keys($this->longOptions)
+ );
+ } catch (PHPUnit_Framework_Exception $e) {
+ $this->showError($e->getMessage());
+ }
+
+ foreach ($this->options[0] as $option) {
+ switch ($option[0]) {
+ case '--colors':
+ $this->arguments['colors'] = $option[1] ?: PHPUnit_TextUI_ResultPrinter::COLOR_AUTO;
+ break;
+
+ case '--bootstrap':
+ $this->arguments['bootstrap'] = $option[1];
+ break;
+
+ case '--columns':
+ if (is_numeric($option[1])) {
+ $this->arguments['columns'] = (int) $option[1];
+ } elseif ($option[1] == 'max') {
+ $this->arguments['columns'] = 'max';
+ }
+ break;
+
+ case 'c':
+ case '--configuration':
+ $this->arguments['configuration'] = $option[1];
+ break;
+
+ case '--coverage-clover':
+ $this->arguments['coverageClover'] = $option[1];
+ break;
+
+ case '--coverage-crap4j':
+ $this->arguments['coverageCrap4J'] = $option[1];
+ break;
+
+ case '--coverage-html':
+ $this->arguments['coverageHtml'] = $option[1];
+ break;
+
+ case '--coverage-php':
+ $this->arguments['coveragePHP'] = $option[1];
+ break;
+
+ case '--coverage-text':
+ if ($option[1] === null) {
+ $option[1] = 'php://stdout';
+ }
+
+ $this->arguments['coverageText'] = $option[1];
+ $this->arguments['coverageTextShowUncoveredFiles'] = false;
+ $this->arguments['coverageTextShowOnlySummary'] = false;
+ break;
+
+ case '--coverage-xml':
+ $this->arguments['coverageXml'] = $option[1];
+ break;
+
+ case 'd':
+ $ini = explode('=', $option[1]);
+
+ if (isset($ini[0])) {
+ if (isset($ini[1])) {
+ ini_set($ini[0], $ini[1]);
+ } else {
+ ini_set($ini[0], true);
+ }
+ }
+ break;
+
+ case '--debug':
+ $this->arguments['debug'] = true;
+ break;
+
+ case 'h':
+ case '--help':
+ $this->showHelp();
+ exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
+ break;
+
+ case '--filter':
+ $this->arguments['filter'] = $option[1];
+ break;
+
+ case '--testsuite':
+ $this->arguments['testsuite'] = $option[1];
+ break;
+
+ case '--generate-configuration':
+ $this->printVersionString();
+
+ printf(
+ "Generating phpunit.xml in %s\n\n",
+ getcwd()
+ );
+
+ print 'Bootstrap script (relative to path shown above; default: vendor/autoload.php): ';
+ $bootstrapScript = trim(fgets(STDIN));
+
+ print 'Tests directory (relative to path shown above; default: tests): ';
+ $testsDirectory = trim(fgets(STDIN));
+
+ print 'Source directory (relative to path shown above; default: src): ';
+ $src = trim(fgets(STDIN));
+
+ if ($bootstrapScript == '') {
+ $bootstrapScript = 'vendor/autoload.php';
+ }
+
+ if ($testsDirectory == '') {
+ $testsDirectory = 'tests';
+ }
+
+ if ($src == '') {
+ $src = 'src';
+ }
+
+ $generator = new PHPUnit_Util_ConfigurationGenerator;
+
+ file_put_contents(
+ 'phpunit.xml',
+ $generator->generateDefaultConfiguration(
+ PHPUnit_Runner_Version::series(),
+ $bootstrapScript,
+ $testsDirectory,
+ $src
+ )
+ );
+
+ printf(
+ "\nGenerated phpunit.xml in %s\n",
+ getcwd()
+ );
+
+ exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
+ break;
+
+ case '--group':
+ $this->arguments['groups'] = explode(',', $option[1]);
+ break;
+
+ case '--exclude-group':
+ $this->arguments['excludeGroups'] = explode(
+ ',',
+ $option[1]
+ );
+ break;
+
+ case '--test-suffix':
+ $this->arguments['testSuffixes'] = explode(
+ ',',
+ $option[1]
+ );
+ break;
+
+ case '--include-path':
+ $includePath = $option[1];
+ break;
+
+ case '--list-groups':
+ $this->arguments['listGroups'] = true;
+ break;
+
+ case '--list-suites':
+ $this->arguments['listSuites'] = true;
+ break;
+
+ case '--printer':
+ $this->arguments['printer'] = $option[1];
+ break;
+
+ case '--loader':
+ $this->arguments['loader'] = $option[1];
+ break;
+
+ case '--log-json':
+ $this->arguments['jsonLogfile'] = $option[1];
+ break;
+
+ case '--log-junit':
+ $this->arguments['junitLogfile'] = $option[1];
+ break;
+
+ case '--log-tap':
+ $this->arguments['tapLogfile'] = $option[1];
+ break;
+
+ case '--log-teamcity':
+ $this->arguments['teamcityLogfile'] = $option[1];
+ break;
+
+ case '--process-isolation':
+ $this->arguments['processIsolation'] = true;
+ break;
+
+ case '--repeat':
+ $this->arguments['repeat'] = (int) $option[1];
+ break;
+
+ case '--stderr':
+ $this->arguments['stderr'] = true;
+ break;
+
+ case '--stop-on-error':
+ $this->arguments['stopOnError'] = true;
+ break;
+
+ case '--stop-on-failure':
+ $this->arguments['stopOnFailure'] = true;
+ break;
+
+ case '--stop-on-warning':
+ $this->arguments['stopOnWarning'] = true;
+ break;
+
+ case '--stop-on-incomplete':
+ $this->arguments['stopOnIncomplete'] = true;
+ break;
+
+ case '--stop-on-risky':
+ $this->arguments['stopOnRisky'] = true;
+ break;
+
+ case '--stop-on-skipped':
+ $this->arguments['stopOnSkipped'] = true;
+ break;
+
+ case '--fail-on-warning':
+ $this->arguments['failOnWarning'] = true;
+ break;
+
+ case '--fail-on-risky':
+ $this->arguments['failOnRisky'] = true;
+ break;
+
+ case '--tap':
+ $this->arguments['printer'] = 'PHPUnit_Util_Log_TAP';
+ break;
+
+ case '--teamcity':
+ $this->arguments['printer'] = 'PHPUnit_Util_Log_TeamCity';
+ break;
+
+ case '--testdox':
+ $this->arguments['printer'] = 'PHPUnit_Util_TestDox_ResultPrinter_Text';
+ break;
+
+ case '--testdox-group':
+ $this->arguments['testdoxGroups'] = explode(
+ ',',
+ $option[1]
+ );
+ break;
+
+ case '--testdox-exclude-group':
+ $this->arguments['testdoxExcludeGroups'] = explode(
+ ',',
+ $option[1]
+ );
+ break;
+
+ case '--testdox-html':
+ $this->arguments['testdoxHTMLFile'] = $option[1];
+ break;
+
+ case '--testdox-text':
+ $this->arguments['testdoxTextFile'] = $option[1];
+ break;
+
+ case '--testdox-xml':
+ $this->arguments['testdoxXMLFile'] = $option[1];
+ break;
+
+ case '--no-configuration':
+ $this->arguments['useDefaultConfiguration'] = false;
+ break;
+
+ case '--no-extensions':
+ $this->arguments['noExtensions'] = true;
+ break;
+
+ case '--no-coverage':
+ $this->arguments['noCoverage'] = true;
+ break;
+
+ case '--no-globals-backup':
+ $this->arguments['backupGlobals'] = false;
+ break;
+
+ case '--static-backup':
+ $this->arguments['backupStaticAttributes'] = true;
+ break;
+
+ case 'v':
+ case '--verbose':
+ $this->arguments['verbose'] = true;
+ break;
+
+ case '--atleast-version':
+ exit(version_compare(PHPUnit_Runner_Version::id(), $option[1], '>=')
+ ? PHPUnit_TextUI_TestRunner::SUCCESS_EXIT
+ : PHPUnit_TextUI_TestRunner::FAILURE_EXIT
+ );
+ break;
+
+ case '--version':
+ $this->printVersionString();
+ exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
+ break;
+
+ case '--report-useless-tests':
+ $this->arguments['reportUselessTests'] = true;
+ break;
+
+ case '--strict-coverage':
+ $this->arguments['strictCoverage'] = true;
+ break;
+
+ case '--disable-coverage-ignore':
+ $this->arguments['disableCodeCoverageIgnore'] = true;
+ break;
+
+ case '--strict-global-state':
+ $this->arguments['beStrictAboutChangesToGlobalState'] = true;
+ break;
+
+ case '--disallow-test-output':
+ $this->arguments['disallowTestOutput'] = true;
+ break;
+
+ case '--disallow-resource-usage':
+ $this->arguments['beStrictAboutResourceUsageDuringSmallTests'] = true;
+ break;
+
+ case '--enforce-time-limit':
+ $this->arguments['enforceTimeLimit'] = true;
+ break;
+
+ case '--disallow-todo-tests':
+ $this->arguments['disallowTodoAnnotatedTests'] = true;
+ break;
+
+ case '--reverse-list':
+ $this->arguments['reverseList'] = true;
+ break;
+
+ case '--check-version':
+ $this->handleVersionCheck();
+ break;
+
+ case '--selfupdate':
+ case '--self-update':
+ $this->handleSelfUpdate();
+ break;
+
+ case '--selfupgrade':
+ case '--self-upgrade':
+ $this->handleSelfUpdate(true);
+ break;
+
+ case '--whitelist':
+ $this->arguments['whitelist'] = $option[1];
+ break;
+
+ default:
+ $optionName = str_replace('--', '', $option[0]);
+
+ $handler = null;
+ if (isset($this->longOptions[$optionName])) {
+ $handler = $this->longOptions[$optionName];
+ } elseif (isset($this->longOptions[$optionName . '='])) {
+ $handler = $this->longOptions[$optionName . '='];
+ }
+
+ if (isset($handler) && is_callable([$this, $handler])) {
+ $this->$handler($option[1]);
+ }
+ }
+ }
+
+ $this->handleCustomTestSuite();
+
+ if (!isset($this->arguments['test'])) {
+ if (isset($this->options[1][0])) {
+ $this->arguments['test'] = $this->options[1][0];
+ }
+
+ if (isset($this->options[1][1])) {
+ $this->arguments['testFile'] = realpath($this->options[1][1]);
+ } else {
+ $this->arguments['testFile'] = '';
+ }
+
+ if (isset($this->arguments['test']) &&
+ is_file($this->arguments['test']) &&
+ substr($this->arguments['test'], -5, 5) != '.phpt') {
+ $this->arguments['testFile'] = realpath($this->arguments['test']);
+ $this->arguments['test'] = substr($this->arguments['test'], 0, strrpos($this->arguments['test'], '.'));
+ }
+ }
+
+ if (!isset($this->arguments['testSuffixes'])) {
+ $this->arguments['testSuffixes'] = ['Test.php', '.phpt'];
+ }
+
+ if (isset($includePath)) {
+ ini_set(
+ 'include_path',
+ $includePath . PATH_SEPARATOR . ini_get('include_path')
+ );
+ }
+
+ if ($this->arguments['loader'] !== null) {
+ $this->arguments['loader'] = $this->handleLoader($this->arguments['loader']);
+ }
+
+ if (isset($this->arguments['configuration']) &&
+ is_dir($this->arguments['configuration'])) {
+ $configurationFile = $this->arguments['configuration'] . '/phpunit.xml';
+
+ if (file_exists($configurationFile)) {
+ $this->arguments['configuration'] = realpath(
+ $configurationFile
+ );
+ } elseif (file_exists($configurationFile . '.dist')) {
+ $this->arguments['configuration'] = realpath(
+ $configurationFile . '.dist'
+ );
+ }
+ } elseif (!isset($this->arguments['configuration']) &&
+ $this->arguments['useDefaultConfiguration']) {
+ if (file_exists('phpunit.xml')) {
+ $this->arguments['configuration'] = realpath('phpunit.xml');
+ } elseif (file_exists('phpunit.xml.dist')) {
+ $this->arguments['configuration'] = realpath(
+ 'phpunit.xml.dist'
+ );
+ }
+ }
+
+ if (isset($this->arguments['configuration'])) {
+ try {
+ $configuration = PHPUnit_Util_Configuration::getInstance(
+ $this->arguments['configuration']
+ );
+ } catch (Throwable $e) {
+ print $e->getMessage() . "\n";
+ exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT);
+ } catch (Exception $e) {
+ print $e->getMessage() . "\n";
+ exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT);
+ }
+
+ $phpunitConfiguration = $configuration->getPHPUnitConfiguration();
+
+ $configuration->handlePHPConfiguration();
+
+ /*
+ * Issue #1216
+ */
+ if (isset($this->arguments['bootstrap'])) {
+ $this->handleBootstrap($this->arguments['bootstrap']);
+ } elseif (isset($phpunitConfiguration['bootstrap'])) {
+ $this->handleBootstrap($phpunitConfiguration['bootstrap']);
+ }
+
+ /*
+ * Issue #657
+ */
+ if (isset($phpunitConfiguration['stderr']) && ! isset($this->arguments['stderr'])) {
+ $this->arguments['stderr'] = $phpunitConfiguration['stderr'];
+ }
+
+ if (isset($phpunitConfiguration['extensionsDirectory']) && !isset($this->arguments['noExtensions']) && extension_loaded('phar')) {
+ $this->handleExtensions($phpunitConfiguration['extensionsDirectory']);
+ }
+
+ if (isset($phpunitConfiguration['columns']) && ! isset($this->arguments['columns'])) {
+ $this->arguments['columns'] = $phpunitConfiguration['columns'];
+ }
+
+ if (!isset($this->arguments['printer']) && isset($phpunitConfiguration['printerClass'])) {
+ if (isset($phpunitConfiguration['printerFile'])) {
+ $file = $phpunitConfiguration['printerFile'];
+ } else {
+ $file = '';
+ }
+
+ $this->arguments['printer'] = $this->handlePrinter(
+ $phpunitConfiguration['printerClass'],
+ $file
+ );
+ }
+
+ if (isset($phpunitConfiguration['testSuiteLoaderClass'])) {
+ if (isset($phpunitConfiguration['testSuiteLoaderFile'])) {
+ $file = $phpunitConfiguration['testSuiteLoaderFile'];
+ } else {
+ $file = '';
+ }
+
+ $this->arguments['loader'] = $this->handleLoader(
+ $phpunitConfiguration['testSuiteLoaderClass'],
+ $file
+ );
+ }
+
+ if (!isset($this->arguments['test'])) {
+ $testSuite = $configuration->getTestSuiteConfiguration(isset($this->arguments['testsuite']) ? $this->arguments['testsuite'] : null);
+
+ if ($testSuite !== null) {
+ $this->arguments['test'] = $testSuite;
+ }
+ }
+ } elseif (isset($this->arguments['bootstrap'])) {
+ $this->handleBootstrap($this->arguments['bootstrap']);
+ }
+
+ if (isset($this->arguments['printer']) &&
+ is_string($this->arguments['printer'])) {
+ $this->arguments['printer'] = $this->handlePrinter($this->arguments['printer']);
+ }
+
+ if (isset($this->arguments['test']) && is_string($this->arguments['test']) && substr($this->arguments['test'], -5, 5) == '.phpt') {
+ $test = new PHPUnit_Extensions_PhptTestCase($this->arguments['test']);
+
+ $this->arguments['test'] = new PHPUnit_Framework_TestSuite;
+ $this->arguments['test']->addTest($test);
+ }
+
+ if (!isset($this->arguments['test']) ||
+ (isset($this->arguments['testDatabaseLogRevision']) && !isset($this->arguments['testDatabaseDSN']))) {
+ $this->showHelp();
+ exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT);
+ }
+ }
+
+ /**
+ * Handles the loading of the PHPUnit_Runner_TestSuiteLoader implementation.
+ *
+ * @param string $loaderClass
+ * @param string $loaderFile
+ *
+ * @return PHPUnit_Runner_TestSuiteLoader
+ */
+ protected function handleLoader($loaderClass, $loaderFile = '')
+ {
+ if (!class_exists($loaderClass, false)) {
+ if ($loaderFile == '') {
+ $loaderFile = PHPUnit_Util_Filesystem::classNameToFilename(
+ $loaderClass
+ );
+ }
+
+ $loaderFile = stream_resolve_include_path($loaderFile);
+
+ if ($loaderFile) {
+ require $loaderFile;
+ }
+ }
+
+ if (class_exists($loaderClass, false)) {
+ $class = new ReflectionClass($loaderClass);
+
+ if ($class->implementsInterface('PHPUnit_Runner_TestSuiteLoader') &&
+ $class->isInstantiable()) {
+ return $class->newInstance();
+ }
+ }
+
+ if ($loaderClass == 'PHPUnit_Runner_StandardTestSuiteLoader') {
+ return;
+ }
+
+ $this->showError(
+ sprintf(
+ 'Could not use "%s" as loader.',
+ $loaderClass
+ )
+ );
+ }
+
+ /**
+ * Handles the loading of the PHPUnit_Util_Printer implementation.
+ *
+ * @param string $printerClass
+ * @param string $printerFile
+ *
+ * @return PHPUnit_Util_Printer|string
+ */
+ protected function handlePrinter($printerClass, $printerFile = '')
+ {
+ if (!class_exists($printerClass, false)) {
+ if ($printerFile == '') {
+ $printerFile = PHPUnit_Util_Filesystem::classNameToFilename(
+ $printerClass
+ );
+ }
+
+ $printerFile = stream_resolve_include_path($printerFile);
+
+ if ($printerFile) {
+ require $printerFile;
+ }
+ }
+
+ if (class_exists($printerClass)) {
+ $class = new ReflectionClass($printerClass);
+
+ if ($class->implementsInterface('PHPUnit_Framework_TestListener') &&
+ $class->isSubclassOf('PHPUnit_Util_Printer') &&
+ $class->isInstantiable()) {
+ if ($class->isSubclassOf('PHPUnit_TextUI_ResultPrinter')) {
+ return $printerClass;
+ }
+
+ $outputStream = isset($this->arguments['stderr']) ? 'php://stderr' : null;
+
+ return $class->newInstance($outputStream);
+ }
+ }
+
+ $this->showError(
+ sprintf(
+ 'Could not use "%s" as printer.',
+ $printerClass
+ )
+ );
+ }
+
+ /**
+ * Loads a bootstrap file.
+ *
+ * @param string $filename
+ */
+ protected function handleBootstrap($filename)
+ {
+ try {
+ PHPUnit_Util_Fileloader::checkAndLoad($filename);
+ } catch (PHPUnit_Framework_Exception $e) {
+ $this->showError($e->getMessage());
+ }
+ }
+
+ protected function handleSelfUpdate($upgrade = false)
+ {
+ $this->printVersionString();
+
+ if ($upgrade) {
+ print "Warning: Deprecated --self-upgrade used\n\n";
+ } else {
+ print "Warning: Deprecated --self-update used\n\n";
+ }
+
+ $localFilename = realpath($_SERVER['argv'][0]);
+
+ if (!is_writable($localFilename)) {
+ print 'No write permission to update ' . $localFilename . "\n";
+ exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT);
+ }
+
+ if (!extension_loaded('openssl')) {
+ print "The OpenSSL extension is not loaded.\n";
+ exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT);
+ }
+
+ if (!$upgrade) {
+ $remoteFilename = sprintf(
+ 'https://phar.phpunit.de/phpunit-%s.phar',
+ file_get_contents(
+ sprintf(
+ 'https://phar.phpunit.de/latest-version-of/phpunit-%s',
+ PHPUnit_Runner_Version::series()
+ )
+ )
+ );
+ } else {
+ $remoteFilename = sprintf(
+ 'https://phar.phpunit.de/phpunit%s.phar',
+ PHPUnit_Runner_Version::getReleaseChannel()
+ );
+ }
+
+ $tempFilename = tempnam(sys_get_temp_dir(), 'phpunit') . '.phar';
+
+ // Workaround for https://bugs.php.net/bug.php?id=65538
+ $caFile = dirname($tempFilename) . '/ca.pem';
+ copy(__PHPUNIT_PHAR_ROOT__ . '/ca.pem', $caFile);
+
+ print 'Updating the PHPUnit PHAR ... ';
+
+ $options = [
+ 'ssl' => [
+ 'allow_self_signed' => false,
+ 'cafile' => $caFile,
+ 'verify_peer' => true
+ ]
+ ];
+
+ file_put_contents(
+ $tempFilename,
+ file_get_contents(
+ $remoteFilename,
+ false,
+ stream_context_create($options)
+ )
+ );
+
+ chmod($tempFilename, 0777 & ~umask());
+
+ try {
+ $phar = new Phar($tempFilename);
+ unset($phar);
+ rename($tempFilename, $localFilename);
+ unlink($caFile);
+ } catch (Throwable $_e) {
+ $e = $_e;
+ } catch (Exception $_e) {
+ $e = $_e;
+ }
+
+ if (isset($e)) {
+ unlink($caFile);
+ unlink($tempFilename);
+ print " done\n\n" . $e->getMessage() . "\n";
+ exit(2);
+ }
+
+ print " done\n";
+ exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
+ }
+
+ protected function handleVersionCheck()
+ {
+ $this->printVersionString();
+
+ $latestVersion = file_get_contents('https://phar.phpunit.de/latest-version-of/phpunit');
+ $isOutdated = version_compare($latestVersion, PHPUnit_Runner_Version::id(), '>');
+
+ if ($isOutdated) {
+ print "You are not using the latest version of PHPUnit.\n";
+ print 'Use "phpunit --self-upgrade" to install PHPUnit ' . $latestVersion . "\n";
+ } else {
+ print "You are using the latest version of PHPUnit.\n";
+ }
+
+ exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
+ }
+
+ /**
+ * Show the help message.
+ */
+ protected function showHelp()
+ {
+ $this->printVersionString();
+
+ print <<<EOT
+Usage: phpunit [options] UnitTest [UnitTest.php]
+ phpunit [options] <directory>
+
+Code Coverage Options:
+
+ --coverage-clover <file> Generate code coverage report in Clover XML format.
+ --coverage-crap4j <file> Generate code coverage report in Crap4J XML format.
+ --coverage-html <dir> Generate code coverage report in HTML format.
+ --coverage-php <file> Export PHP_CodeCoverage object to file.
+ --coverage-text=<file> Generate code coverage report in text format.
+ Default: Standard output.
+ --coverage-xml <dir> Generate code coverage report in PHPUnit XML format.
+ --whitelist <dir> Whitelist <dir> for code coverage analysis.
+ --disable-coverage-ignore Disable annotations for ignoring code coverage.
+
+Logging Options:
+
+ --log-junit <file> Log test execution in JUnit XML format to file.
+ --log-teamcity <file> Log test execution in TeamCity format to file.
+ --testdox-html <file> Write agile documentation in HTML format to file.
+ --testdox-text <file> Write agile documentation in Text format to file.
+ --testdox-xml <file> Write agile documentation in XML format to file.
+ --reverse-list Print defects in reverse order
+
+Test Selection Options:
+
+ --filter <pattern> Filter which tests to run.
+ --testsuite <name> Filter which testsuite to run.
+ --group ... Only runs tests from the specified group(s).
+ --exclude-group ... Exclude tests from the specified group(s).
+ --list-groups List available test groups.
+ --list-suites List available test suites.
+ --test-suffix ... Only search for test in files with specified
+ suffix(es). Default: Test.php,.phpt
+
+Test Execution Options:
+
+ --report-useless-tests Be strict about tests that do not test anything.
+ --strict-coverage Be strict about @covers annotation usage.
+ --strict-global-state Be strict about changes to global state
+ --disallow-test-output Be strict about output during tests.
+ --disallow-resource-usage Be strict about resource usage during small tests.
+ --enforce-time-limit Enforce time limit based on test size.
+ --disallow-todo-tests Disallow @todo-annotated tests.
+
+ --process-isolation Run each test in a separate PHP process.
+ --no-globals-backup Do not backup and restore \$GLOBALS for each test.
+ --static-backup Backup and restore static attributes for each test.
+
+ --colors=<flag> Use colors in output ("never", "auto" or "always").
+ --columns <n> Number of columns to use for progress output.
+ --columns max Use maximum number of columns for progress output.
+ --stderr Write to STDERR instead of STDOUT.
+ --stop-on-error Stop execution upon first error.
+ --stop-on-failure Stop execution upon first error or failure.
+ --stop-on-warning Stop execution upon first warning.
+ --stop-on-risky Stop execution upon first risky test.
+ --stop-on-skipped Stop execution upon first skipped test.
+ --stop-on-incomplete Stop execution upon first incomplete test.
+ --fail-on-warning Treat tests with warnings as failures.
+ --fail-on-risky Treat risky tests as failures.
+ -v|--verbose Output more verbose information.
+ --debug Display debugging information during test execution.
+
+ --loader <loader> TestSuiteLoader implementation to use.
+ --repeat <times> Runs the test(s) repeatedly.
+ --teamcity Report test execution progress in TeamCity format.
+ --testdox Report test execution progress in TestDox format.
+ --testdox-group Only include tests from the specified group(s).
+ --testdox-exclude-group Exclude tests from the specified group(s).
+ --printer <printer> TestListener implementation to use.
+
+Configuration Options:
+
+ --bootstrap <file> A "bootstrap" PHP file that is run before the tests.
+ -c|--configuration <file> Read configuration from XML file.
+ --no-configuration Ignore default configuration file (phpunit.xml).
+ --no-coverage Ignore code coverage configuration.
+ --no-extensions Do not load PHPUnit extensions.
+ --include-path <path(s)> Prepend PHP's include_path with given path(s).
+ -d key[=value] Sets a php.ini value.
+ --generate-configuration Generate configuration file with suggested settings.
+
+Miscellaneous Options:
+
+ -h|--help Prints this usage information.
+ --version Prints the version and exits.
+ --atleast-version <min> Checks that version is greater than min and exits.
+
+EOT;
+
+ if (defined('__PHPUNIT_PHAR__')) {
+ print "\n --check-version Check whether PHPUnit is the latest version.";
+ }
+ }
+
+ /**
+ * Custom callback for test suite discovery.
+ */
+ protected function handleCustomTestSuite()
+ {
+ }
+
+ private function printVersionString()
+ {
+ if ($this->versionStringPrinted) {
+ return;
+ }
+
+ print PHPUnit_Runner_Version::getVersionString() . "\n\n";
+
+ $this->versionStringPrinted = true;
+ }
+
+ /**
+ * @param string $message
+ */
+ private function showError($message)
+ {
+ $this->printVersionString();
+
+ print $message . "\n";
+
+ exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT);
+ }
+
+ /**
+ * @param string $directory
+ */
+ private function handleExtensions($directory)
+ {
+ $facade = new File_Iterator_Facade;
+
+ foreach ($facade->getFilesAsArray($directory, '.phar') as $file) {
+ require $file;
+
+ $this->arguments['loadedExtensions'][] = $file;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/TextUI/ResultPrinter.php b/vendor/phpunit/phpunit/src/TextUI/ResultPrinter.php
new file mode 100644
index 0000000..b279993
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/TextUI/ResultPrinter.php
@@ -0,0 +1,680 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use SebastianBergmann\Environment\Console;
+
+/**
+ * Prints the result of a TextUI TestRunner run.
+ */
+class PHPUnit_TextUI_ResultPrinter extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
+{
+ const EVENT_TEST_START = 0;
+ const EVENT_TEST_END = 1;
+ const EVENT_TESTSUITE_START = 2;
+ const EVENT_TESTSUITE_END = 3;
+
+ const COLOR_NEVER = 'never';
+ const COLOR_AUTO = 'auto';
+ const COLOR_ALWAYS = 'always';
+ const COLOR_DEFAULT = self::COLOR_NEVER;
+
+ /**
+ * @var array
+ */
+ private static $ansiCodes = [
+ 'bold' => 1,
+ 'fg-black' => 30,
+ 'fg-red' => 31,
+ 'fg-green' => 32,
+ 'fg-yellow' => 33,
+ 'fg-blue' => 34,
+ 'fg-magenta' => 35,
+ 'fg-cyan' => 36,
+ 'fg-white' => 37,
+ 'bg-black' => 40,
+ 'bg-red' => 41,
+ 'bg-green' => 42,
+ 'bg-yellow' => 43,
+ 'bg-blue' => 44,
+ 'bg-magenta' => 45,
+ 'bg-cyan' => 46,
+ 'bg-white' => 47
+ ];
+
+ /**
+ * @var int
+ */
+ protected $column = 0;
+
+ /**
+ * @var int
+ */
+ protected $maxColumn;
+
+ /**
+ * @var bool
+ */
+ protected $lastTestFailed = false;
+
+ /**
+ * @var int
+ */
+ protected $numAssertions = 0;
+
+ /**
+ * @var int
+ */
+ protected $numTests = -1;
+
+ /**
+ * @var int
+ */
+ protected $numTestsRun = 0;
+
+ /**
+ * @var int
+ */
+ protected $numTestsWidth;
+
+ /**
+ * @var bool
+ */
+ protected $colors = false;
+
+ /**
+ * @var bool
+ */
+ protected $debug = false;
+
+ /**
+ * @var bool
+ */
+ protected $verbose = false;
+
+ /**
+ * @var int
+ */
+ private $numberOfColumns;
+
+ /**
+ * @var bool
+ */
+ private $reverse = false;
+
+ /**
+ * @var bool
+ */
+ private $defectListPrinted = false;
+
+ /**
+ * Constructor.
+ *
+ * @param mixed $out
+ * @param bool $verbose
+ * @param string $colors
+ * @param bool $debug
+ * @param int|string $numberOfColumns
+ * @param bool $reverse
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function __construct($out = null, $verbose = false, $colors = self::COLOR_DEFAULT, $debug = false, $numberOfColumns = 80, $reverse = false)
+ {
+ parent::__construct($out);
+
+ if (!is_bool($verbose)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'boolean');
+ }
+
+ $availableColors = [self::COLOR_NEVER, self::COLOR_AUTO, self::COLOR_ALWAYS];
+
+ if (!in_array($colors, $availableColors)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(
+ 3,
+ vsprintf('value from "%s", "%s" or "%s"', $availableColors)
+ );
+ }
+
+ if (!is_bool($debug)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(4, 'boolean');
+ }
+
+ if (!is_int($numberOfColumns) && $numberOfColumns != 'max') {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(5, 'integer or "max"');
+ }
+
+ if (!is_bool($reverse)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(6, 'boolean');
+ }
+
+ $console = new Console;
+ $maxNumberOfColumns = $console->getNumberOfColumns();
+
+ if ($numberOfColumns == 'max' || $numberOfColumns > $maxNumberOfColumns) {
+ $numberOfColumns = $maxNumberOfColumns;
+ }
+
+ $this->numberOfColumns = $numberOfColumns;
+ $this->verbose = $verbose;
+ $this->debug = $debug;
+ $this->reverse = $reverse;
+
+ if ($colors === self::COLOR_AUTO && $console->hasColorSupport()) {
+ $this->colors = true;
+ } else {
+ $this->colors = (self::COLOR_ALWAYS === $colors);
+ }
+ }
+
+ /**
+ * @param PHPUnit_Framework_TestResult $result
+ */
+ public function printResult(PHPUnit_Framework_TestResult $result)
+ {
+ $this->printHeader();
+ $this->printErrors($result);
+ $this->printWarnings($result);
+ $this->printFailures($result);
+
+ if ($this->verbose) {
+ $this->printRisky($result);
+ $this->printIncompletes($result);
+ $this->printSkipped($result);
+ }
+
+ $this->printFooter($result);
+ }
+
+ /**
+ * @param array $defects
+ * @param string $type
+ */
+ protected function printDefects(array $defects, $type)
+ {
+ $count = count($defects);
+
+ if ($count == 0) {
+ return;
+ }
+
+ if ($this->defectListPrinted) {
+ $this->write("\n--\n\n");
+ }
+
+ $this->write(
+ sprintf(
+ "There %s %d %s%s:\n",
+ ($count == 1) ? 'was' : 'were',
+ $count,
+ $type,
+ ($count == 1) ? '' : 's'
+ )
+ );
+
+ $i = 1;
+
+ if ($this->reverse) {
+ $defects = array_reverse($defects);
+ }
+
+ foreach ($defects as $defect) {
+ $this->printDefect($defect, $i++);
+ }
+
+ $this->defectListPrinted = true;
+ }
+
+ /**
+ * @param PHPUnit_Framework_TestFailure $defect
+ * @param int $count
+ */
+ protected function printDefect(PHPUnit_Framework_TestFailure $defect, $count)
+ {
+ $this->printDefectHeader($defect, $count);
+ $this->printDefectTrace($defect);
+ }
+
+ /**
+ * @param PHPUnit_Framework_TestFailure $defect
+ * @param int $count
+ */
+ protected function printDefectHeader(PHPUnit_Framework_TestFailure $defect, $count)
+ {
+ $this->write(
+ sprintf(
+ "\n%d) %s\n",
+ $count,
+ $defect->getTestName()
+ )
+ );
+ }
+
+ /**
+ * @param PHPUnit_Framework_TestFailure $defect
+ */
+ protected function printDefectTrace(PHPUnit_Framework_TestFailure $defect)
+ {
+ $e = $defect->thrownException();
+ $this->write((string) $e);
+
+ while ($e = $e->getPrevious()) {
+ $this->write("\nCaused by\n" . $e);
+ }
+ }
+
+ /**
+ * @param PHPUnit_Framework_TestResult $result
+ */
+ protected function printErrors(PHPUnit_Framework_TestResult $result)
+ {
+ $this->printDefects($result->errors(), 'error');
+ }
+
+ /**
+ * @param PHPUnit_Framework_TestResult $result
+ */
+ protected function printFailures(PHPUnit_Framework_TestResult $result)
+ {
+ $this->printDefects($result->failures(), 'failure');
+ }
+
+ /**
+ * @param PHPUnit_Framework_TestResult $result
+ */
+ protected function printWarnings(PHPUnit_Framework_TestResult $result)
+ {
+ $this->printDefects($result->warnings(), 'warning');
+ }
+
+ /**
+ * @param PHPUnit_Framework_TestResult $result
+ */
+ protected function printIncompletes(PHPUnit_Framework_TestResult $result)
+ {
+ $this->printDefects($result->notImplemented(), 'incomplete test');
+ }
+
+ /**
+ * @param PHPUnit_Framework_TestResult $result
+ */
+ protected function printRisky(PHPUnit_Framework_TestResult $result)
+ {
+ $this->printDefects($result->risky(), 'risky test');
+ }
+
+ /**
+ * @param PHPUnit_Framework_TestResult $result
+ */
+ protected function printSkipped(PHPUnit_Framework_TestResult $result)
+ {
+ $this->printDefects($result->skipped(), 'skipped test');
+ }
+
+ protected function printHeader()
+ {
+ $this->write("\n\n" . PHP_Timer::resourceUsage() . "\n\n");
+ }
+
+ /**
+ * @param PHPUnit_Framework_TestResult $result
+ */
+ protected function printFooter(PHPUnit_Framework_TestResult $result)
+ {
+ if (count($result) === 0) {
+ $this->writeWithColor(
+ 'fg-black, bg-yellow',
+ 'No tests executed!'
+ );
+
+ return;
+ }
+
+ if ($result->wasSuccessful() &&
+ $result->allHarmless() &&
+ $result->allCompletelyImplemented() &&
+ $result->noneSkipped()) {
+ $this->writeWithColor(
+ 'fg-black, bg-green',
+ sprintf(
+ 'OK (%d test%s, %d assertion%s)',
+ count($result),
+ (count($result) == 1) ? '' : 's',
+ $this->numAssertions,
+ ($this->numAssertions == 1) ? '' : 's'
+ )
+ );
+ } else {
+ if ($result->wasSuccessful()) {
+ $color = 'fg-black, bg-yellow';
+
+ if ($this->verbose) {
+ $this->write("\n");
+ }
+
+ $this->writeWithColor(
+ $color,
+ 'OK, but incomplete, skipped, or risky tests!'
+ );
+ } else {
+ $this->write("\n");
+
+ if ($result->errorCount()) {
+ $color = 'fg-white, bg-red';
+
+ $this->writeWithColor(
+ $color,
+ 'ERRORS!'
+ );
+ } elseif ($result->failureCount()) {
+ $color = 'fg-white, bg-red';
+
+ $this->writeWithColor(
+ $color,
+ 'FAILURES!'
+ );
+ } elseif ($result->warningCount()) {
+ $color = 'fg-black, bg-yellow';
+
+ $this->writeWithColor(
+ $color,
+ 'WARNINGS!'
+ );
+ }
+ }
+
+ $this->writeCountString(count($result), 'Tests', $color, true);
+ $this->writeCountString($this->numAssertions, 'Assertions', $color, true);
+ $this->writeCountString($result->errorCount(), 'Errors', $color);
+ $this->writeCountString($result->failureCount(), 'Failures', $color);
+ $this->writeCountString($result->warningCount(), 'Warnings', $color);
+ $this->writeCountString($result->skippedCount(), 'Skipped', $color);
+ $this->writeCountString($result->notImplementedCount(), 'Incomplete', $color);
+ $this->writeCountString($result->riskyCount(), 'Risky', $color);
+ $this->writeWithColor($color, '.', true);
+ }
+ }
+
+ public function printWaitPrompt()
+ {
+ $this->write("\n<RETURN> to continue\n");
+ }
+
+ /**
+ * An error occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->writeProgressWithColor('fg-red, bold', 'E');
+ $this->lastTestFailed = true;
+ }
+
+ /**
+ * A failure occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_AssertionFailedError $e
+ * @param float $time
+ */
+ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
+ {
+ $this->writeProgressWithColor('bg-red, fg-white', 'F');
+ $this->lastTestFailed = true;
+ }
+
+ /**
+ * A warning occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_Warning $e
+ * @param float $time
+ */
+ public function addWarning(PHPUnit_Framework_Test $test, PHPUnit_Framework_Warning $e, $time)
+ {
+ $this->writeProgressWithColor('fg-yellow, bold', 'W');
+ $this->lastTestFailed = true;
+ }
+
+ /**
+ * Incomplete test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->writeProgressWithColor('fg-yellow, bold', 'I');
+ $this->lastTestFailed = true;
+ }
+
+ /**
+ * Risky test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->writeProgressWithColor('fg-yellow, bold', 'R');
+ $this->lastTestFailed = true;
+ }
+
+ /**
+ * Skipped test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->writeProgressWithColor('fg-cyan, bold', 'S');
+ $this->lastTestFailed = true;
+ }
+
+ /**
+ * A testsuite started.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ if ($this->numTests == -1) {
+ $this->numTests = count($suite);
+ $this->numTestsWidth = strlen((string) $this->numTests);
+ $this->maxColumn = $this->numberOfColumns - strlen(' / (XXX%)') - (2 * $this->numTestsWidth);
+ }
+ }
+
+ /**
+ * A testsuite ended.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ }
+
+ /**
+ * A test started.
+ *
+ * @param PHPUnit_Framework_Test $test
+ */
+ public function startTest(PHPUnit_Framework_Test $test)
+ {
+ if ($this->debug) {
+ $this->write(
+ sprintf(
+ "\nStarting test '%s'.\n",
+ PHPUnit_Util_Test::describe($test)
+ )
+ );
+ }
+ }
+
+ /**
+ * A test ended.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param float $time
+ */
+ public function endTest(PHPUnit_Framework_Test $test, $time)
+ {
+ if (!$this->lastTestFailed) {
+ $this->writeProgress('.');
+ }
+
+ if ($test instanceof PHPUnit_Framework_TestCase) {
+ $this->numAssertions += $test->getNumAssertions();
+ } elseif ($test instanceof PHPUnit_Extensions_PhptTestCase) {
+ $this->numAssertions++;
+ }
+
+ $this->lastTestFailed = false;
+
+ if ($test instanceof PHPUnit_Framework_TestCase) {
+ if (!$test->hasExpectationOnOutput()) {
+ $this->write($test->getActualOutput());
+ }
+ }
+ }
+
+ /**
+ * @param string $progress
+ */
+ protected function writeProgress($progress)
+ {
+ $this->write($progress);
+ $this->column++;
+ $this->numTestsRun++;
+
+ if ($this->column == $this->maxColumn
+ || $this->numTestsRun == $this->numTests
+ ) {
+ if ($this->numTestsRun == $this->numTests) {
+ $this->write(str_repeat(' ', $this->maxColumn - $this->column));
+ }
+
+ $this->write(
+ sprintf(
+ ' %' . $this->numTestsWidth . 'd / %' .
+ $this->numTestsWidth . 'd (%3s%%)',
+ $this->numTestsRun,
+ $this->numTests,
+ floor(($this->numTestsRun / $this->numTests) * 100)
+ )
+ );
+
+ if ($this->column == $this->maxColumn) {
+ $this->writeNewLine();
+ }
+ }
+ }
+
+ protected function writeNewLine()
+ {
+ $this->column = 0;
+ $this->write("\n");
+ }
+
+ /**
+ * Formats a buffer with a specified ANSI color sequence if colors are
+ * enabled.
+ *
+ * @param string $color
+ * @param string $buffer
+ *
+ * @return string
+ */
+ protected function formatWithColor($color, $buffer)
+ {
+ if (!$this->colors) {
+ return $buffer;
+ }
+
+ $codes = array_map('trim', explode(',', $color));
+ $lines = explode("\n", $buffer);
+ $padding = max(array_map('strlen', $lines));
+ $styles = [];
+
+ foreach ($codes as $code) {
+ $styles[] = self::$ansiCodes[$code];
+ }
+
+ $style = sprintf("\x1b[%sm", implode(';', $styles));
+
+ $styledLines = [];
+
+ foreach ($lines as $line) {
+ $styledLines[] = $style . str_pad($line, $padding) . "\x1b[0m";
+ }
+
+ return implode("\n", $styledLines);
+ }
+
+ /**
+ * Writes a buffer out with a color sequence if colors are enabled.
+ *
+ * @param string $color
+ * @param string $buffer
+ * @param bool $lf
+ */
+ protected function writeWithColor($color, $buffer, $lf = true)
+ {
+ $this->write($this->formatWithColor($color, $buffer));
+
+ if ($lf) {
+ $this->write("\n");
+ }
+ }
+
+ /**
+ * Writes progress with a color sequence if colors are enabled.
+ *
+ * @param string $color
+ * @param string $buffer
+ */
+ protected function writeProgressWithColor($color, $buffer)
+ {
+ $buffer = $this->formatWithColor($color, $buffer);
+ $this->writeProgress($buffer);
+ }
+
+ /**
+ * @param int $count
+ * @param string $name
+ * @param string $color
+ * @param bool $always
+ */
+ private function writeCountString($count, $name, $color, $always = false)
+ {
+ static $first = true;
+
+ if ($always || $count > 0) {
+ $this->writeWithColor(
+ $color,
+ sprintf(
+ '%s%s: %d',
+ !$first ? ', ' : '',
+ $name,
+ $count
+ ),
+ false
+ );
+
+ $first = false;
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/TextUI/TestRunner.php b/vendor/phpunit/phpunit/src/TextUI/TestRunner.php
new file mode 100644
index 0000000..5e17a25
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/TextUI/TestRunner.php
@@ -0,0 +1,1142 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use SebastianBergmann\CodeCoverage\CodeCoverage;
+use SebastianBergmann\CodeCoverage\Exception as CodeCoverageException;
+use SebastianBergmann\CodeCoverage\Filter as CodeCoverageFilter;
+use SebastianBergmann\CodeCoverage\Report\Clover as CloverReport;
+use SebastianBergmann\CodeCoverage\Report\Crap4j as Crap4jReport;
+use SebastianBergmann\CodeCoverage\Report\Html\Facade as HtmlReport;
+use SebastianBergmann\CodeCoverage\Report\PHP as PhpReport;
+use SebastianBergmann\CodeCoverage\Report\Text as TextReport;
+use SebastianBergmann\CodeCoverage\Report\Xml\Facade as XmlReport;
+use SebastianBergmann\Environment\Runtime;
+
+/**
+ * A TestRunner for the Command Line Interface (CLI)
+ * PHP SAPI Module.
+ */
+class PHPUnit_TextUI_TestRunner extends PHPUnit_Runner_BaseTestRunner
+{
+ const SUCCESS_EXIT = 0;
+ const FAILURE_EXIT = 1;
+ const EXCEPTION_EXIT = 2;
+
+ /**
+ * @var CodeCoverageFilter
+ */
+ protected $codeCoverageFilter;
+
+ /**
+ * @var PHPUnit_Runner_TestSuiteLoader
+ */
+ protected $loader = null;
+
+ /**
+ * @var PHPUnit_TextUI_ResultPrinter
+ */
+ protected $printer = null;
+
+ /**
+ * @var bool
+ */
+ protected static $versionStringPrinted = false;
+
+ /**
+ * @var Runtime
+ */
+ private $runtime;
+
+ /**
+ * @var bool
+ */
+ private $messagePrinted = false;
+
+ /**
+ * @param PHPUnit_Runner_TestSuiteLoader $loader
+ * @param CodeCoverageFilter $filter
+ */
+ public function __construct(PHPUnit_Runner_TestSuiteLoader $loader = null, CodeCoverageFilter $filter = null)
+ {
+ if ($filter === null) {
+ $filter = new CodeCoverageFilter;
+ }
+
+ $this->codeCoverageFilter = $filter;
+ $this->loader = $loader;
+ $this->runtime = new Runtime;
+ }
+
+ /**
+ * @param PHPUnit_Framework_Test|ReflectionClass $test
+ * @param array $arguments
+ *
+ * @return PHPUnit_Framework_TestResult
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public static function run($test, array $arguments = [])
+ {
+ if ($test instanceof ReflectionClass) {
+ $test = new PHPUnit_Framework_TestSuite($test);
+ }
+
+ if ($test instanceof PHPUnit_Framework_Test) {
+ $aTestRunner = new self;
+
+ return $aTestRunner->doRun(
+ $test,
+ $arguments
+ );
+ } else {
+ throw new PHPUnit_Framework_Exception(
+ 'No test case or test suite found.'
+ );
+ }
+ }
+
+ /**
+ * @return PHPUnit_Framework_TestResult
+ */
+ protected function createTestResult()
+ {
+ return new PHPUnit_Framework_TestResult;
+ }
+
+ /**
+ * @param PHPUnit_Framework_TestSuite $suite
+ * @param array $arguments
+ */
+ private function processSuiteFilters(PHPUnit_Framework_TestSuite $suite, array $arguments)
+ {
+ if (!$arguments['filter'] &&
+ empty($arguments['groups']) &&
+ empty($arguments['excludeGroups'])) {
+ return;
+ }
+
+ $filterFactory = new PHPUnit_Runner_Filter_Factory();
+
+ if (!empty($arguments['excludeGroups'])) {
+ $filterFactory->addFilter(
+ new ReflectionClass('PHPUnit_Runner_Filter_Group_Exclude'),
+ $arguments['excludeGroups']
+ );
+ }
+
+ if (!empty($arguments['groups'])) {
+ $filterFactory->addFilter(
+ new ReflectionClass('PHPUnit_Runner_Filter_Group_Include'),
+ $arguments['groups']
+ );
+ }
+
+ if ($arguments['filter']) {
+ $filterFactory->addFilter(
+ new ReflectionClass('PHPUnit_Runner_Filter_Test'),
+ $arguments['filter']
+ );
+ }
+ $suite->injectFilter($filterFactory);
+ }
+
+ /**
+ * @param PHPUnit_Framework_Test $suite
+ * @param array $arguments
+ * @param bool $exit
+ *
+ * @return PHPUnit_Framework_TestResult
+ */
+ public function doRun(PHPUnit_Framework_Test $suite, array $arguments = [], $exit = true)
+ {
+ if (isset($arguments['configuration'])) {
+ $GLOBALS['__PHPUNIT_CONFIGURATION_FILE'] = $arguments['configuration'];
+ }
+
+ $this->handleConfiguration($arguments);
+
+ $this->processSuiteFilters($suite, $arguments);
+
+ if (isset($arguments['bootstrap'])) {
+ $GLOBALS['__PHPUNIT_BOOTSTRAP'] = $arguments['bootstrap'];
+ }
+
+ if ($arguments['backupGlobals'] === false) {
+ $suite->setBackupGlobals(false);
+ }
+
+ if ($arguments['backupStaticAttributes'] === true) {
+ $suite->setBackupStaticAttributes(true);
+ }
+
+ if ($arguments['beStrictAboutChangesToGlobalState'] === true) {
+ $suite->setBeStrictAboutChangesToGlobalState(true);
+ }
+
+ if (is_int($arguments['repeat'])) {
+ $test = new PHPUnit_Extensions_RepeatedTest(
+ $suite,
+ $arguments['repeat'],
+ $arguments['processIsolation']
+ );
+
+ $suite = new PHPUnit_Framework_TestSuite();
+ $suite->addTest($test);
+ }
+
+ $result = $this->createTestResult();
+
+ if (!$arguments['convertErrorsToExceptions']) {
+ $result->convertErrorsToExceptions(false);
+ }
+
+ if (!$arguments['convertNoticesToExceptions']) {
+ PHPUnit_Framework_Error_Notice::$enabled = false;
+ }
+
+ if (!$arguments['convertWarningsToExceptions']) {
+ PHPUnit_Framework_Error_Warning::$enabled = false;
+ }
+
+ if ($arguments['stopOnError']) {
+ $result->stopOnError(true);
+ }
+
+ if ($arguments['stopOnFailure']) {
+ $result->stopOnFailure(true);
+ }
+
+ if ($arguments['stopOnWarning']) {
+ $result->stopOnWarning(true);
+ }
+
+ if ($arguments['stopOnIncomplete']) {
+ $result->stopOnIncomplete(true);
+ }
+
+ if ($arguments['stopOnRisky']) {
+ $result->stopOnRisky(true);
+ }
+
+ if ($arguments['stopOnSkipped']) {
+ $result->stopOnSkipped(true);
+ }
+
+ if ($arguments['registerMockObjectsFromTestArgumentsRecursively']) {
+ $result->setRegisterMockObjectsFromTestArgumentsRecursively(true);
+ }
+
+ if ($this->printer === null) {
+ if (isset($arguments['printer']) &&
+ $arguments['printer'] instanceof PHPUnit_Util_Printer) {
+ $this->printer = $arguments['printer'];
+ } else {
+ $printerClass = 'PHPUnit_TextUI_ResultPrinter';
+
+ if (isset($arguments['printer']) &&
+ is_string($arguments['printer']) &&
+ class_exists($arguments['printer'], false)) {
+ $class = new ReflectionClass($arguments['printer']);
+
+ if ($class->isSubclassOf('PHPUnit_TextUI_ResultPrinter')) {
+ $printerClass = $arguments['printer'];
+ }
+ }
+
+ $this->printer = new $printerClass(
+ (isset($arguments['stderr']) && $arguments['stderr'] === true) ? 'php://stderr' : null,
+ $arguments['verbose'],
+ $arguments['colors'],
+ $arguments['debug'],
+ $arguments['columns'],
+ $arguments['reverseList']
+ );
+ }
+ }
+
+ if (!$this->printer instanceof PHPUnit_Util_Log_TAP) {
+ $this->printer->write(
+ PHPUnit_Runner_Version::getVersionString() . "\n"
+ );
+
+ self::$versionStringPrinted = true;
+
+ if ($arguments['verbose']) {
+ $runtime = $this->runtime->getNameWithVersion();
+
+ if ($this->runtime->hasXdebug()) {
+ $runtime .= sprintf(
+ ' with Xdebug %s',
+ phpversion('xdebug')
+ );
+ }
+
+ $this->writeMessage('Runtime', $runtime);
+
+ if (isset($arguments['configuration'])) {
+ $this->writeMessage(
+ 'Configuration',
+ $arguments['configuration']->getFilename()
+ );
+ }
+
+ foreach ($arguments['loadedExtensions'] as $extension) {
+ $this->writeMessage(
+ 'Extension',
+ $extension
+ );
+ }
+
+ foreach ($arguments['notLoadedExtensions'] as $extension) {
+ $this->writeMessage(
+ 'Extension',
+ $extension
+ );
+ }
+ }
+
+ if (isset($arguments['deprecatedCheckForUnintentionallyCoveredCodeSettingUsed'])) {
+ $this->writeMessage('Warning', 'Deprecated configuration setting "checkForUnintentionallyCoveredCode" used');
+ }
+
+ if (isset($arguments['tapLogfile'])) {
+ $this->writeMessage('Warning', 'Deprecated TAP test listener used');
+ }
+
+ if (isset($arguments['jsonLogfile'])) {
+ $this->writeMessage('Warning', 'Deprecated JSON test listener used');
+ }
+ }
+
+ foreach ($arguments['listeners'] as $listener) {
+ $result->addListener($listener);
+ }
+
+ $result->addListener($this->printer);
+
+ if (isset($arguments['testdoxHTMLFile'])) {
+ $result->addListener(
+ new PHPUnit_Util_TestDox_ResultPrinter_HTML(
+ $arguments['testdoxHTMLFile'],
+ $arguments['testdoxGroups'],
+ $arguments['testdoxExcludeGroups']
+ )
+ );
+ }
+
+ if (isset($arguments['testdoxTextFile'])) {
+ $result->addListener(
+ new PHPUnit_Util_TestDox_ResultPrinter_Text(
+ $arguments['testdoxTextFile'],
+ $arguments['testdoxGroups'],
+ $arguments['testdoxExcludeGroups']
+ )
+ );
+ }
+
+ if (isset($arguments['testdoxXMLFile'])) {
+ $result->addListener(
+ new PHPUnit_Util_TestDox_ResultPrinter_XML(
+ $arguments['testdoxXMLFile']
+ )
+ );
+ }
+
+ $codeCoverageReports = 0;
+
+ if (isset($arguments['coverageClover'])) {
+ $codeCoverageReports++;
+ }
+
+ if (isset($arguments['coverageCrap4J'])) {
+ $codeCoverageReports++;
+ }
+
+ if (isset($arguments['coverageHtml'])) {
+ $codeCoverageReports++;
+ }
+
+ if (isset($arguments['coveragePHP'])) {
+ $codeCoverageReports++;
+ }
+
+ if (isset($arguments['coverageText'])) {
+ $codeCoverageReports++;
+ }
+
+ if (isset($arguments['coverageXml'])) {
+ $codeCoverageReports++;
+ }
+
+ if (isset($arguments['noCoverage'])) {
+ $codeCoverageReports = 0;
+ }
+
+ if ($codeCoverageReports > 0 && !$this->runtime->canCollectCodeCoverage()) {
+ $this->writeMessage('Error', 'No code coverage driver is available');
+
+ $codeCoverageReports = 0;
+ }
+
+ if (!$this->printer instanceof PHPUnit_Util_Log_TAP) {
+ $this->printer->write("\n");
+ }
+
+ if ($codeCoverageReports > 0) {
+ $codeCoverage = new CodeCoverage(
+ null,
+ $this->codeCoverageFilter
+ );
+
+ $codeCoverage->setUnintentionallyCoveredSubclassesWhitelist(
+ [SebastianBergmann\Comparator\Comparator::class]
+ );
+
+ $codeCoverage->setCheckForUnintentionallyCoveredCode(
+ $arguments['strictCoverage']
+ );
+
+ $codeCoverage->setCheckForMissingCoversAnnotation(
+ $arguments['strictCoverage']
+ );
+
+ if (isset($arguments['forceCoversAnnotation'])) {
+ $codeCoverage->setForceCoversAnnotation(
+ $arguments['forceCoversAnnotation']
+ );
+ }
+
+ if (isset($arguments['disableCodeCoverageIgnore'])) {
+ $codeCoverage->setDisableIgnoredLines(true);
+ }
+
+ if (isset($arguments['whitelist'])) {
+ $this->codeCoverageFilter->addDirectoryToWhitelist($arguments['whitelist']);
+ }
+
+ if (isset($arguments['configuration'])) {
+ $filterConfiguration = $arguments['configuration']->getFilterConfiguration();
+
+ $codeCoverage->setAddUncoveredFilesFromWhitelist(
+ $filterConfiguration['whitelist']['addUncoveredFilesFromWhitelist']
+ );
+
+ $codeCoverage->setProcessUncoveredFilesFromWhitelist(
+ $filterConfiguration['whitelist']['processUncoveredFilesFromWhitelist']
+ );
+
+ foreach ($filterConfiguration['whitelist']['include']['directory'] as $dir) {
+ $this->codeCoverageFilter->addDirectoryToWhitelist(
+ $dir['path'],
+ $dir['suffix'],
+ $dir['prefix']
+ );
+ }
+
+ foreach ($filterConfiguration['whitelist']['include']['file'] as $file) {
+ $this->codeCoverageFilter->addFileToWhitelist($file);
+ }
+
+ foreach ($filterConfiguration['whitelist']['exclude']['directory'] as $dir) {
+ $this->codeCoverageFilter->removeDirectoryFromWhitelist(
+ $dir['path'],
+ $dir['suffix'],
+ $dir['prefix']
+ );
+ }
+
+ foreach ($filterConfiguration['whitelist']['exclude']['file'] as $file) {
+ $this->codeCoverageFilter->removeFileFromWhitelist($file);
+ }
+ }
+
+ if (!$this->codeCoverageFilter->hasWhitelist()) {
+ $this->writeMessage('Error', 'No whitelist configured, no code coverage will be generated');
+
+ $codeCoverageReports = 0;
+
+ unset($codeCoverage);
+ }
+ }
+
+ if (isset($codeCoverage)) {
+ $result->setCodeCoverage($codeCoverage);
+
+ if ($codeCoverageReports > 1 && isset($arguments['cacheTokens'])) {
+ $codeCoverage->setCacheTokens($arguments['cacheTokens']);
+ }
+ }
+
+ if (isset($arguments['jsonLogfile'])) {
+ $result->addListener(
+ new PHPUnit_Util_Log_JSON($arguments['jsonLogfile'])
+ );
+ }
+
+ if (isset($arguments['tapLogfile'])) {
+ $result->addListener(
+ new PHPUnit_Util_Log_TAP($arguments['tapLogfile'])
+ );
+ }
+
+ if (isset($arguments['teamcityLogfile'])) {
+ $result->addListener(
+ new PHPUnit_Util_Log_TeamCity($arguments['teamcityLogfile'])
+ );
+ }
+
+ if (isset($arguments['junitLogfile'])) {
+ $result->addListener(
+ new PHPUnit_Util_Log_JUnit(
+ $arguments['junitLogfile'],
+ $arguments['logIncompleteSkipped']
+ )
+ );
+ }
+
+ $result->beStrictAboutTestsThatDoNotTestAnything($arguments['reportUselessTests']);
+ $result->beStrictAboutOutputDuringTests($arguments['disallowTestOutput']);
+ $result->beStrictAboutTodoAnnotatedTests($arguments['disallowTodoAnnotatedTests']);
+ $result->beStrictAboutResourceUsageDuringSmallTests($arguments['beStrictAboutResourceUsageDuringSmallTests']);
+ $result->enforceTimeLimit($arguments['enforceTimeLimit']);
+ $result->setTimeoutForSmallTests($arguments['timeoutForSmallTests']);
+ $result->setTimeoutForMediumTests($arguments['timeoutForMediumTests']);
+ $result->setTimeoutForLargeTests($arguments['timeoutForLargeTests']);
+
+ if ($suite instanceof PHPUnit_Framework_TestSuite) {
+ $suite->setRunTestInSeparateProcess($arguments['processIsolation']);
+ }
+
+ $suite->run($result);
+
+ unset($suite);
+ $result->flushListeners();
+
+ if ($this->printer instanceof PHPUnit_TextUI_ResultPrinter) {
+ $this->printer->printResult($result);
+ }
+
+ if (isset($codeCoverage)) {
+ if (isset($arguments['coverageClover'])) {
+ $this->printer->write(
+ "\nGenerating code coverage report in Clover XML format ..."
+ );
+
+ try {
+ $writer = new CloverReport();
+ $writer->process($codeCoverage, $arguments['coverageClover']);
+
+ $this->printer->write(" done\n");
+ unset($writer);
+ } catch (CodeCoverageException $e) {
+ $this->printer->write(
+ " failed\n" . $e->getMessage() . "\n"
+ );
+ }
+ }
+
+ if (isset($arguments['coverageCrap4J'])) {
+ $this->printer->write(
+ "\nGenerating Crap4J report XML file ..."
+ );
+
+ try {
+ $writer = new Crap4jReport($arguments['crap4jThreshold']);
+ $writer->process($codeCoverage, $arguments['coverageCrap4J']);
+
+ $this->printer->write(" done\n");
+ unset($writer);
+ } catch (CodeCoverageException $e) {
+ $this->printer->write(
+ " failed\n" . $e->getMessage() . "\n"
+ );
+ }
+ }
+
+ if (isset($arguments['coverageHtml'])) {
+ $this->printer->write(
+ "\nGenerating code coverage report in HTML format ..."
+ );
+
+ try {
+ $writer = new HtmlReport(
+ $arguments['reportLowUpperBound'],
+ $arguments['reportHighLowerBound'],
+ sprintf(
+ ' and <a href="https://phpunit.de/">PHPUnit %s</a>',
+ PHPUnit_Runner_Version::id()
+ )
+ );
+
+ $writer->process($codeCoverage, $arguments['coverageHtml']);
+
+ $this->printer->write(" done\n");
+ unset($writer);
+ } catch (CodeCoverageException $e) {
+ $this->printer->write(
+ " failed\n" . $e->getMessage() . "\n"
+ );
+ }
+ }
+
+ if (isset($arguments['coveragePHP'])) {
+ $this->printer->write(
+ "\nGenerating code coverage report in PHP format ..."
+ );
+
+ try {
+ $writer = new PhpReport();
+ $writer->process($codeCoverage, $arguments['coveragePHP']);
+
+ $this->printer->write(" done\n");
+ unset($writer);
+ } catch (CodeCoverageException $e) {
+ $this->printer->write(
+ " failed\n" . $e->getMessage() . "\n"
+ );
+ }
+ }
+
+ if (isset($arguments['coverageText'])) {
+ if ($arguments['coverageText'] == 'php://stdout') {
+ $outputStream = $this->printer;
+ $colors = $arguments['colors'] && $arguments['colors'] != PHPUnit_TextUI_ResultPrinter::COLOR_NEVER;
+ } else {
+ $outputStream = new PHPUnit_Util_Printer($arguments['coverageText']);
+ $colors = false;
+ }
+
+ $processor = new TextReport(
+ $arguments['reportLowUpperBound'],
+ $arguments['reportHighLowerBound'],
+ $arguments['coverageTextShowUncoveredFiles'],
+ $arguments['coverageTextShowOnlySummary']
+ );
+
+ $outputStream->write(
+ $processor->process($codeCoverage, $colors)
+ );
+ }
+
+ if (isset($arguments['coverageXml'])) {
+ $this->printer->write(
+ "\nGenerating code coverage report in PHPUnit XML format ..."
+ );
+
+ try {
+ $writer = new XmlReport;
+ $writer->process($codeCoverage, $arguments['coverageXml']);
+
+ $this->printer->write(" done\n");
+ unset($writer);
+ } catch (CodeCoverageException $e) {
+ $this->printer->write(
+ " failed\n" . $e->getMessage() . "\n"
+ );
+ }
+ }
+ }
+
+ if ($exit) {
+ if ($result->wasSuccessful(false)) {
+ if ($arguments['failOnRisky'] && !$result->allHarmless()) {
+ exit(self::FAILURE_EXIT);
+ }
+
+ if ($arguments['failOnWarning'] && $result->warningCount() > 0) {
+ exit(self::FAILURE_EXIT);
+ }
+
+ exit(self::SUCCESS_EXIT);
+ }
+
+ if ($result->errorCount() > 0) {
+ exit(self::EXCEPTION_EXIT);
+ }
+
+ if ($result->failureCount() > 0) {
+ exit(self::FAILURE_EXIT);
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param PHPUnit_TextUI_ResultPrinter $resultPrinter
+ */
+ public function setPrinter(PHPUnit_TextUI_ResultPrinter $resultPrinter)
+ {
+ $this->printer = $resultPrinter;
+ }
+
+ /**
+ * Override to define how to handle a failed loading of
+ * a test suite.
+ *
+ * @param string $message
+ */
+ protected function runFailed($message)
+ {
+ $this->write($message . PHP_EOL);
+ exit(self::FAILURE_EXIT);
+ }
+
+ /**
+ * @param string $buffer
+ */
+ protected function write($buffer)
+ {
+ if (PHP_SAPI != 'cli' && PHP_SAPI != 'phpdbg') {
+ $buffer = htmlspecialchars($buffer);
+ }
+
+ if ($this->printer !== null) {
+ $this->printer->write($buffer);
+ } else {
+ print $buffer;
+ }
+ }
+
+ /**
+ * Returns the loader to be used.
+ *
+ * @return PHPUnit_Runner_TestSuiteLoader
+ */
+ public function getLoader()
+ {
+ if ($this->loader === null) {
+ $this->loader = new PHPUnit_Runner_StandardTestSuiteLoader;
+ }
+
+ return $this->loader;
+ }
+
+ /**
+ * @param array $arguments
+ */
+ protected function handleConfiguration(array &$arguments)
+ {
+ if (isset($arguments['configuration']) &&
+ !$arguments['configuration'] instanceof PHPUnit_Util_Configuration) {
+ $arguments['configuration'] = PHPUnit_Util_Configuration::getInstance(
+ $arguments['configuration']
+ );
+ }
+
+ $arguments['debug'] = isset($arguments['debug']) ? $arguments['debug'] : false;
+ $arguments['filter'] = isset($arguments['filter']) ? $arguments['filter'] : false;
+ $arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : [];
+
+ if (isset($arguments['configuration'])) {
+ $arguments['configuration']->handlePHPConfiguration();
+
+ $phpunitConfiguration = $arguments['configuration']->getPHPUnitConfiguration();
+
+ if (isset($phpunitConfiguration['deprecatedCheckForUnintentionallyCoveredCodeSettingUsed'])) {
+ $arguments['deprecatedCheckForUnintentionallyCoveredCodeSettingUsed'] = true;
+ }
+
+ if (isset($phpunitConfiguration['backupGlobals']) &&
+ !isset($arguments['backupGlobals'])) {
+ $arguments['backupGlobals'] = $phpunitConfiguration['backupGlobals'];
+ }
+
+ if (isset($phpunitConfiguration['backupStaticAttributes']) &&
+ !isset($arguments['backupStaticAttributes'])) {
+ $arguments['backupStaticAttributes'] = $phpunitConfiguration['backupStaticAttributes'];
+ }
+
+ if (isset($phpunitConfiguration['beStrictAboutChangesToGlobalState']) &&
+ !isset($arguments['beStrictAboutChangesToGlobalState'])) {
+ $arguments['beStrictAboutChangesToGlobalState'] = $phpunitConfiguration['beStrictAboutChangesToGlobalState'];
+ }
+
+ if (isset($phpunitConfiguration['bootstrap']) &&
+ !isset($arguments['bootstrap'])) {
+ $arguments['bootstrap'] = $phpunitConfiguration['bootstrap'];
+ }
+
+ if (isset($phpunitConfiguration['cacheTokens']) &&
+ !isset($arguments['cacheTokens'])) {
+ $arguments['cacheTokens'] = $phpunitConfiguration['cacheTokens'];
+ }
+
+ if (isset($phpunitConfiguration['colors']) &&
+ !isset($arguments['colors'])) {
+ $arguments['colors'] = $phpunitConfiguration['colors'];
+ }
+
+ if (isset($phpunitConfiguration['convertErrorsToExceptions']) &&
+ !isset($arguments['convertErrorsToExceptions'])) {
+ $arguments['convertErrorsToExceptions'] = $phpunitConfiguration['convertErrorsToExceptions'];
+ }
+
+ if (isset($phpunitConfiguration['convertNoticesToExceptions']) &&
+ !isset($arguments['convertNoticesToExceptions'])) {
+ $arguments['convertNoticesToExceptions'] = $phpunitConfiguration['convertNoticesToExceptions'];
+ }
+
+ if (isset($phpunitConfiguration['convertWarningsToExceptions']) &&
+ !isset($arguments['convertWarningsToExceptions'])) {
+ $arguments['convertWarningsToExceptions'] = $phpunitConfiguration['convertWarningsToExceptions'];
+ }
+
+ if (isset($phpunitConfiguration['processIsolation']) &&
+ !isset($arguments['processIsolation'])) {
+ $arguments['processIsolation'] = $phpunitConfiguration['processIsolation'];
+ }
+
+ if (isset($phpunitConfiguration['stopOnError']) &&
+ !isset($arguments['stopOnError'])) {
+ $arguments['stopOnError'] = $phpunitConfiguration['stopOnError'];
+ }
+
+ if (isset($phpunitConfiguration['stopOnFailure']) &&
+ !isset($arguments['stopOnFailure'])) {
+ $arguments['stopOnFailure'] = $phpunitConfiguration['stopOnFailure'];
+ }
+
+ if (isset($phpunitConfiguration['stopOnWarning']) &&
+ !isset($arguments['stopOnWarning'])) {
+ $arguments['stopOnWarning'] = $phpunitConfiguration['stopOnWarning'];
+ }
+
+ if (isset($phpunitConfiguration['stopOnIncomplete']) &&
+ !isset($arguments['stopOnIncomplete'])) {
+ $arguments['stopOnIncomplete'] = $phpunitConfiguration['stopOnIncomplete'];
+ }
+
+ if (isset($phpunitConfiguration['stopOnRisky']) &&
+ !isset($arguments['stopOnRisky'])) {
+ $arguments['stopOnRisky'] = $phpunitConfiguration['stopOnRisky'];
+ }
+
+ if (isset($phpunitConfiguration['stopOnSkipped']) &&
+ !isset($arguments['stopOnSkipped'])) {
+ $arguments['stopOnSkipped'] = $phpunitConfiguration['stopOnSkipped'];
+ }
+
+ if (isset($phpunitConfiguration['failOnWarning']) &&
+ !isset($arguments['failOnWarning'])) {
+ $arguments['failOnWarning'] = $phpunitConfiguration['failOnWarning'];
+ }
+
+ if (isset($phpunitConfiguration['failOnRisky']) &&
+ !isset($arguments['failOnRisky'])) {
+ $arguments['failOnRisky'] = $phpunitConfiguration['failOnRisky'];
+ }
+
+ if (isset($phpunitConfiguration['timeoutForSmallTests']) &&
+ !isset($arguments['timeoutForSmallTests'])) {
+ $arguments['timeoutForSmallTests'] = $phpunitConfiguration['timeoutForSmallTests'];
+ }
+
+ if (isset($phpunitConfiguration['timeoutForMediumTests']) &&
+ !isset($arguments['timeoutForMediumTests'])) {
+ $arguments['timeoutForMediumTests'] = $phpunitConfiguration['timeoutForMediumTests'];
+ }
+
+ if (isset($phpunitConfiguration['timeoutForLargeTests']) &&
+ !isset($arguments['timeoutForLargeTests'])) {
+ $arguments['timeoutForLargeTests'] = $phpunitConfiguration['timeoutForLargeTests'];
+ }
+
+ if (isset($phpunitConfiguration['reportUselessTests']) &&
+ !isset($arguments['reportUselessTests'])) {
+ $arguments['reportUselessTests'] = $phpunitConfiguration['reportUselessTests'];
+ }
+
+ if (isset($phpunitConfiguration['strictCoverage']) &&
+ !isset($arguments['strictCoverage'])) {
+ $arguments['strictCoverage'] = $phpunitConfiguration['strictCoverage'];
+ }
+
+ if (isset($phpunitConfiguration['disallowTestOutput']) &&
+ !isset($arguments['disallowTestOutput'])) {
+ $arguments['disallowTestOutput'] = $phpunitConfiguration['disallowTestOutput'];
+ }
+
+ if (isset($phpunitConfiguration['enforceTimeLimit']) &&
+ !isset($arguments['enforceTimeLimit'])) {
+ $arguments['enforceTimeLimit'] = $phpunitConfiguration['enforceTimeLimit'];
+ }
+
+ if (isset($phpunitConfiguration['disallowTodoAnnotatedTests']) &&
+ !isset($arguments['disallowTodoAnnotatedTests'])) {
+ $arguments['disallowTodoAnnotatedTests'] = $phpunitConfiguration['disallowTodoAnnotatedTests'];
+ }
+
+ if (isset($phpunitConfiguration['beStrictAboutResourceUsageDuringSmallTests']) &&
+ !isset($arguments['beStrictAboutResourceUsageDuringSmallTests'])) {
+ $arguments['beStrictAboutResourceUsageDuringSmallTests'] = $phpunitConfiguration['beStrictAboutResourceUsageDuringSmallTests'];
+ }
+
+ if (isset($phpunitConfiguration['verbose']) &&
+ !isset($arguments['verbose'])) {
+ $arguments['verbose'] = $phpunitConfiguration['verbose'];
+ }
+
+ if (isset($phpunitConfiguration['reverseDefectList']) &&
+ !isset($arguments['reverseList'])) {
+ $arguments['reverseList'] = $phpunitConfiguration['reverseDefectList'];
+ }
+
+ if (isset($phpunitConfiguration['forceCoversAnnotation']) &&
+ !isset($arguments['forceCoversAnnotation'])) {
+ $arguments['forceCoversAnnotation'] = $phpunitConfiguration['forceCoversAnnotation'];
+ }
+
+ if (isset($phpunitConfiguration['disableCodeCoverageIgnore']) &&
+ !isset($arguments['disableCodeCoverageIgnore'])) {
+ $arguments['disableCodeCoverageIgnore'] = $phpunitConfiguration['disableCodeCoverageIgnore'];
+ }
+
+ if (isset($phpunitConfiguration['registerMockObjectsFromTestArgumentsRecursively']) &&
+ !isset($arguments['registerMockObjectsFromTestArgumentsRecursively'])) {
+ $arguments['registerMockObjectsFromTestArgumentsRecursively'] = $phpunitConfiguration['registerMockObjectsFromTestArgumentsRecursively'];
+ }
+
+ $groupCliArgs = [];
+
+ if (!empty($arguments['groups'])) {
+ $groupCliArgs = $arguments['groups'];
+ }
+
+ $groupConfiguration = $arguments['configuration']->getGroupConfiguration();
+
+ if (!empty($groupConfiguration['include']) &&
+ !isset($arguments['groups'])) {
+ $arguments['groups'] = $groupConfiguration['include'];
+ }
+
+ if (!empty($groupConfiguration['exclude']) &&
+ !isset($arguments['excludeGroups'])) {
+ $arguments['excludeGroups'] = array_diff($groupConfiguration['exclude'], $groupCliArgs);
+ }
+
+ foreach ($arguments['configuration']->getListenerConfiguration() as $listener) {
+ if (!class_exists($listener['class'], false) &&
+ $listener['file'] !== '') {
+ require_once $listener['file'];
+ }
+
+ if (!class_exists($listener['class'])) {
+ throw new PHPUnit_Framework_Exception(
+ sprintf(
+ 'Class "%s" does not exist',
+ $listener['class']
+ )
+ );
+ }
+
+ $listenerClass = new ReflectionClass($listener['class']);
+
+ if (!$listenerClass->implementsInterface(PHPUnit_Framework_TestListener::class)) {
+ throw new PHPUnit_Framework_Exception(
+ sprintf(
+ 'Class "%s" does not implement the PHPUnit_Framework_TestListener interface',
+ $listener['class']
+ )
+ );
+ }
+
+ if (count($listener['arguments']) == 0) {
+ $listener = new $listener['class'];
+ } else {
+ $listener = $listenerClass->newInstanceArgs(
+ $listener['arguments']
+ );
+ }
+
+ $arguments['listeners'][] = $listener;
+ }
+
+ $loggingConfiguration = $arguments['configuration']->getLoggingConfiguration();
+
+ if (isset($loggingConfiguration['coverage-clover']) &&
+ !isset($arguments['coverageClover'])) {
+ $arguments['coverageClover'] = $loggingConfiguration['coverage-clover'];
+ }
+
+ if (isset($loggingConfiguration['coverage-crap4j']) &&
+ !isset($arguments['coverageCrap4J'])) {
+ $arguments['coverageCrap4J'] = $loggingConfiguration['coverage-crap4j'];
+
+ if (isset($loggingConfiguration['crap4jThreshold']) &&
+ !isset($arguments['crap4jThreshold'])) {
+ $arguments['crap4jThreshold'] = $loggingConfiguration['crap4jThreshold'];
+ }
+ }
+
+ if (isset($loggingConfiguration['coverage-html']) &&
+ !isset($arguments['coverageHtml'])) {
+ if (isset($loggingConfiguration['lowUpperBound']) &&
+ !isset($arguments['reportLowUpperBound'])) {
+ $arguments['reportLowUpperBound'] = $loggingConfiguration['lowUpperBound'];
+ }
+
+ if (isset($loggingConfiguration['highLowerBound']) &&
+ !isset($arguments['reportHighLowerBound'])) {
+ $arguments['reportHighLowerBound'] = $loggingConfiguration['highLowerBound'];
+ }
+
+ $arguments['coverageHtml'] = $loggingConfiguration['coverage-html'];
+ }
+
+ if (isset($loggingConfiguration['coverage-php']) &&
+ !isset($arguments['coveragePHP'])) {
+ $arguments['coveragePHP'] = $loggingConfiguration['coverage-php'];
+ }
+
+ if (isset($loggingConfiguration['coverage-text']) &&
+ !isset($arguments['coverageText'])) {
+ $arguments['coverageText'] = $loggingConfiguration['coverage-text'];
+ if (isset($loggingConfiguration['coverageTextShowUncoveredFiles'])) {
+ $arguments['coverageTextShowUncoveredFiles'] = $loggingConfiguration['coverageTextShowUncoveredFiles'];
+ } else {
+ $arguments['coverageTextShowUncoveredFiles'] = false;
+ }
+ if (isset($loggingConfiguration['coverageTextShowOnlySummary'])) {
+ $arguments['coverageTextShowOnlySummary'] = $loggingConfiguration['coverageTextShowOnlySummary'];
+ } else {
+ $arguments['coverageTextShowOnlySummary'] = false;
+ }
+ }
+
+ if (isset($loggingConfiguration['coverage-xml']) &&
+ !isset($arguments['coverageXml'])) {
+ $arguments['coverageXml'] = $loggingConfiguration['coverage-xml'];
+ }
+
+ if (isset($loggingConfiguration['json']) &&
+ !isset($arguments['jsonLogfile'])) {
+ $arguments['jsonLogfile'] = $loggingConfiguration['json'];
+ }
+
+ if (isset($loggingConfiguration['plain'])) {
+ $arguments['listeners'][] = new PHPUnit_TextUI_ResultPrinter(
+ $loggingConfiguration['plain'],
+ true
+ );
+ }
+
+ if (isset($loggingConfiguration['tap']) &&
+ !isset($arguments['tapLogfile'])) {
+ $arguments['tapLogfile'] = $loggingConfiguration['tap'];
+ }
+
+ if (isset($loggingConfiguration['teamcity']) &&
+ !isset($arguments['teamcityLogfile'])) {
+ $arguments['teamcityLogfile'] = $loggingConfiguration['teamcity'];
+ }
+
+ if (isset($loggingConfiguration['junit']) &&
+ !isset($arguments['junitLogfile'])) {
+ $arguments['junitLogfile'] = $loggingConfiguration['junit'];
+
+ if (isset($loggingConfiguration['logIncompleteSkipped']) &&
+ !isset($arguments['logIncompleteSkipped'])) {
+ $arguments['logIncompleteSkipped'] = $loggingConfiguration['logIncompleteSkipped'];
+ }
+ }
+
+ if (isset($loggingConfiguration['testdox-html']) &&
+ !isset($arguments['testdoxHTMLFile'])) {
+ $arguments['testdoxHTMLFile'] = $loggingConfiguration['testdox-html'];
+ }
+
+ if (isset($loggingConfiguration['testdox-text']) &&
+ !isset($arguments['testdoxTextFile'])) {
+ $arguments['testdoxTextFile'] = $loggingConfiguration['testdox-text'];
+ }
+
+ if (isset($loggingConfiguration['testdox-xml']) &&
+ !isset($arguments['testdoxXMLFile'])) {
+ $arguments['testdoxXMLFile'] = $loggingConfiguration['testdox-xml'];
+ }
+
+ $testdoxGroupConfiguration = $arguments['configuration']->getTestdoxGroupConfiguration();
+
+ if (isset($testdoxGroupConfiguration['include']) &&
+ !isset($arguments['testdoxGroups'])) {
+ $arguments['testdoxGroups'] = $testdoxGroupConfiguration['include'];
+ }
+
+ if (isset($testdoxGroupConfiguration['exclude']) &&
+ !isset($arguments['testdoxExcludeGroups'])) {
+ $arguments['testdoxExcludeGroups'] = $testdoxGroupConfiguration['exclude'];
+ }
+ }
+
+ $arguments['addUncoveredFilesFromWhitelist'] = isset($arguments['addUncoveredFilesFromWhitelist']) ? $arguments['addUncoveredFilesFromWhitelist'] : true;
+ $arguments['processUncoveredFilesFromWhitelist'] = isset($arguments['processUncoveredFilesFromWhitelist']) ? $arguments['processUncoveredFilesFromWhitelist'] : false;
+ $arguments['backupGlobals'] = isset($arguments['backupGlobals']) ? $arguments['backupGlobals'] : null;
+ $arguments['backupStaticAttributes'] = isset($arguments['backupStaticAttributes']) ? $arguments['backupStaticAttributes'] : null;
+ $arguments['beStrictAboutChangesToGlobalState'] = isset($arguments['beStrictAboutChangesToGlobalState']) ? $arguments['beStrictAboutChangesToGlobalState'] : null;
+ $arguments['cacheTokens'] = isset($arguments['cacheTokens']) ? $arguments['cacheTokens'] : false;
+ $arguments['columns'] = isset($arguments['columns']) ? $arguments['columns'] : 80;
+ $arguments['colors'] = isset($arguments['colors']) ? $arguments['colors'] : PHPUnit_TextUI_ResultPrinter::COLOR_DEFAULT;
+ $arguments['convertErrorsToExceptions'] = isset($arguments['convertErrorsToExceptions']) ? $arguments['convertErrorsToExceptions'] : true;
+ $arguments['convertNoticesToExceptions'] = isset($arguments['convertNoticesToExceptions']) ? $arguments['convertNoticesToExceptions'] : true;
+ $arguments['convertWarningsToExceptions'] = isset($arguments['convertWarningsToExceptions']) ? $arguments['convertWarningsToExceptions'] : true;
+ $arguments['excludeGroups'] = isset($arguments['excludeGroups']) ? $arguments['excludeGroups'] : [];
+ $arguments['groups'] = isset($arguments['groups']) ? $arguments['groups'] : [];
+ $arguments['logIncompleteSkipped'] = isset($arguments['logIncompleteSkipped']) ? $arguments['logIncompleteSkipped'] : false;
+ $arguments['processIsolation'] = isset($arguments['processIsolation']) ? $arguments['processIsolation'] : false;
+ $arguments['repeat'] = isset($arguments['repeat']) ? $arguments['repeat'] : false;
+ $arguments['reportHighLowerBound'] = isset($arguments['reportHighLowerBound']) ? $arguments['reportHighLowerBound'] : 90;
+ $arguments['reportLowUpperBound'] = isset($arguments['reportLowUpperBound']) ? $arguments['reportLowUpperBound'] : 50;
+ $arguments['crap4jThreshold'] = isset($arguments['crap4jThreshold']) ? $arguments['crap4jThreshold'] : 30;
+ $arguments['stopOnError'] = isset($arguments['stopOnError']) ? $arguments['stopOnError'] : false;
+ $arguments['stopOnFailure'] = isset($arguments['stopOnFailure']) ? $arguments['stopOnFailure'] : false;
+ $arguments['stopOnWarning'] = isset($arguments['stopOnWarning']) ? $arguments['stopOnWarning'] : false;
+ $arguments['stopOnIncomplete'] = isset($arguments['stopOnIncomplete']) ? $arguments['stopOnIncomplete'] : false;
+ $arguments['stopOnRisky'] = isset($arguments['stopOnRisky']) ? $arguments['stopOnRisky'] : false;
+ $arguments['stopOnSkipped'] = isset($arguments['stopOnSkipped']) ? $arguments['stopOnSkipped'] : false;
+ $arguments['failOnWarning'] = isset($arguments['failOnWarning']) ? $arguments['failOnWarning'] : false;
+ $arguments['failOnRisky'] = isset($arguments['failOnRisky']) ? $arguments['failOnRisky'] : false;
+ $arguments['timeoutForSmallTests'] = isset($arguments['timeoutForSmallTests']) ? $arguments['timeoutForSmallTests'] : 1;
+ $arguments['timeoutForMediumTests'] = isset($arguments['timeoutForMediumTests']) ? $arguments['timeoutForMediumTests'] : 10;
+ $arguments['timeoutForLargeTests'] = isset($arguments['timeoutForLargeTests']) ? $arguments['timeoutForLargeTests'] : 60;
+ $arguments['reportUselessTests'] = isset($arguments['reportUselessTests']) ? $arguments['reportUselessTests'] : false;
+ $arguments['strictCoverage'] = isset($arguments['strictCoverage']) ? $arguments['strictCoverage'] : false;
+ $arguments['disallowTestOutput'] = isset($arguments['disallowTestOutput']) ? $arguments['disallowTestOutput'] : false;
+ $arguments['enforceTimeLimit'] = isset($arguments['enforceTimeLimit']) ? $arguments['enforceTimeLimit'] : false;
+ $arguments['disallowTodoAnnotatedTests'] = isset($arguments['disallowTodoAnnotatedTests']) ? $arguments['disallowTodoAnnotatedTests'] : false;
+ $arguments['beStrictAboutResourceUsageDuringSmallTests'] = isset($arguments['beStrictAboutResourceUsageDuringSmallTests']) ? $arguments['beStrictAboutResourceUsageDuringSmallTests'] : false;
+ $arguments['reverseList'] = isset($arguments['reverseList']) ? $arguments['reverseList'] : false;
+ $arguments['registerMockObjectsFromTestArgumentsRecursively'] = isset($arguments['registerMockObjectsFromTestArgumentsRecursively']) ? $arguments['registerMockObjectsFromTestArgumentsRecursively'] : false;
+ $arguments['verbose'] = isset($arguments['verbose']) ? $arguments['verbose'] : false;
+ $arguments['testdoxExcludeGroups'] = isset($arguments['testdoxExcludeGroups']) ? $arguments['testdoxExcludeGroups'] : [];
+ $arguments['testdoxGroups'] = isset($arguments['testdoxGroups']) ? $arguments['testdoxGroups'] : [];
+ }
+
+ /**
+ * @param string $type
+ * @param string $message
+ */
+ private function writeMessage($type, $message)
+ {
+ if (!$this->messagePrinted) {
+ $this->write("\n");
+ }
+
+ $this->write(
+ sprintf(
+ "%-15s%s\n",
+ $type . ':',
+ $message
+ )
+ );
+
+ $this->messagePrinted = true;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/Blacklist.php b/vendor/phpunit/phpunit/src/Util/Blacklist.php
new file mode 100644
index 0000000..a140917
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/Blacklist.php
@@ -0,0 +1,111 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Utility class for blacklisting PHPUnit's own source code files.
+ */
+class PHPUnit_Util_Blacklist
+{
+ /**
+ * @var array
+ */
+ public static $blacklistedClassNames = [
+ 'File_Iterator' => 1,
+ 'PHP_Invoker' => 1,
+ 'PHP_Timer' => 1,
+ 'PHP_Token' => 1,
+ 'PHPUnit_Framework_TestCase' => 2,
+ 'PHPUnit_Extensions_Database_TestCase' => 2,
+ 'PHPUnit_Framework_MockObject_Generator' => 2,
+ 'Text_Template' => 1,
+ 'Symfony\Component\Yaml\Yaml' => 1,
+ 'SebastianBergmann\CodeCoverage\CodeCoverage' => 1,
+ 'SebastianBergmann\Diff\Diff' => 1,
+ 'SebastianBergmann\Environment\Runtime' => 1,
+ 'SebastianBergmann\Comparator\Comparator' => 1,
+ 'SebastianBergmann\Exporter\Exporter' => 1,
+ 'SebastianBergmann\GlobalState\Snapshot' => 1,
+ 'SebastianBergmann\RecursionContext\Context' => 1,
+ 'SebastianBergmann\Version' => 1,
+ 'Composer\Autoload\ClassLoader' => 1,
+ 'Doctrine\Instantiator\Instantiator' => 1,
+ 'phpDocumentor\Reflection\DocBlock' => 1,
+ 'Prophecy\Prophet' => 1,
+ 'DeepCopy\DeepCopy' => 1
+ ];
+
+ /**
+ * @var array
+ */
+ private static $directories;
+
+ /**
+ * @return array
+ */
+ public function getBlacklistedDirectories()
+ {
+ $this->initialize();
+
+ return self::$directories;
+ }
+
+ /**
+ * @param string $file
+ *
+ * @return bool
+ */
+ public function isBlacklisted($file)
+ {
+ if (defined('PHPUNIT_TESTSUITE')) {
+ return false;
+ }
+
+ $this->initialize();
+
+ foreach (self::$directories as $directory) {
+ if (strpos($file, $directory) === 0) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private function initialize()
+ {
+ if (self::$directories === null) {
+ self::$directories = [];
+
+ foreach (self::$blacklistedClassNames as $className => $parent) {
+ if (!class_exists($className)) {
+ continue;
+ }
+
+ $reflector = new ReflectionClass($className);
+ $directory = $reflector->getFileName();
+
+ for ($i = 0; $i < $parent; $i++) {
+ $directory = dirname($directory);
+ }
+
+ self::$directories[] = $directory;
+ }
+
+ // Hide process isolation workaround on Windows.
+ // @see PHPUnit_Util_PHP::factory()
+ // @see PHPUnit_Util_PHP_Windows::process()
+ if (DIRECTORY_SEPARATOR === '\\') {
+ // tempnam() prefix is limited to first 3 chars.
+ // @see http://php.net/manual/en/function.tempnam.php
+ self::$directories[] = sys_get_temp_dir() . '\\PHP';
+ }
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/Configuration.php b/vendor/phpunit/phpunit/src/Util/Configuration.php
new file mode 100644
index 0000000..d91825d
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/Configuration.php
@@ -0,0 +1,1135 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Wrapper for the PHPUnit XML configuration file.
+ *
+ * Example XML configuration file:
+ * <code>
+ * <?xml version="1.0" encoding="utf-8" ?>
+ *
+ * <phpunit backupGlobals="true"
+ * backupStaticAttributes="false"
+ * bootstrap="/path/to/bootstrap.php"
+ * cacheTokens="false"
+ * columns="80"
+ * colors="false"
+ * stderr="false"
+ * convertErrorsToExceptions="true"
+ * convertNoticesToExceptions="true"
+ * convertWarningsToExceptions="true"
+ * forceCoversAnnotation="false"
+ * processIsolation="false"
+ * stopOnError="false"
+ * stopOnFailure="false"
+ * stopOnWarning="false"
+ * stopOnIncomplete="false"
+ * stopOnRisky="false"
+ * stopOnSkipped="false"
+ * failOnWarning="false"
+ * failOnRisky="false"
+ * extensionsDirectory="tools/phpunit.d"
+ * printerClass="PHPUnit_TextUI_ResultPrinter"
+ * testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"
+ * beStrictAboutChangesToGlobalState="false"
+ * beStrictAboutCoversAnnotation="false"
+ * beStrictAboutOutputDuringTests="false"
+ * beStrictAboutResourceUsageDuringSmallTests="false"
+ * beStrictAboutTestsThatDoNotTestAnything="false"
+ * beStrictAboutTodoAnnotatedTests="false"
+ * checkForUnintentionallyCoveredCode="false"
+ * enforceTimeLimit="false"
+ * timeoutForSmallTests="1"
+ * timeoutForMediumTests="10"
+ * timeoutForLargeTests="60"
+ * verbose="false"
+ * reverseDefectList="false"
+ * registerMockObjectsFromTestArgumentsRecursively="false">
+ * <testsuites>
+ * <testsuite name="My Test Suite">
+ * <directory suffix="Test.php" phpVersion="5.3.0" phpVersionOperator=">=">/path/to/files</directory>
+ * <file phpVersion="5.3.0" phpVersionOperator=">=">/path/to/MyTest.php</file>
+ * <exclude>/path/to/files/exclude</exclude>
+ * </testsuite>
+ * </testsuites>
+ *
+ * <groups>
+ * <include>
+ * <group>name</group>
+ * </include>
+ * <exclude>
+ * <group>name</group>
+ * </exclude>
+ * </groups>
+ *
+ * <testdoxGroups>
+ * <include>
+ * <group>name</group>
+ * </include>
+ * <exclude>
+ * <group>name</group>
+ * </exclude>
+ * </testdoxGroups>
+ *
+ * <filter>
+ * <whitelist addUncoveredFilesFromWhitelist="true"
+ * processUncoveredFilesFromWhitelist="false">
+ * <directory suffix=".php">/path/to/files</directory>
+ * <file>/path/to/file</file>
+ * <exclude>
+ * <directory suffix=".php">/path/to/files</directory>
+ * <file>/path/to/file</file>
+ * </exclude>
+ * </whitelist>
+ * </filter>
+ *
+ * <listeners>
+ * <listener class="MyListener" file="/optional/path/to/MyListener.php">
+ * <arguments>
+ * <array>
+ * <element key="0">
+ * <string>Sebastian</string>
+ * </element>
+ * </array>
+ * <integer>22</integer>
+ * <string>April</string>
+ * <double>19.78</double>
+ * <null/>
+ * <object class="stdClass"/>
+ * <file>MyRelativeFile.php</file>
+ * <directory>MyRelativeDir</directory>
+ * </arguments>
+ * </listener>
+ * </listeners>
+ *
+ * <logging>
+ * <log type="coverage-html" target="/tmp/report" lowUpperBound="50" highLowerBound="90"/>
+ * <log type="coverage-clover" target="/tmp/clover.xml"/>
+ * <log type="coverage-crap4j" target="/tmp/crap.xml" threshold="30"/>
+ * <log type="json" target="/tmp/logfile.json"/>
+ * <log type="plain" target="/tmp/logfile.txt"/>
+ * <log type="tap" target="/tmp/logfile.tap"/>
+ * <log type="teamcity" target="/tmp/logfile.txt"/>
+ * <log type="junit" target="/tmp/logfile.xml" logIncompleteSkipped="false"/>
+ * <log type="testdox-html" target="/tmp/testdox.html"/>
+ * <log type="testdox-text" target="/tmp/testdox.txt"/>
+ * <log type="testdox-xml" target="/tmp/testdox.xml"/>
+ * </logging>
+ *
+ * <php>
+ * <includePath>.</includePath>
+ * <ini name="foo" value="bar"/>
+ * <const name="foo" value="bar"/>
+ * <var name="foo" value="bar"/>
+ * <env name="foo" value="bar"/>
+ * <post name="foo" value="bar"/>
+ * <get name="foo" value="bar"/>
+ * <cookie name="foo" value="bar"/>
+ * <server name="foo" value="bar"/>
+ * <files name="foo" value="bar"/>
+ * <request name="foo" value="bar"/>
+ * </php>
+ * </phpunit>
+ * </code>
+ */
+class PHPUnit_Util_Configuration
+{
+ private static $instances = [];
+
+ protected $document;
+ protected $xpath;
+ protected $filename;
+
+ /**
+ * Loads a PHPUnit configuration file.
+ *
+ * @param string $filename
+ */
+ protected function __construct($filename)
+ {
+ $this->filename = $filename;
+ $this->document = PHPUnit_Util_XML::loadFile($filename, false, true, true);
+ $this->xpath = new DOMXPath($this->document);
+ }
+
+ final private function __clone()
+ {
+ }
+
+ /**
+ * Returns a PHPUnit configuration object.
+ *
+ * @param string $filename
+ *
+ * @return PHPUnit_Util_Configuration
+ */
+ public static function getInstance($filename)
+ {
+ $realpath = realpath($filename);
+
+ if ($realpath === false) {
+ throw new PHPUnit_Framework_Exception(
+ sprintf(
+ 'Could not read "%s".',
+ $filename
+ )
+ );
+ }
+
+ if (!isset(self::$instances[$realpath])) {
+ self::$instances[$realpath] = new self($realpath);
+ }
+
+ return self::$instances[$realpath];
+ }
+
+ /**
+ * Returns the realpath to the configuration file.
+ *
+ * @return string
+ */
+ public function getFilename()
+ {
+ return $this->filename;
+ }
+
+ /**
+ * Returns the configuration for SUT filtering.
+ *
+ * @return array
+ */
+ public function getFilterConfiguration()
+ {
+ $addUncoveredFilesFromWhitelist = true;
+ $processUncoveredFilesFromWhitelist = false;
+
+ $tmp = $this->xpath->query('filter/whitelist');
+
+ if ($tmp->length == 1) {
+ if ($tmp->item(0)->hasAttribute('addUncoveredFilesFromWhitelist')) {
+ $addUncoveredFilesFromWhitelist = $this->getBoolean(
+ (string) $tmp->item(0)->getAttribute(
+ 'addUncoveredFilesFromWhitelist'
+ ),
+ true
+ );
+ }
+
+ if ($tmp->item(0)->hasAttribute('processUncoveredFilesFromWhitelist')) {
+ $processUncoveredFilesFromWhitelist = $this->getBoolean(
+ (string) $tmp->item(0)->getAttribute(
+ 'processUncoveredFilesFromWhitelist'
+ ),
+ false
+ );
+ }
+ }
+
+ return [
+ 'whitelist' => [
+ 'addUncoveredFilesFromWhitelist' => $addUncoveredFilesFromWhitelist,
+ 'processUncoveredFilesFromWhitelist' => $processUncoveredFilesFromWhitelist,
+ 'include' => [
+ 'directory' => $this->readFilterDirectories(
+ 'filter/whitelist/directory'
+ ),
+ 'file' => $this->readFilterFiles(
+ 'filter/whitelist/file'
+ )
+ ],
+ 'exclude' => [
+ 'directory' => $this->readFilterDirectories(
+ 'filter/whitelist/exclude/directory'
+ ),
+ 'file' => $this->readFilterFiles(
+ 'filter/whitelist/exclude/file'
+ )
+ ]
+ ]
+ ];
+ }
+
+ /**
+ * Returns the configuration for groups.
+ *
+ * @return array
+ */
+ public function getGroupConfiguration()
+ {
+ return $this->parseGroupConfiguration('groups');
+ }
+
+ /**
+ * Returns the configuration for testdox groups.
+ *
+ * @return array
+ */
+ public function getTestdoxGroupConfiguration()
+ {
+ return $this->parseGroupConfiguration('testdoxGroups');
+ }
+
+ /**
+ * @param string $root
+ *
+ * @return array
+ */
+ private function parseGroupConfiguration($root)
+ {
+ $groups = [
+ 'include' => [],
+ 'exclude' => []
+ ];
+
+ foreach ($this->xpath->query($root . '/include/group') as $group) {
+ $groups['include'][] = (string) $group->textContent;
+ }
+
+ foreach ($this->xpath->query($root . '/exclude/group') as $group) {
+ $groups['exclude'][] = (string) $group->textContent;
+ }
+
+ return $groups;
+ }
+
+ /**
+ * Returns the configuration for listeners.
+ *
+ * @return array
+ */
+ public function getListenerConfiguration()
+ {
+ $result = [];
+
+ foreach ($this->xpath->query('listeners/listener') as $listener) {
+ $class = (string) $listener->getAttribute('class');
+ $file = '';
+ $arguments = [];
+
+ if ($listener->getAttribute('file')) {
+ $file = $this->toAbsolutePath(
+ (string) $listener->getAttribute('file'),
+ true
+ );
+ }
+
+ foreach ($listener->childNodes as $node) {
+ if ($node instanceof DOMElement && $node->tagName == 'arguments') {
+ foreach ($node->childNodes as $argument) {
+ if ($argument instanceof DOMElement) {
+ if ($argument->tagName == 'file' ||
+ $argument->tagName == 'directory') {
+ $arguments[] = $this->toAbsolutePath((string) $argument->textContent);
+ } else {
+ $arguments[] = PHPUnit_Util_XML::xmlToVariable($argument);
+ }
+ }
+ }
+ }
+ }
+
+ $result[] = [
+ 'class' => $class,
+ 'file' => $file,
+ 'arguments' => $arguments
+ ];
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns the logging configuration.
+ *
+ * @return array
+ */
+ public function getLoggingConfiguration()
+ {
+ $result = [];
+
+ foreach ($this->xpath->query('logging/log') as $log) {
+ $type = (string) $log->getAttribute('type');
+ $target = (string) $log->getAttribute('target');
+
+ if (!$target) {
+ continue;
+ }
+
+ $target = $this->toAbsolutePath($target);
+
+ if ($type == 'coverage-html') {
+ if ($log->hasAttribute('lowUpperBound')) {
+ $result['lowUpperBound'] = $this->getInteger(
+ (string) $log->getAttribute('lowUpperBound'),
+ 50
+ );
+ }
+
+ if ($log->hasAttribute('highLowerBound')) {
+ $result['highLowerBound'] = $this->getInteger(
+ (string) $log->getAttribute('highLowerBound'),
+ 90
+ );
+ }
+ } elseif ($type == 'coverage-crap4j') {
+ if ($log->hasAttribute('threshold')) {
+ $result['crap4jThreshold'] = $this->getInteger(
+ (string) $log->getAttribute('threshold'),
+ 30
+ );
+ }
+ } elseif ($type == 'junit') {
+ if ($log->hasAttribute('logIncompleteSkipped')) {
+ $result['logIncompleteSkipped'] = $this->getBoolean(
+ (string) $log->getAttribute('logIncompleteSkipped'),
+ false
+ );
+ }
+ } elseif ($type == 'coverage-text') {
+ if ($log->hasAttribute('showUncoveredFiles')) {
+ $result['coverageTextShowUncoveredFiles'] = $this->getBoolean(
+ (string) $log->getAttribute('showUncoveredFiles'),
+ false
+ );
+ }
+ if ($log->hasAttribute('showOnlySummary')) {
+ $result['coverageTextShowOnlySummary'] = $this->getBoolean(
+ (string) $log->getAttribute('showOnlySummary'),
+ false
+ );
+ }
+ }
+
+ $result[$type] = $target;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns the PHP configuration.
+ *
+ * @return array
+ */
+ public function getPHPConfiguration()
+ {
+ $result = [
+ 'include_path' => [],
+ 'ini' => [],
+ 'const' => [],
+ 'var' => [],
+ 'env' => [],
+ 'post' => [],
+ 'get' => [],
+ 'cookie' => [],
+ 'server' => [],
+ 'files' => [],
+ 'request' => []
+ ];
+
+ foreach ($this->xpath->query('php/includePath') as $includePath) {
+ $path = (string) $includePath->textContent;
+ if ($path) {
+ $result['include_path'][] = $this->toAbsolutePath($path);
+ }
+ }
+
+ foreach ($this->xpath->query('php/ini') as $ini) {
+ $name = (string) $ini->getAttribute('name');
+ $value = (string) $ini->getAttribute('value');
+
+ $result['ini'][$name] = $value;
+ }
+
+ foreach ($this->xpath->query('php/const') as $const) {
+ $name = (string) $const->getAttribute('name');
+ $value = (string) $const->getAttribute('value');
+
+ $result['const'][$name] = $this->getBoolean($value, $value);
+ }
+
+ foreach (['var', 'env', 'post', 'get', 'cookie', 'server', 'files', 'request'] as $array) {
+ foreach ($this->xpath->query('php/' . $array) as $var) {
+ $name = (string) $var->getAttribute('name');
+ $value = (string) $var->getAttribute('value');
+
+ $result[$array][$name] = $this->getBoolean($value, $value);
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Handles the PHP configuration.
+ */
+ public function handlePHPConfiguration()
+ {
+ $configuration = $this->getPHPConfiguration();
+
+ if (! empty($configuration['include_path'])) {
+ ini_set(
+ 'include_path',
+ implode(PATH_SEPARATOR, $configuration['include_path']) .
+ PATH_SEPARATOR .
+ ini_get('include_path')
+ );
+ }
+
+ foreach ($configuration['ini'] as $name => $value) {
+ if (defined($value)) {
+ $value = constant($value);
+ }
+
+ ini_set($name, $value);
+ }
+
+ foreach ($configuration['const'] as $name => $value) {
+ if (!defined($name)) {
+ define($name, $value);
+ }
+ }
+
+ foreach (['var', 'post', 'get', 'cookie', 'server', 'files', 'request'] as $array) {
+ // See https://github.com/sebastianbergmann/phpunit/issues/277
+ switch ($array) {
+ case 'var':
+ $target = &$GLOBALS;
+ break;
+
+ case 'server':
+ $target = &$_SERVER;
+ break;
+
+ default:
+ $target = &$GLOBALS['_' . strtoupper($array)];
+ break;
+ }
+
+ foreach ($configuration[$array] as $name => $value) {
+ $target[$name] = $value;
+ }
+ }
+
+ foreach ($configuration['env'] as $name => $value) {
+ if (false === getenv($name)) {
+ putenv("{$name}={$value}");
+ }
+ if (!isset($_ENV[$name])) {
+ $_ENV[$name] = $value;
+ }
+ }
+ }
+
+ /**
+ * Returns the PHPUnit configuration.
+ *
+ * @return array
+ */
+ public function getPHPUnitConfiguration()
+ {
+ $result = [];
+ $root = $this->document->documentElement;
+
+ if ($root->hasAttribute('cacheTokens')) {
+ $result['cacheTokens'] = $this->getBoolean(
+ (string) $root->getAttribute('cacheTokens'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('columns')) {
+ $columns = (string) $root->getAttribute('columns');
+
+ if ($columns == 'max') {
+ $result['columns'] = 'max';
+ } else {
+ $result['columns'] = $this->getInteger($columns, 80);
+ }
+ }
+
+ if ($root->hasAttribute('colors')) {
+ /* only allow boolean for compatibility with previous versions
+ 'always' only allowed from command line */
+ if ($this->getBoolean($root->getAttribute('colors'), false)) {
+ $result['colors'] = PHPUnit_TextUI_ResultPrinter::COLOR_AUTO;
+ } else {
+ $result['colors'] = PHPUnit_TextUI_ResultPrinter::COLOR_NEVER;
+ }
+ }
+
+ /*
+ * Issue #657
+ */
+ if ($root->hasAttribute('stderr')) {
+ $result['stderr'] = $this->getBoolean(
+ (string) $root->getAttribute('stderr'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('backupGlobals')) {
+ $result['backupGlobals'] = $this->getBoolean(
+ (string) $root->getAttribute('backupGlobals'),
+ true
+ );
+ }
+
+ if ($root->hasAttribute('backupStaticAttributes')) {
+ $result['backupStaticAttributes'] = $this->getBoolean(
+ (string) $root->getAttribute('backupStaticAttributes'),
+ false
+ );
+ }
+
+ if ($root->getAttribute('bootstrap')) {
+ $result['bootstrap'] = $this->toAbsolutePath(
+ (string) $root->getAttribute('bootstrap')
+ );
+ }
+
+ if ($root->hasAttribute('convertErrorsToExceptions')) {
+ $result['convertErrorsToExceptions'] = $this->getBoolean(
+ (string) $root->getAttribute('convertErrorsToExceptions'),
+ true
+ );
+ }
+
+ if ($root->hasAttribute('convertNoticesToExceptions')) {
+ $result['convertNoticesToExceptions'] = $this->getBoolean(
+ (string) $root->getAttribute('convertNoticesToExceptions'),
+ true
+ );
+ }
+
+ if ($root->hasAttribute('convertWarningsToExceptions')) {
+ $result['convertWarningsToExceptions'] = $this->getBoolean(
+ (string) $root->getAttribute('convertWarningsToExceptions'),
+ true
+ );
+ }
+
+ if ($root->hasAttribute('forceCoversAnnotation')) {
+ $result['forceCoversAnnotation'] = $this->getBoolean(
+ (string) $root->getAttribute('forceCoversAnnotation'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('disableCodeCoverageIgnore')) {
+ $result['disableCodeCoverageIgnore'] = $this->getBoolean(
+ (string) $root->getAttribute('disableCodeCoverageIgnore'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('processIsolation')) {
+ $result['processIsolation'] = $this->getBoolean(
+ (string) $root->getAttribute('processIsolation'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('stopOnError')) {
+ $result['stopOnError'] = $this->getBoolean(
+ (string) $root->getAttribute('stopOnError'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('stopOnFailure')) {
+ $result['stopOnFailure'] = $this->getBoolean(
+ (string) $root->getAttribute('stopOnFailure'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('stopOnWarning')) {
+ $result['stopOnWarning'] = $this->getBoolean(
+ (string) $root->getAttribute('stopOnWarning'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('stopOnIncomplete')) {
+ $result['stopOnIncomplete'] = $this->getBoolean(
+ (string) $root->getAttribute('stopOnIncomplete'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('stopOnRisky')) {
+ $result['stopOnRisky'] = $this->getBoolean(
+ (string) $root->getAttribute('stopOnRisky'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('stopOnSkipped')) {
+ $result['stopOnSkipped'] = $this->getBoolean(
+ (string) $root->getAttribute('stopOnSkipped'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('failOnWarning')) {
+ $result['failOnWarning'] = $this->getBoolean(
+ (string) $root->getAttribute('failOnWarning'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('failOnRisky')) {
+ $result['failOnRisky'] = $this->getBoolean(
+ (string) $root->getAttribute('failOnRisky'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('testSuiteLoaderClass')) {
+ $result['testSuiteLoaderClass'] = (string) $root->getAttribute(
+ 'testSuiteLoaderClass'
+ );
+ }
+
+ if ($root->getAttribute('testSuiteLoaderFile')) {
+ $result['testSuiteLoaderFile'] = $this->toAbsolutePath(
+ (string) $root->getAttribute('testSuiteLoaderFile')
+ );
+ }
+
+ if ($root->hasAttribute('printerClass')) {
+ $result['printerClass'] = (string) $root->getAttribute(
+ 'printerClass'
+ );
+ }
+
+ if ($root->getAttribute('printerFile')) {
+ $result['printerFile'] = $this->toAbsolutePath(
+ (string) $root->getAttribute('printerFile')
+ );
+ }
+
+ if ($root->hasAttribute('beStrictAboutChangesToGlobalState')) {
+ $result['beStrictAboutChangesToGlobalState'] = $this->getBoolean(
+ (string) $root->getAttribute('beStrictAboutChangesToGlobalState'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('beStrictAboutOutputDuringTests')) {
+ $result['disallowTestOutput'] = $this->getBoolean(
+ (string) $root->getAttribute('beStrictAboutOutputDuringTests'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('beStrictAboutResourceUsageDuringSmallTests')) {
+ $result['beStrictAboutResourceUsageDuringSmallTests'] = $this->getBoolean(
+ (string) $root->getAttribute('beStrictAboutResourceUsageDuringSmallTests'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('beStrictAboutTestsThatDoNotTestAnything')) {
+ $result['reportUselessTests'] = $this->getBoolean(
+ (string) $root->getAttribute('beStrictAboutTestsThatDoNotTestAnything'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('beStrictAboutTodoAnnotatedTests')) {
+ $result['disallowTodoAnnotatedTests'] = $this->getBoolean(
+ (string) $root->getAttribute('beStrictAboutTodoAnnotatedTests'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('beStrictAboutCoversAnnotation')) {
+ $result['strictCoverage'] = $this->getBoolean(
+ (string) $root->getAttribute('beStrictAboutCoversAnnotation'),
+ false
+ );
+ } elseif ($root->hasAttribute('checkForUnintentionallyCoveredCode')) {
+ $result['strictCoverage'] = $this->getBoolean(
+ (string) $root->getAttribute('checkForUnintentionallyCoveredCode'),
+ false
+ );
+
+ $result['deprecatedCheckForUnintentionallyCoveredCodeSettingUsed'] = true;
+ }
+
+ if ($root->hasAttribute('enforceTimeLimit')) {
+ $result['enforceTimeLimit'] = $this->getBoolean(
+ (string) $root->getAttribute('enforceTimeLimit'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('timeoutForSmallTests')) {
+ $result['timeoutForSmallTests'] = $this->getInteger(
+ (string) $root->getAttribute('timeoutForSmallTests'),
+ 1
+ );
+ }
+
+ if ($root->hasAttribute('timeoutForMediumTests')) {
+ $result['timeoutForMediumTests'] = $this->getInteger(
+ (string) $root->getAttribute('timeoutForMediumTests'),
+ 10
+ );
+ }
+
+ if ($root->hasAttribute('timeoutForLargeTests')) {
+ $result['timeoutForLargeTests'] = $this->getInteger(
+ (string) $root->getAttribute('timeoutForLargeTests'),
+ 60
+ );
+ }
+
+ if ($root->hasAttribute('reverseDefectList')) {
+ $result['reverseDefectList'] = $this->getBoolean(
+ (string) $root->getAttribute('reverseDefectList'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('verbose')) {
+ $result['verbose'] = $this->getBoolean(
+ (string) $root->getAttribute('verbose'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('registerMockObjectsFromTestArgumentsRecursively')) {
+ $result['registerMockObjectsFromTestArgumentsRecursively'] = $this->getBoolean(
+ (string) $root->getAttribute('registerMockObjectsFromTestArgumentsRecursively'),
+ false
+ );
+ }
+
+ if ($root->hasAttribute('extensionsDirectory')) {
+ $result['extensionsDirectory'] = $this->toAbsolutePath(
+ (string) $root->getAttribute(
+ 'extensionsDirectory'
+ )
+ );
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns the test suite configuration.
+ *
+ * @return PHPUnit_Framework_TestSuite
+ */
+ public function getTestSuiteConfiguration($testSuiteFilter = null)
+ {
+ $testSuiteNodes = $this->xpath->query('testsuites/testsuite');
+
+ if ($testSuiteNodes->length == 0) {
+ $testSuiteNodes = $this->xpath->query('testsuite');
+ }
+
+ if ($testSuiteNodes->length == 1) {
+ return $this->getTestSuite($testSuiteNodes->item(0), $testSuiteFilter);
+ }
+
+ if ($testSuiteNodes->length > 1) {
+ $suite = new PHPUnit_Framework_TestSuite;
+
+ foreach ($testSuiteNodes as $testSuiteNode) {
+ $suite->addTestSuite(
+ $this->getTestSuite($testSuiteNode, $testSuiteFilter)
+ );
+ }
+
+ return $suite;
+ }
+ }
+
+ /**
+ * Returns the test suite names from the configuration.
+ *
+ * @return array
+ */
+ public function getTestSuiteNames()
+ {
+ $names = [];
+ $nodes = $this->xpath->query('*/testsuite');
+ foreach ($nodes as $node) {
+ $names[] = $node->getAttribute('name');
+ }
+
+ return $names;
+ }
+
+ /**
+ * @param DOMElement $testSuiteNode
+ *
+ * @return PHPUnit_Framework_TestSuite
+ */
+ protected function getTestSuite(DOMElement $testSuiteNode, $testSuiteFilter = null)
+ {
+ if ($testSuiteNode->hasAttribute('name')) {
+ $suite = new PHPUnit_Framework_TestSuite(
+ (string) $testSuiteNode->getAttribute('name')
+ );
+ } else {
+ $suite = new PHPUnit_Framework_TestSuite;
+ }
+
+ $exclude = [];
+
+ foreach ($testSuiteNode->getElementsByTagName('exclude') as $excludeNode) {
+ $excludeFile = (string) $excludeNode->textContent;
+ if ($excludeFile) {
+ $exclude[] = $this->toAbsolutePath($excludeFile);
+ }
+ }
+
+ $fileIteratorFacade = new File_Iterator_Facade;
+
+ foreach ($testSuiteNode->getElementsByTagName('directory') as $directoryNode) {
+ if ($testSuiteFilter && $directoryNode->parentNode->getAttribute('name') != $testSuiteFilter) {
+ continue;
+ }
+
+ $directory = (string) $directoryNode->textContent;
+
+ if (empty($directory)) {
+ continue;
+ }
+
+ if ($directoryNode->hasAttribute('phpVersion')) {
+ $phpVersion = (string) $directoryNode->getAttribute('phpVersion');
+ } else {
+ $phpVersion = PHP_VERSION;
+ }
+
+ if ($directoryNode->hasAttribute('phpVersionOperator')) {
+ $phpVersionOperator = (string) $directoryNode->getAttribute('phpVersionOperator');
+ } else {
+ $phpVersionOperator = '>=';
+ }
+
+ if (!version_compare(PHP_VERSION, $phpVersion, $phpVersionOperator)) {
+ continue;
+ }
+
+ if ($directoryNode->hasAttribute('prefix')) {
+ $prefix = (string) $directoryNode->getAttribute('prefix');
+ } else {
+ $prefix = '';
+ }
+
+ if ($directoryNode->hasAttribute('suffix')) {
+ $suffix = (string) $directoryNode->getAttribute('suffix');
+ } else {
+ $suffix = 'Test.php';
+ }
+
+ $files = $fileIteratorFacade->getFilesAsArray(
+ $this->toAbsolutePath($directory),
+ $suffix,
+ $prefix,
+ $exclude
+ );
+ $suite->addTestFiles($files);
+ }
+
+ foreach ($testSuiteNode->getElementsByTagName('file') as $fileNode) {
+ if ($testSuiteFilter && $fileNode->parentNode->getAttribute('name') != $testSuiteFilter) {
+ continue;
+ }
+
+ $file = (string) $fileNode->textContent;
+
+ if (empty($file)) {
+ continue;
+ }
+
+ // Get the absolute path to the file
+ $file = $fileIteratorFacade->getFilesAsArray(
+ $this->toAbsolutePath($file)
+ );
+
+ if (!isset($file[0])) {
+ continue;
+ }
+
+ $file = $file[0];
+
+ if ($fileNode->hasAttribute('phpVersion')) {
+ $phpVersion = (string) $fileNode->getAttribute('phpVersion');
+ } else {
+ $phpVersion = PHP_VERSION;
+ }
+
+ if ($fileNode->hasAttribute('phpVersionOperator')) {
+ $phpVersionOperator = (string) $fileNode->getAttribute('phpVersionOperator');
+ } else {
+ $phpVersionOperator = '>=';
+ }
+
+ if (!version_compare(PHP_VERSION, $phpVersion, $phpVersionOperator)) {
+ continue;
+ }
+
+ $suite->addTestFile($file);
+ }
+
+ return $suite;
+ }
+
+ /**
+ * @param string $value
+ * @param bool $default
+ *
+ * @return bool
+ */
+ protected function getBoolean($value, $default)
+ {
+ if (strtolower($value) == 'false') {
+ return false;
+ } elseif (strtolower($value) == 'true') {
+ return true;
+ }
+
+ return $default;
+ }
+
+ /**
+ * @param string $value
+ * @param bool $default
+ *
+ * @return bool
+ */
+ protected function getInteger($value, $default)
+ {
+ if (is_numeric($value)) {
+ return (int) $value;
+ }
+
+ return $default;
+ }
+
+ /**
+ * @param string $query
+ *
+ * @return array
+ */
+ protected function readFilterDirectories($query)
+ {
+ $directories = [];
+
+ foreach ($this->xpath->query($query) as $directory) {
+ $directoryPath = (string) $directory->textContent;
+
+ if (!$directoryPath) {
+ continue;
+ }
+
+ if ($directory->hasAttribute('prefix')) {
+ $prefix = (string) $directory->getAttribute('prefix');
+ } else {
+ $prefix = '';
+ }
+
+ if ($directory->hasAttribute('suffix')) {
+ $suffix = (string) $directory->getAttribute('suffix');
+ } else {
+ $suffix = '.php';
+ }
+
+ if ($directory->hasAttribute('group')) {
+ $group = (string) $directory->getAttribute('group');
+ } else {
+ $group = 'DEFAULT';
+ }
+
+ $directories[] = [
+ 'path' => $this->toAbsolutePath($directoryPath),
+ 'prefix' => $prefix,
+ 'suffix' => $suffix,
+ 'group' => $group
+ ];
+ }
+
+ return $directories;
+ }
+
+ /**
+ * @param string $query
+ *
+ * @return array
+ */
+ protected function readFilterFiles($query)
+ {
+ $files = [];
+
+ foreach ($this->xpath->query($query) as $file) {
+ $filePath = (string) $file->textContent;
+
+ if ($filePath) {
+ $files[] = $this->toAbsolutePath($filePath);
+ }
+ }
+
+ return $files;
+ }
+
+ /**
+ * @param string $path
+ * @param bool $useIncludePath
+ *
+ * @return string
+ */
+ protected function toAbsolutePath($path, $useIncludePath = false)
+ {
+ $path = trim($path);
+
+ if ($path[0] === '/') {
+ return $path;
+ }
+
+ // Matches the following on Windows:
+ // - \\NetworkComputer\Path
+ // - \\.\D:
+ // - \\.\c:
+ // - C:\Windows
+ // - C:\windows
+ // - C:/windows
+ // - c:/windows
+ if (defined('PHP_WINDOWS_VERSION_BUILD') &&
+ ($path[0] === '\\' ||
+ (strlen($path) >= 3 && preg_match('#^[A-Z]\:[/\\\]#i', substr($path, 0, 3))))) {
+ return $path;
+ }
+
+ // Stream
+ if (strpos($path, '://') !== false) {
+ return $path;
+ }
+
+ $file = dirname($this->filename) . DIRECTORY_SEPARATOR . $path;
+
+ if ($useIncludePath && !file_exists($file)) {
+ $includePathFile = stream_resolve_include_path($path);
+
+ if ($includePathFile) {
+ $file = $includePathFile;
+ }
+ }
+
+ return $file;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/ConfigurationGenerator.php b/vendor/phpunit/phpunit/src/Util/ConfigurationGenerator.php
new file mode 100644
index 0000000..e1d9572
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/ConfigurationGenerator.php
@@ -0,0 +1,66 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Util_ConfigurationGenerator
+{
+ /**
+ * @var string
+ */
+ private $defaultTemplate = <<<EOT
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/{phpunit_version}/phpunit.xsd"
+ bootstrap="{bootstrap_script}"
+ backupGlobals="false"
+ beStrictAboutCoversAnnotation="true"
+ beStrictAboutOutputDuringTests="true"
+ beStrictAboutTestsThatDoNotTestAnything="true"
+ beStrictAboutTodoAnnotatedTests="true"
+ verbose="true">
+ <testsuite name="default">
+ <directory suffix="Test.php">{tests_directory}</directory>
+ </testsuite>
+
+ <filter>
+ <whitelist processUncoveredFilesFromWhitelist="true">
+ <directory suffix=".php">{src_directory}</directory>
+ </whitelist>
+ </filter>
+</phpunit>
+
+EOT;
+
+ /**
+ * @param string $phpunitVersion
+ * @param string $bootstrapScript
+ * @param string $testsDirectory
+ * @param string $srcDirectory
+ *
+ * @return string
+ */
+ public function generateDefaultConfiguration($phpunitVersion, $bootstrapScript, $testsDirectory, $srcDirectory)
+ {
+ return str_replace(
+ [
+ '{phpunit_version}',
+ '{bootstrap_script}',
+ '{tests_directory}',
+ '{src_directory}'
+ ],
+ [
+ $phpunitVersion,
+ $bootstrapScript,
+ $testsDirectory,
+ $srcDirectory
+ ],
+ $this->defaultTemplate
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/ErrorHandler.php b/vendor/phpunit/phpunit/src/Util/ErrorHandler.php
new file mode 100644
index 0000000..f62b110
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/ErrorHandler.php
@@ -0,0 +1,115 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+// Workaround for http://bugs.php.net/bug.php?id=47987,
+// see https://github.com/sebastianbergmann/phpunit/issues#issue/125 for details
+// Use dirname(__DIR__) instead of using /../ because of https://github.com/facebook/hhvm/issues/5215
+require_once dirname(__DIR__) . '/Framework/Error.php';
+require_once dirname(__DIR__) . '/Framework/Error/Notice.php';
+require_once dirname(__DIR__) . '/Framework/Error/Warning.php';
+require_once dirname(__DIR__) . '/Framework/Error/Deprecated.php';
+
+/**
+ * Error handler that converts PHP errors and warnings to exceptions.
+ */
+class PHPUnit_Util_ErrorHandler
+{
+ protected static $errorStack = [];
+
+ /**
+ * Returns the error stack.
+ *
+ * @return array
+ */
+ public static function getErrorStack()
+ {
+ return self::$errorStack;
+ }
+
+ /**
+ * @param int $errno
+ * @param string $errstr
+ * @param string $errfile
+ * @param int $errline
+ *
+ * @throws PHPUnit_Framework_Error
+ */
+ public static function handleError($errno, $errstr, $errfile, $errline)
+ {
+ if (!($errno & error_reporting())) {
+ return false;
+ }
+
+ self::$errorStack[] = [$errno, $errstr, $errfile, $errline];
+
+ $trace = debug_backtrace(false);
+ array_shift($trace);
+
+ foreach ($trace as $frame) {
+ if ($frame['function'] == '__toString') {
+ return false;
+ }
+ }
+
+ if ($errno == E_NOTICE || $errno == E_USER_NOTICE || $errno == E_STRICT) {
+ if (PHPUnit_Framework_Error_Notice::$enabled !== true) {
+ return false;
+ }
+
+ $exception = 'PHPUnit_Framework_Error_Notice';
+ } elseif ($errno == E_WARNING || $errno == E_USER_WARNING) {
+ if (PHPUnit_Framework_Error_Warning::$enabled !== true) {
+ return false;
+ }
+
+ $exception = 'PHPUnit_Framework_Error_Warning';
+ } elseif ($errno == E_DEPRECATED || $errno == E_USER_DEPRECATED) {
+ if (PHPUnit_Framework_Error_Deprecated::$enabled !== true) {
+ return false;
+ }
+
+ $exception = 'PHPUnit_Framework_Error_Deprecated';
+ } else {
+ $exception = 'PHPUnit_Framework_Error';
+ }
+
+ throw new $exception($errstr, $errno, $errfile, $errline);
+ }
+
+ /**
+ * Registers an error handler and returns a function that will restore
+ * the previous handler when invoked
+ *
+ * @param int $severity PHP predefined error constant
+ *
+ * @throws Exception if event of specified severity is emitted
+ */
+ public static function handleErrorOnce($severity = E_WARNING)
+ {
+ $terminator = function () {
+ static $expired = false;
+ if (!$expired) {
+ $expired = true;
+ // cleans temporary error handler
+ return restore_error_handler();
+ }
+ };
+
+ set_error_handler(function ($errno, $errstr) use ($severity) {
+ if ($errno === $severity) {
+ return;
+ }
+
+ return false;
+ });
+
+ return $terminator;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/Fileloader.php b/vendor/phpunit/phpunit/src/Util/Fileloader.php
new file mode 100644
index 0000000..14b048c
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/Fileloader.php
@@ -0,0 +1,68 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Utility methods to load PHP sourcefiles.
+ */
+class PHPUnit_Util_Fileloader
+{
+ /**
+ * Checks if a PHP sourcefile is readable.
+ * The sourcefile is loaded through the load() method.
+ *
+ * @param string $filename
+ *
+ * @return string
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public static function checkAndLoad($filename)
+ {
+ $includePathFilename = stream_resolve_include_path($filename);
+
+ if (!$includePathFilename || !is_readable($includePathFilename)) {
+ throw new PHPUnit_Framework_Exception(
+ sprintf('Cannot open file "%s".' . "\n", $filename)
+ );
+ }
+
+ self::load($includePathFilename);
+
+ return $includePathFilename;
+ }
+
+ /**
+ * Loads a PHP sourcefile.
+ *
+ * @param string $filename
+ *
+ * @return mixed
+ */
+ public static function load($filename)
+ {
+ $oldVariableNames = array_keys(get_defined_vars());
+
+ include_once $filename;
+
+ $newVariables = get_defined_vars();
+ $newVariableNames = array_diff(
+ array_keys($newVariables),
+ $oldVariableNames
+ );
+
+ foreach ($newVariableNames as $variableName) {
+ if ($variableName != 'oldVariableNames') {
+ $GLOBALS[$variableName] = $newVariables[$variableName];
+ }
+ }
+
+ return $filename;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/Filesystem.php b/vendor/phpunit/phpunit/src/Util/Filesystem.php
new file mode 100644
index 0000000..168c153
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/Filesystem.php
@@ -0,0 +1,38 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Filesystem helpers.
+ */
+class PHPUnit_Util_Filesystem
+{
+ /**
+ * @var array
+ */
+ protected static $buffer = [];
+
+ /**
+ * Maps class names to source file names:
+ * - PEAR CS: Foo_Bar_Baz -> Foo/Bar/Baz.php
+ * - Namespace: Foo\Bar\Baz -> Foo/Bar/Baz.php
+ *
+ * @param string $className
+ *
+ * @return string
+ */
+ public static function classNameToFilename($className)
+ {
+ return str_replace(
+ ['_', '\\'],
+ DIRECTORY_SEPARATOR,
+ $className
+ ) . '.php';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/Filter.php b/vendor/phpunit/phpunit/src/Util/Filter.php
new file mode 100644
index 0000000..9b7d55e
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/Filter.php
@@ -0,0 +1,103 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Utility class for code filtering.
+ */
+class PHPUnit_Util_Filter
+{
+ /**
+ * Filters stack frames from PHPUnit classes.
+ *
+ * @param Exception $e
+ * @param bool $asString
+ *
+ * @return string
+ */
+ public static function getFilteredStacktrace($e, $asString = true)
+ {
+ $prefix = false;
+ $script = realpath($GLOBALS['_SERVER']['SCRIPT_NAME']);
+
+ if (defined('__PHPUNIT_PHAR_ROOT__')) {
+ $prefix = __PHPUNIT_PHAR_ROOT__;
+ }
+
+ if ($asString === true) {
+ $filteredStacktrace = '';
+ } else {
+ $filteredStacktrace = [];
+ }
+
+ if ($e instanceof PHPUnit_Framework_SyntheticError) {
+ $eTrace = $e->getSyntheticTrace();
+ $eFile = $e->getSyntheticFile();
+ $eLine = $e->getSyntheticLine();
+ } elseif ($e instanceof PHPUnit_Framework_Exception) {
+ $eTrace = $e->getSerializableTrace();
+ $eFile = $e->getFile();
+ $eLine = $e->getLine();
+ } else {
+ if ($e->getPrevious()) {
+ $e = $e->getPrevious();
+ }
+ $eTrace = $e->getTrace();
+ $eFile = $e->getFile();
+ $eLine = $e->getLine();
+ }
+
+ if (!self::frameExists($eTrace, $eFile, $eLine)) {
+ array_unshift(
+ $eTrace,
+ ['file' => $eFile, 'line' => $eLine]
+ );
+ }
+
+ $blacklist = new PHPUnit_Util_Blacklist;
+
+ foreach ($eTrace as $frame) {
+ if (isset($frame['file']) && is_file($frame['file']) &&
+ !$blacklist->isBlacklisted($frame['file']) &&
+ ($prefix === false || strpos($frame['file'], $prefix) !== 0) &&
+ $frame['file'] !== $script) {
+ if ($asString === true) {
+ $filteredStacktrace .= sprintf(
+ "%s:%s\n",
+ $frame['file'],
+ isset($frame['line']) ? $frame['line'] : '?'
+ );
+ } else {
+ $filteredStacktrace[] = $frame;
+ }
+ }
+ }
+
+ return $filteredStacktrace;
+ }
+
+ /**
+ * @param array $trace
+ * @param string $file
+ * @param int $line
+ *
+ * @return bool
+ */
+ private static function frameExists(array $trace, $file, $line)
+ {
+ foreach ($trace as $frame) {
+ if (isset($frame['file']) && $frame['file'] == $file &&
+ isset($frame['line']) && $frame['line'] == $line) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/Getopt.php b/vendor/phpunit/phpunit/src/Util/Getopt.php
new file mode 100644
index 0000000..894778d
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/Getopt.php
@@ -0,0 +1,164 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Command-line options parsing class.
+ */
+class PHPUnit_Util_Getopt
+{
+ public static function getopt(array $args, $short_options, $long_options = null)
+ {
+ if (empty($args)) {
+ return [[], []];
+ }
+
+ $opts = [];
+ $non_opts = [];
+
+ if ($long_options) {
+ sort($long_options);
+ }
+
+ if (isset($args[0][0]) && $args[0][0] != '-') {
+ array_shift($args);
+ }
+
+ reset($args);
+
+ $args = array_map('trim', $args);
+
+ while (false !== $arg = current($args)) {
+ $i = key($args);
+ next($args);
+ if ($arg == '') {
+ continue;
+ }
+
+ if ($arg == '--') {
+ $non_opts = array_merge($non_opts, array_slice($args, $i + 1));
+
+ break;
+ }
+
+ if ($arg[0] != '-' || (strlen($arg) > 1 && $arg[1] == '-' && !$long_options)) {
+ $non_opts[] = $args[$i];
+
+ continue;
+ } elseif (strlen($arg) > 1 && $arg[1] == '-') {
+ self::parseLongOption(
+ substr($arg, 2),
+ $long_options,
+ $opts,
+ $args
+ );
+ } else {
+ self::parseShortOption(
+ substr($arg, 1),
+ $short_options,
+ $opts,
+ $args
+ );
+ }
+ }
+
+ return [$opts, $non_opts];
+ }
+
+ protected static function parseShortOption($arg, $short_options, &$opts, &$args)
+ {
+ $argLen = strlen($arg);
+
+ for ($i = 0; $i < $argLen; $i++) {
+ $opt = $arg[$i];
+ $opt_arg = null;
+
+ if (($spec = strstr($short_options, $opt)) === false || $arg[$i] == ':') {
+ throw new PHPUnit_Framework_Exception(
+ "unrecognized option -- $opt"
+ );
+ }
+
+ if (strlen($spec) > 1 && $spec[1] == ':') {
+ if ($i + 1 < $argLen) {
+ $opts[] = [$opt, substr($arg, $i + 1)];
+
+ break;
+ }
+ if (!(strlen($spec) > 2 && $spec[2] == ':')) {
+ if (false === $opt_arg = current($args)) {
+ throw new PHPUnit_Framework_Exception(
+ "option requires an argument -- $opt"
+ );
+ }
+ next($args);
+ }
+ }
+
+ $opts[] = [$opt, $opt_arg];
+ }
+ }
+
+ protected static function parseLongOption($arg, $long_options, &$opts, &$args)
+ {
+ $count = count($long_options);
+ $list = explode('=', $arg);
+ $opt = $list[0];
+ $opt_arg = null;
+
+ if (count($list) > 1) {
+ $opt_arg = $list[1];
+ }
+
+ $opt_len = strlen($opt);
+
+ for ($i = 0; $i < $count; $i++) {
+ $long_opt = $long_options[$i];
+ $opt_start = substr($long_opt, 0, $opt_len);
+
+ if ($opt_start != $opt) {
+ continue;
+ }
+
+ $opt_rest = substr($long_opt, $opt_len);
+
+ if ($opt_rest != '' && $opt[0] != '=' && $i + 1 < $count &&
+ $opt == substr($long_options[$i + 1], 0, $opt_len)) {
+ throw new PHPUnit_Framework_Exception(
+ "option --$opt is ambiguous"
+ );
+ }
+
+ if (substr($long_opt, -1) == '=') {
+ if (substr($long_opt, -2) != '==') {
+ if (!strlen($opt_arg)) {
+ if (false === $opt_arg = current($args)) {
+ throw new PHPUnit_Framework_Exception(
+ "option --$opt requires an argument"
+ );
+ }
+ next($args);
+ }
+ }
+ } elseif ($opt_arg) {
+ throw new PHPUnit_Framework_Exception(
+ "option --$opt doesn't allow an argument"
+ );
+ }
+
+ $full_option = '--' . preg_replace('/={1,2}$/', '', $long_opt);
+ $opts[] = [$full_option, $opt_arg];
+
+ return;
+ }
+
+ throw new PHPUnit_Framework_Exception("unrecognized option --$opt");
+ }
+}
+
diff --git a/vendor/phpunit/phpunit/src/Util/GlobalState.php b/vendor/phpunit/phpunit/src/Util/GlobalState.php
new file mode 100644
index 0000000..7235823
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/GlobalState.php
@@ -0,0 +1,214 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Util_GlobalState
+{
+ /**
+ * @var array
+ */
+ protected static $superGlobalArrays = [
+ '_ENV',
+ '_POST',
+ '_GET',
+ '_COOKIE',
+ '_SERVER',
+ '_FILES',
+ '_REQUEST'
+ ];
+
+ /**
+ * @var array
+ */
+ protected static $superGlobalArraysLong = [
+ 'HTTP_ENV_VARS',
+ 'HTTP_POST_VARS',
+ 'HTTP_GET_VARS',
+ 'HTTP_COOKIE_VARS',
+ 'HTTP_SERVER_VARS',
+ 'HTTP_POST_FILES'
+ ];
+
+ /**
+ * @return string
+ */
+ public static function getIncludedFilesAsString()
+ {
+ return static::processIncludedFilesAsString(get_included_files());
+ }
+
+ /**
+ * @param array $files
+ *
+ * @return string
+ */
+ public static function processIncludedFilesAsString(array $files)
+ {
+ $blacklist = new PHPUnit_Util_Blacklist;
+ $prefix = false;
+ $result = '';
+
+ if (defined('__PHPUNIT_PHAR__')) {
+ $prefix = 'phar://' . __PHPUNIT_PHAR__ . '/';
+ }
+
+ for ($i = count($files) - 1; $i > 0; $i--) {
+ $file = $files[$i];
+
+ if ($prefix !== false && strpos($file, $prefix) === 0) {
+ continue;
+ }
+
+ // Skip virtual file system protocols
+ if (preg_match('/^(vfs|phpvfs[a-z0-9]+):/', $file)) {
+ continue;
+ }
+
+ if (!$blacklist->isBlacklisted($file) && is_file($file)) {
+ $result = 'require_once \'' . $file . "';\n" . $result;
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * @return string
+ */
+ public static function getIniSettingsAsString()
+ {
+ $result = '';
+ $iniSettings = ini_get_all(null, false);
+
+ foreach ($iniSettings as $key => $value) {
+ $result .= sprintf(
+ '@ini_set(%s, %s);' . "\n",
+ self::exportVariable($key),
+ self::exportVariable($value)
+ );
+ }
+
+ return $result;
+ }
+
+ /**
+ * @return string
+ */
+ public static function getConstantsAsString()
+ {
+ $constants = get_defined_constants(true);
+ $result = '';
+
+ if (isset($constants['user'])) {
+ foreach ($constants['user'] as $name => $value) {
+ $result .= sprintf(
+ 'if (!defined(\'%s\')) define(\'%s\', %s);' . "\n",
+ $name,
+ $name,
+ self::exportVariable($value)
+ );
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * @return string
+ */
+ public static function getGlobalsAsString()
+ {
+ $result = '';
+ $superGlobalArrays = self::getSuperGlobalArrays();
+
+ foreach ($superGlobalArrays as $superGlobalArray) {
+ if (isset($GLOBALS[$superGlobalArray]) &&
+ is_array($GLOBALS[$superGlobalArray])) {
+ foreach (array_keys($GLOBALS[$superGlobalArray]) as $key) {
+ if ($GLOBALS[$superGlobalArray][$key] instanceof Closure) {
+ continue;
+ }
+
+ $result .= sprintf(
+ '$GLOBALS[\'%s\'][\'%s\'] = %s;' . "\n",
+ $superGlobalArray,
+ $key,
+ self::exportVariable($GLOBALS[$superGlobalArray][$key])
+ );
+ }
+ }
+ }
+
+ $blacklist = $superGlobalArrays;
+ $blacklist[] = 'GLOBALS';
+
+ foreach (array_keys($GLOBALS) as $key) {
+ if (!in_array($key, $blacklist) && !$GLOBALS[$key] instanceof Closure) {
+ $result .= sprintf(
+ '$GLOBALS[\'%s\'] = %s;' . "\n",
+ $key,
+ self::exportVariable($GLOBALS[$key])
+ );
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * @return array
+ */
+ protected static function getSuperGlobalArrays()
+ {
+ if (ini_get('register_long_arrays') == '1') {
+ return array_merge(
+ self::$superGlobalArrays,
+ self::$superGlobalArraysLong
+ );
+ } else {
+ return self::$superGlobalArrays;
+ }
+ }
+
+ protected static function exportVariable($variable)
+ {
+ if (is_scalar($variable) || is_null($variable) ||
+ (is_array($variable) && self::arrayOnlyContainsScalars($variable))) {
+ return var_export($variable, true);
+ }
+
+ return 'unserialize(' .
+ var_export(serialize($variable), true) .
+ ')';
+ }
+
+ /**
+ * @param array $array
+ *
+ * @return bool
+ */
+ protected static function arrayOnlyContainsScalars(array $array)
+ {
+ $result = true;
+
+ foreach ($array as $element) {
+ if (is_array($element)) {
+ $result = self::arrayOnlyContainsScalars($element);
+ } elseif (!is_scalar($element) && !is_null($element)) {
+ $result = false;
+ }
+
+ if ($result === false) {
+ break;
+ }
+ }
+
+ return $result;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/InvalidArgumentHelper.php b/vendor/phpunit/phpunit/src/Util/InvalidArgumentHelper.php
new file mode 100644
index 0000000..b7a8511
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/InvalidArgumentHelper.php
@@ -0,0 +1,39 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Factory for PHPUnit_Framework_Exception objects that are used to describe
+ * invalid arguments passed to a function or method.
+ */
+class PHPUnit_Util_InvalidArgumentHelper
+{
+ /**
+ * @param int $argument
+ * @param string $type
+ * @param mixed $value
+ *
+ * @return PHPUnit_Framework_Exception
+ */
+ public static function factory($argument, $type, $value = null)
+ {
+ $stack = debug_backtrace(false);
+
+ return new PHPUnit_Framework_Exception(
+ sprintf(
+ 'Argument #%d%sof %s::%s() must be a %s',
+ $argument,
+ $value !== null ? ' (' . gettype($value) . '#' . $value . ')' : ' (No Value) ',
+ $stack[1]['class'],
+ $stack[1]['function'],
+ $type
+ )
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/Log/JSON.php b/vendor/phpunit/phpunit/src/Util/Log/JSON.php
new file mode 100644
index 0000000..7576993
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/Log/JSON.php
@@ -0,0 +1,254 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A TestListener that generates JSON messages.
+ */
+class PHPUnit_Util_Log_JSON extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
+{
+ /**
+ * @var string
+ */
+ protected $currentTestSuiteName = '';
+
+ /**
+ * @var string
+ */
+ protected $currentTestName = '';
+
+ /**
+ * @var bool
+ */
+ protected $currentTestPass = true;
+
+ /**
+ * An error occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->writeCase(
+ 'error',
+ $time,
+ PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
+ PHPUnit_Framework_TestFailure::exceptionToString($e),
+ $test
+ );
+
+ $this->currentTestPass = false;
+ }
+
+ /**
+ * A warning occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_Warning $e
+ * @param float $time
+ */
+ public function addWarning(PHPUnit_Framework_Test $test, PHPUnit_Framework_Warning $e, $time)
+ {
+ $this->writeCase(
+ 'warning',
+ $time,
+ PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
+ PHPUnit_Framework_TestFailure::exceptionToString($e),
+ $test
+ );
+
+ $this->currentTestPass = false;
+ }
+
+ /**
+ * A failure occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_AssertionFailedError $e
+ * @param float $time
+ */
+ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
+ {
+ $this->writeCase(
+ 'fail',
+ $time,
+ PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
+ PHPUnit_Framework_TestFailure::exceptionToString($e),
+ $test
+ );
+
+ $this->currentTestPass = false;
+ }
+
+ /**
+ * Incomplete test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->writeCase(
+ 'error',
+ $time,
+ PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
+ 'Incomplete Test: ' . $e->getMessage(),
+ $test
+ );
+
+ $this->currentTestPass = false;
+ }
+
+ /**
+ * Risky test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->writeCase(
+ 'error',
+ $time,
+ PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
+ 'Risky Test: ' . $e->getMessage(),
+ $test
+ );
+
+ $this->currentTestPass = false;
+ }
+
+ /**
+ * Skipped test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->writeCase(
+ 'error',
+ $time,
+ PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
+ 'Skipped Test: ' . $e->getMessage(),
+ $test
+ );
+
+ $this->currentTestPass = false;
+ }
+
+ /**
+ * A testsuite started.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ $this->currentTestSuiteName = $suite->getName();
+ $this->currentTestName = '';
+
+ $this->write(
+ [
+ 'event' => 'suiteStart',
+ 'suite' => $this->currentTestSuiteName,
+ 'tests' => count($suite)
+ ]
+ );
+ }
+
+ /**
+ * A testsuite ended.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ $this->currentTestSuiteName = '';
+ $this->currentTestName = '';
+ }
+
+ /**
+ * A test started.
+ *
+ * @param PHPUnit_Framework_Test $test
+ */
+ public function startTest(PHPUnit_Framework_Test $test)
+ {
+ $this->currentTestName = PHPUnit_Util_Test::describe($test);
+ $this->currentTestPass = true;
+
+ $this->write(
+ [
+ 'event' => 'testStart',
+ 'suite' => $this->currentTestSuiteName,
+ 'test' => $this->currentTestName
+ ]
+ );
+ }
+
+ /**
+ * A test ended.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param float $time
+ */
+ public function endTest(PHPUnit_Framework_Test $test, $time)
+ {
+ if ($this->currentTestPass) {
+ $this->writeCase('pass', $time, [], '', $test);
+ }
+ }
+
+ /**
+ * @param string $status
+ * @param float $time
+ * @param array $trace
+ * @param string $message
+ * @param PHPUnit_Framework_TestCase|null $test
+ */
+ protected function writeCase($status, $time, array $trace = [], $message = '', $test = null)
+ {
+ $output = '';
+ // take care of TestSuite producing error (e.g. by running into exception) as TestSuite doesn't have hasOutput
+ if ($test !== null && method_exists($test, 'hasOutput') && $test->hasOutput()) {
+ $output = $test->getActualOutput();
+ }
+ $this->write(
+ [
+ 'event' => 'test',
+ 'suite' => $this->currentTestSuiteName,
+ 'test' => $this->currentTestName,
+ 'status' => $status,
+ 'time' => $time,
+ 'trace' => $trace,
+ 'message' => PHPUnit_Util_String::convertToUtf8($message),
+ 'output' => $output,
+ ]
+ );
+ }
+
+ /**
+ * @param string $buffer
+ */
+ public function write($buffer)
+ {
+ array_walk_recursive($buffer, function (&$input) {
+ if (is_string($input)) {
+ $input = PHPUnit_Util_String::convertToUtf8($input);
+ }
+ });
+
+ parent::write(json_encode($buffer, JSON_PRETTY_PRINT));
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/Log/JUnit.php b/vendor/phpunit/phpunit/src/Util/Log/JUnit.php
new file mode 100644
index 0000000..2beda32
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/Log/JUnit.php
@@ -0,0 +1,450 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A TestListener that generates a logfile of the test execution in XML markup.
+ *
+ * The XML markup used is the same as the one that is used by the JUnit Ant task.
+ */
+class PHPUnit_Util_Log_JUnit extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
+{
+ /**
+ * @var DOMDocument
+ */
+ protected $document;
+
+ /**
+ * @var DOMElement
+ */
+ protected $root;
+
+ /**
+ * @var bool
+ */
+ protected $logIncompleteSkipped = false;
+
+ /**
+ * @var bool
+ */
+ protected $writeDocument = true;
+
+ /**
+ * @var DOMElement[]
+ */
+ protected $testSuites = [];
+
+ /**
+ * @var int[]
+ */
+ protected $testSuiteTests = [0];
+
+ /**
+ * @var int[]
+ */
+ protected $testSuiteAssertions = [0];
+
+ /**
+ * @var int[]
+ */
+ protected $testSuiteErrors = [0];
+
+ /**
+ * @var int[]
+ */
+ protected $testSuiteFailures = [0];
+
+ /**
+ * @var int[]
+ */
+ protected $testSuiteTimes = [0];
+
+ /**
+ * @var int
+ */
+ protected $testSuiteLevel = 0;
+
+ /**
+ * @var DOMElement
+ */
+ protected $currentTestCase = null;
+
+ /**
+ * @var bool
+ */
+ protected $attachCurrentTestCase = true;
+
+ /**
+ * Constructor.
+ *
+ * @param mixed $out
+ * @param bool $logIncompleteSkipped
+ */
+ public function __construct($out = null, $logIncompleteSkipped = false)
+ {
+ $this->document = new DOMDocument('1.0', 'UTF-8');
+ $this->document->formatOutput = true;
+
+ $this->root = $this->document->createElement('testsuites');
+ $this->document->appendChild($this->root);
+
+ parent::__construct($out);
+
+ $this->logIncompleteSkipped = $logIncompleteSkipped;
+ }
+
+ /**
+ * Flush buffer and close output.
+ */
+ public function flush()
+ {
+ if ($this->writeDocument === true) {
+ $this->write($this->getXML());
+ }
+
+ parent::flush();
+ }
+
+ /**
+ * An error occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->doAddFault($test, $e, $time, 'error');
+ $this->testSuiteErrors[$this->testSuiteLevel]++;
+ }
+
+ /**
+ * A warning occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_Warning $e
+ * @param float $time
+ */
+ public function addWarning(PHPUnit_Framework_Test $test, PHPUnit_Framework_Warning $e, $time)
+ {
+ if (!$this->logIncompleteSkipped) {
+ return;
+ }
+
+ $this->doAddFault($test, $e, $time, 'warning');
+ $this->testSuiteFailures[$this->testSuiteLevel]++;
+ }
+
+ /**
+ * A failure occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_AssertionFailedError $e
+ * @param float $time
+ */
+ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
+ {
+ $this->doAddFault($test, $e, $time, 'failure');
+ $this->testSuiteFailures[$this->testSuiteLevel]++;
+ }
+
+ /**
+ * Incomplete test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ if ($this->logIncompleteSkipped && $this->currentTestCase !== null) {
+ $error = $this->document->createElement(
+ 'error',
+ PHPUnit_Util_XML::prepareString(
+ "Incomplete Test\n" .
+ PHPUnit_Util_Filter::getFilteredStacktrace($e)
+ )
+ );
+
+ $error->setAttribute('type', get_class($e));
+
+ $this->currentTestCase->appendChild($error);
+
+ $this->testSuiteErrors[$this->testSuiteLevel]++;
+ } else {
+ $this->attachCurrentTestCase = false;
+ }
+ }
+
+ /**
+ * Risky test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ if ($this->logIncompleteSkipped && $this->currentTestCase !== null) {
+ $error = $this->document->createElement(
+ 'error',
+ PHPUnit_Util_XML::prepareString(
+ "Risky Test\n" .
+ PHPUnit_Util_Filter::getFilteredStacktrace($e)
+ )
+ );
+
+ $error->setAttribute('type', get_class($e));
+
+ $this->currentTestCase->appendChild($error);
+
+ $this->testSuiteErrors[$this->testSuiteLevel]++;
+ } else {
+ $this->attachCurrentTestCase = false;
+ }
+ }
+
+ /**
+ * Skipped test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ if ($this->logIncompleteSkipped && $this->currentTestCase !== null) {
+ $error = $this->document->createElement(
+ 'error',
+ PHPUnit_Util_XML::prepareString(
+ "Skipped Test\n" .
+ PHPUnit_Util_Filter::getFilteredStacktrace($e)
+ )
+ );
+
+ $error->setAttribute('type', get_class($e));
+
+ $this->currentTestCase->appendChild($error);
+
+ $this->testSuiteErrors[$this->testSuiteLevel]++;
+ } else {
+ $this->attachCurrentTestCase = false;
+ }
+ }
+
+ /**
+ * A testsuite started.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ $testSuite = $this->document->createElement('testsuite');
+ $testSuite->setAttribute('name', $suite->getName());
+
+ if (class_exists($suite->getName(), false)) {
+ try {
+ $class = new ReflectionClass($suite->getName());
+
+ $testSuite->setAttribute('file', $class->getFileName());
+ } catch (ReflectionException $e) {
+ }
+ }
+
+ if ($this->testSuiteLevel > 0) {
+ $this->testSuites[$this->testSuiteLevel]->appendChild($testSuite);
+ } else {
+ $this->root->appendChild($testSuite);
+ }
+
+ $this->testSuiteLevel++;
+ $this->testSuites[$this->testSuiteLevel] = $testSuite;
+ $this->testSuiteTests[$this->testSuiteLevel] = 0;
+ $this->testSuiteAssertions[$this->testSuiteLevel] = 0;
+ $this->testSuiteErrors[$this->testSuiteLevel] = 0;
+ $this->testSuiteFailures[$this->testSuiteLevel] = 0;
+ $this->testSuiteTimes[$this->testSuiteLevel] = 0;
+ }
+
+ /**
+ * A testsuite ended.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ $this->testSuites[$this->testSuiteLevel]->setAttribute(
+ 'tests',
+ $this->testSuiteTests[$this->testSuiteLevel]
+ );
+
+ $this->testSuites[$this->testSuiteLevel]->setAttribute(
+ 'assertions',
+ $this->testSuiteAssertions[$this->testSuiteLevel]
+ );
+
+ $this->testSuites[$this->testSuiteLevel]->setAttribute(
+ 'failures',
+ $this->testSuiteFailures[$this->testSuiteLevel]
+ );
+
+ $this->testSuites[$this->testSuiteLevel]->setAttribute(
+ 'errors',
+ $this->testSuiteErrors[$this->testSuiteLevel]
+ );
+
+ $this->testSuites[$this->testSuiteLevel]->setAttribute(
+ 'time',
+ sprintf('%F', $this->testSuiteTimes[$this->testSuiteLevel])
+ );
+
+ if ($this->testSuiteLevel > 1) {
+ $this->testSuiteTests[$this->testSuiteLevel - 1] += $this->testSuiteTests[$this->testSuiteLevel];
+ $this->testSuiteAssertions[$this->testSuiteLevel - 1] += $this->testSuiteAssertions[$this->testSuiteLevel];
+ $this->testSuiteErrors[$this->testSuiteLevel - 1] += $this->testSuiteErrors[$this->testSuiteLevel];
+ $this->testSuiteFailures[$this->testSuiteLevel - 1] += $this->testSuiteFailures[$this->testSuiteLevel];
+ $this->testSuiteTimes[$this->testSuiteLevel - 1] += $this->testSuiteTimes[$this->testSuiteLevel];
+ }
+
+ $this->testSuiteLevel--;
+ }
+
+ /**
+ * A test started.
+ *
+ * @param PHPUnit_Framework_Test $test
+ */
+ public function startTest(PHPUnit_Framework_Test $test)
+ {
+ $testCase = $this->document->createElement('testcase');
+ $testCase->setAttribute('name', $test->getName());
+
+ if ($test instanceof PHPUnit_Framework_TestCase) {
+ $class = new ReflectionClass($test);
+ $methodName = $test->getName();
+
+ if ($class->hasMethod($methodName)) {
+ $method = $class->getMethod($test->getName());
+
+ $testCase->setAttribute('class', $class->getName());
+ $testCase->setAttribute('file', $class->getFileName());
+ $testCase->setAttribute('line', $method->getStartLine());
+ }
+ }
+
+ $this->currentTestCase = $testCase;
+ }
+
+ /**
+ * A test ended.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param float $time
+ */
+ public function endTest(PHPUnit_Framework_Test $test, $time)
+ {
+ if ($this->attachCurrentTestCase) {
+ if ($test instanceof PHPUnit_Framework_TestCase) {
+ $numAssertions = $test->getNumAssertions();
+ $this->testSuiteAssertions[$this->testSuiteLevel] += $numAssertions;
+
+ $this->currentTestCase->setAttribute(
+ 'assertions',
+ $numAssertions
+ );
+ }
+
+ $this->currentTestCase->setAttribute(
+ 'time',
+ sprintf('%F', $time)
+ );
+
+ $this->testSuites[$this->testSuiteLevel]->appendChild(
+ $this->currentTestCase
+ );
+
+ $this->testSuiteTests[$this->testSuiteLevel]++;
+ $this->testSuiteTimes[$this->testSuiteLevel] += $time;
+
+ if (method_exists($test, 'hasOutput') && $test->hasOutput()) {
+ $systemOut = $this->document->createElement('system-out');
+ $systemOut->appendChild(
+ $this->document->createTextNode($test->getActualOutput())
+ );
+ $this->currentTestCase->appendChild($systemOut);
+ }
+ }
+
+ $this->attachCurrentTestCase = true;
+ $this->currentTestCase = null;
+ }
+
+ /**
+ * Returns the XML as a string.
+ *
+ * @return string
+ */
+ public function getXML()
+ {
+ return $this->document->saveXML();
+ }
+
+ /**
+ * Enables or disables the writing of the document
+ * in flush().
+ *
+ * This is a "hack" needed for the integration of
+ * PHPUnit with Phing.
+ *
+ * @return string
+ */
+ public function setWriteDocument($flag)
+ {
+ if (is_bool($flag)) {
+ $this->writeDocument = $flag;
+ }
+ }
+
+ /**
+ * Method which generalizes addError() and addFailure()
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ * @param string $type
+ */
+ private function doAddFault(PHPUnit_Framework_Test $test, Exception $e, $time, $type)
+ {
+ if ($this->currentTestCase === null) {
+ return;
+ }
+
+ if ($test instanceof PHPUnit_Framework_SelfDescribing) {
+ $buffer = $test->toString() . PHP_EOL;
+ } else {
+ $buffer = '';
+ }
+
+ $buffer .= PHPUnit_Framework_TestFailure::exceptionToString($e) . PHP_EOL .
+ PHPUnit_Util_Filter::getFilteredStacktrace($e);
+
+ $fault = $this->document->createElement(
+ $type,
+ PHPUnit_Util_XML::prepareString($buffer)
+ );
+
+ if ($e instanceof PHPUnit_Framework_ExceptionWrapper) {
+ $fault->setAttribute('type', $e->getClassName());
+ } else {
+ $fault->setAttribute('type', get_class($e));
+ }
+
+ $this->currentTestCase->appendChild($fault);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/Log/TAP.php b/vendor/phpunit/phpunit/src/Util/Log/TAP.php
new file mode 100644
index 0000000..72161af
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/Log/TAP.php
@@ -0,0 +1,261 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A TestListener that generates a logfile of the
+ * test execution using the Test Anything Protocol (TAP).
+ */
+class PHPUnit_Util_Log_TAP extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
+{
+ /**
+ * @var int
+ */
+ protected $testNumber = 0;
+
+ /**
+ * @var int
+ */
+ protected $testSuiteLevel = 0;
+
+ /**
+ * @var bool
+ */
+ protected $testSuccessful = true;
+
+ /**
+ * Constructor.
+ *
+ * @param mixed $out
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function __construct($out = null)
+ {
+ parent::__construct($out);
+ $this->write("TAP version 13\n");
+ }
+
+ /**
+ * An error occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->writeNotOk($test, 'Error');
+ }
+
+ /**
+ * A warning occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_Warning $e
+ * @param float $time
+ */
+ public function addWarning(PHPUnit_Framework_Test $test, PHPUnit_Framework_Warning $e, $time)
+ {
+ $this->writeNotOk($test, 'Warning');
+ }
+
+ /**
+ * A failure occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_AssertionFailedError $e
+ * @param float $time
+ */
+ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
+ {
+ $this->writeNotOk($test, 'Failure');
+
+ $message = explode(
+ "\n",
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ $diagnostic = [
+ 'message' => $message[0],
+ 'severity' => 'fail'
+ ];
+
+ if ($e instanceof PHPUnit_Framework_ExpectationFailedException) {
+ $cf = $e->getComparisonFailure();
+
+ if ($cf !== null) {
+ $diagnostic['data'] = [
+ 'got' => $cf->getActual(),
+ 'expected' => $cf->getExpected()
+ ];
+ }
+ }
+
+ $yaml = new Symfony\Component\Yaml\Dumper;
+
+ $this->write(
+ sprintf(
+ " ---\n%s ...\n",
+ $yaml->dump($diagnostic, 2, 2)
+ )
+ );
+ }
+
+ /**
+ * Incomplete test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->writeNotOk($test, '', 'TODO Incomplete Test');
+ }
+
+ /**
+ * Risky test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->write(
+ sprintf(
+ "ok %d - # RISKY%s\n",
+ $this->testNumber,
+ $e->getMessage() != '' ? ' ' . $e->getMessage() : ''
+ )
+ );
+
+ $this->testSuccessful = false;
+ }
+
+ /**
+ * Skipped test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->write(
+ sprintf(
+ "ok %d - # SKIP%s\n",
+ $this->testNumber,
+ $e->getMessage() != '' ? ' ' . $e->getMessage() : ''
+ )
+ );
+
+ $this->testSuccessful = false;
+ }
+
+ /**
+ * A testsuite started.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ $this->testSuiteLevel++;
+ }
+
+ /**
+ * A testsuite ended.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ $this->testSuiteLevel--;
+
+ if ($this->testSuiteLevel == 0) {
+ $this->write(sprintf("1..%d\n", $this->testNumber));
+ }
+ }
+
+ /**
+ * A test started.
+ *
+ * @param PHPUnit_Framework_Test $test
+ */
+ public function startTest(PHPUnit_Framework_Test $test)
+ {
+ $this->testNumber++;
+ $this->testSuccessful = true;
+ }
+
+ /**
+ * A test ended.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param float $time
+ */
+ public function endTest(PHPUnit_Framework_Test $test, $time)
+ {
+ if ($this->testSuccessful === true) {
+ $this->write(
+ sprintf(
+ "ok %d - %s\n",
+ $this->testNumber,
+ PHPUnit_Util_Test::describe($test)
+ )
+ );
+ }
+
+ $this->writeDiagnostics($test);
+ }
+
+ /**
+ * @param PHPUnit_Framework_Test $test
+ * @param string $prefix
+ * @param string $directive
+ */
+ protected function writeNotOk(PHPUnit_Framework_Test $test, $prefix = '', $directive = '')
+ {
+ $this->write(
+ sprintf(
+ "not ok %d - %s%s%s\n",
+ $this->testNumber,
+ $prefix != '' ? $prefix . ': ' : '',
+ PHPUnit_Util_Test::describe($test),
+ $directive != '' ? ' # ' . $directive : ''
+ )
+ );
+
+ $this->testSuccessful = false;
+ }
+
+ /**
+ * @param PHPUnit_Framework_Test $test
+ */
+ private function writeDiagnostics(PHPUnit_Framework_Test $test)
+ {
+ if (!$test instanceof PHPUnit_Framework_TestCase) {
+ return;
+ }
+
+ if (!$test->hasOutput()) {
+ return;
+ }
+
+ foreach (explode("\n", trim($test->getActualOutput())) as $line) {
+ $this->write(
+ sprintf(
+ "# %s\n",
+ $line
+ )
+ );
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/Log/TeamCity.php b/vendor/phpunit/phpunit/src/Util/Log/TeamCity.php
new file mode 100644
index 0000000..399efb9
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/Log/TeamCity.php
@@ -0,0 +1,406 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use SebastianBergmann\Comparator\ComparisonFailure;
+
+/**
+ * A TestListener that generates a logfile of the test execution using the
+ * TeamCity format (for use with PhpStorm, for instance).
+ */
+class PHPUnit_Util_Log_TeamCity extends PHPUnit_TextUI_ResultPrinter
+{
+ /**
+ * @var bool
+ */
+ private $isSummaryTestCountPrinted = false;
+
+ /**
+ * @var string
+ */
+ private $startedTestName;
+
+ /**
+ * @var string
+ */
+ private $flowId;
+
+ /**
+ * @param string $progress
+ */
+ protected function writeProgress($progress)
+ {
+ }
+
+ /**
+ * @param PHPUnit_Framework_TestResult $result
+ */
+ public function printResult(PHPUnit_Framework_TestResult $result)
+ {
+ $this->printHeader();
+ $this->printFooter($result);
+ }
+
+ /**
+ * An error occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->printEvent(
+ 'testFailed',
+ [
+ 'name' => $test->getName(),
+ 'message' => self::getMessage($e),
+ 'details' => self::getDetails($e),
+ ]
+ );
+ }
+
+ /**
+ * A warning occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_Warning $e
+ * @param float $time
+ */
+ public function addWarning(PHPUnit_Framework_Test $test, PHPUnit_Framework_Warning $e, $time)
+ {
+ $this->printEvent(
+ 'testFailed',
+ [
+ 'name' => $test->getName(),
+ 'message' => self::getMessage($e),
+ 'details' => self::getDetails($e)
+ ]
+ );
+ }
+
+ /**
+ * A failure occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_AssertionFailedError $e
+ * @param float $time
+ */
+ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
+ {
+ $parameters = [
+ 'name' => $test->getName(),
+ 'message' => self::getMessage($e),
+ 'details' => self::getDetails($e),
+ ];
+
+ if ($e instanceof PHPUnit_Framework_ExpectationFailedException) {
+ $comparisonFailure = $e->getComparisonFailure();
+
+ if ($comparisonFailure instanceof ComparisonFailure) {
+ $expectedString = $comparisonFailure->getExpectedAsString();
+
+ if (is_null($expectedString) || empty($expectedString)) {
+ $expectedString = self::getPrimitiveValueAsString($comparisonFailure->getExpected());
+ }
+
+ $actualString = $comparisonFailure->getActualAsString();
+
+ if (is_null($actualString) || empty($actualString)) {
+ $actualString = self::getPrimitiveValueAsString($comparisonFailure->getActual());
+ }
+
+ if (!is_null($actualString) && !is_null($expectedString)) {
+ $parameters['type'] = 'comparisonFailure';
+ $parameters['actual'] = $actualString;
+ $parameters['expected'] = $expectedString;
+ }
+ }
+ }
+
+ $this->printEvent('testFailed', $parameters);
+ }
+
+ /**
+ * Incomplete test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->printIgnoredTest($test->getName(), $e);
+ }
+
+ /**
+ * Risky test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->addError($test, $e, $time);
+ }
+
+ /**
+ * Skipped test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $testName = $test->getName();
+ if ($this->startedTestName != $testName) {
+ $this->startTest($test);
+ $this->printIgnoredTest($testName, $e);
+ $this->endTest($test, $time);
+ } else {
+ $this->printIgnoredTest($testName, $e);
+ }
+ }
+
+ public function printIgnoredTest($testName, Exception $e)
+ {
+ $this->printEvent(
+ 'testIgnored',
+ [
+ 'name' => $testName,
+ 'message' => self::getMessage($e),
+ 'details' => self::getDetails($e),
+ ]
+ );
+ }
+
+ /**
+ * A testsuite started.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ if (stripos(ini_get('disable_functions'), 'getmypid') === false) {
+ $this->flowId = getmypid();
+ } else {
+ $this->flowId = false;
+ }
+
+ if (!$this->isSummaryTestCountPrinted) {
+ $this->isSummaryTestCountPrinted = true;
+
+ $this->printEvent(
+ 'testCount',
+ ['count' => count($suite)]
+ );
+ }
+
+ $suiteName = $suite->getName();
+
+ if (empty($suiteName)) {
+ return;
+ }
+
+ $parameters = ['name' => $suiteName];
+
+ if (class_exists($suiteName, false)) {
+ $fileName = self::getFileName($suiteName);
+ $parameters['locationHint'] = "php_qn://$fileName::\\$suiteName";
+ } else {
+ $split = preg_split('/::/', $suiteName);
+
+ if (count($split) == 2 && method_exists($split[0], $split[1])) {
+ $fileName = self::getFileName($split[0]);
+ $parameters['locationHint'] = "php_qn://$fileName::\\$suiteName";
+ $parameters['name'] = $split[1];
+ }
+ }
+
+ $this->printEvent('testSuiteStarted', $parameters);
+ }
+
+ /**
+ * A testsuite ended.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ $suiteName = $suite->getName();
+
+ if (empty($suiteName)) {
+ return;
+ }
+
+ $parameters = ['name' => $suiteName];
+
+ if (!class_exists($suiteName, false)) {
+ $split = preg_split('/::/', $suiteName);
+
+ if (count($split) == 2 && method_exists($split[0], $split[1])) {
+ $parameters['name'] = $split[1];
+ }
+ }
+
+ $this->printEvent('testSuiteFinished', $parameters);
+ }
+
+ /**
+ * A test started.
+ *
+ * @param PHPUnit_Framework_Test $test
+ */
+ public function startTest(PHPUnit_Framework_Test $test)
+ {
+ $testName = $test->getName();
+ $this->startedTestName = $testName;
+ $params = ['name' => $testName];
+
+ if ($test instanceof PHPUnit_Framework_TestCase) {
+ $className = get_class($test);
+ $fileName = self::getFileName($className);
+ $params['locationHint'] = "php_qn://$fileName::\\$className::$testName";
+ }
+
+ $this->printEvent('testStarted', $params);
+ }
+
+ /**
+ * A test ended.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param float $time
+ */
+ public function endTest(PHPUnit_Framework_Test $test, $time)
+ {
+ parent::endTest($test, $time);
+
+ $this->printEvent(
+ 'testFinished',
+ [
+ 'name' => $test->getName(),
+ 'duration' => (int) (round($time, 2) * 1000)
+ ]
+ );
+ }
+
+ /**
+ * @param string $eventName
+ * @param array $params
+ */
+ private function printEvent($eventName, $params = [])
+ {
+ $this->write("\n##teamcity[$eventName");
+
+ if ($this->flowId) {
+ $params['flowId'] = $this->flowId;
+ }
+
+ foreach ($params as $key => $value) {
+ $escapedValue = self::escapeValue($value);
+ $this->write(" $key='$escapedValue'");
+ }
+
+ $this->write("]\n");
+ }
+
+ /**
+ * @param Exception $e
+ *
+ * @return string
+ */
+ private static function getMessage(Exception $e)
+ {
+ $message = '';
+
+ if ($e instanceof PHPUnit_Framework_ExceptionWrapper) {
+ if (strlen($e->getClassName()) != 0) {
+ $message = $message . $e->getClassName();
+ }
+
+ if (strlen($message) != 0 && strlen($e->getMessage()) != 0) {
+ $message = $message . ' : ';
+ }
+ }
+
+ return $message . $e->getMessage();
+ }
+
+ /**
+ * @param Exception $e
+ *
+ * @return string
+ */
+ private static function getDetails(Exception $e)
+ {
+ $stackTrace = PHPUnit_Util_Filter::getFilteredStacktrace($e);
+ $previous = $e->getPrevious();
+
+ while ($previous) {
+ $stackTrace .= "\nCaused by\n" .
+ PHPUnit_Framework_TestFailure::exceptionToString($previous) . "\n" .
+ PHPUnit_Util_Filter::getFilteredStacktrace($previous);
+
+ $previous = $previous->getPrevious();
+ }
+
+ return ' ' . str_replace("\n", "\n ", $stackTrace);
+ }
+
+ /**
+ * @param mixed $value
+ *
+ * @return string
+ */
+ private static function getPrimitiveValueAsString($value)
+ {
+ if (is_null($value)) {
+ return 'null';
+ } elseif (is_bool($value)) {
+ return $value == true ? 'true' : 'false';
+ } elseif (is_scalar($value)) {
+ return print_r($value, true);
+ }
+
+ return;
+ }
+
+ /**
+ * @param $text
+ *
+ * @return string
+ */
+ private static function escapeValue($text)
+ {
+ $text = str_replace('|', '||', $text);
+ $text = str_replace("'", "|'", $text);
+ $text = str_replace("\n", '|n', $text);
+ $text = str_replace("\r", '|r', $text);
+ $text = str_replace(']', '|]', $text);
+ $text = str_replace('[', '|[', $text);
+
+ return $text;
+ }
+
+ /**
+ * @param string $className
+ *
+ * @return string
+ */
+ private static function getFileName($className)
+ {
+ $reflectionClass = new ReflectionClass($className);
+ $fileName = $reflectionClass->getFileName();
+
+ return $fileName;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/PHP.php b/vendor/phpunit/phpunit/src/Util/PHP.php
new file mode 100644
index 0000000..47d6347
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/PHP.php
@@ -0,0 +1,410 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use SebastianBergmann\Environment\Runtime;
+
+/**
+ * Utility methods for PHP sub-processes.
+ */
+abstract class PHPUnit_Util_PHP
+{
+ /**
+ * @var Runtime
+ */
+ protected $runtime;
+
+ /**
+ * @var bool
+ */
+ protected $stderrRedirection = false;
+
+ /**
+ * @var string
+ */
+ protected $stdin = '';
+
+ /**
+ * @var string
+ */
+ protected $args = '';
+
+ /**
+ * @var array
+ */
+ protected $env = [];
+
+ /**
+ * @var int
+ */
+ protected $timeout = 0;
+
+ /**
+ * Creates internal Runtime instance.
+ */
+ public function __construct()
+ {
+ $this->runtime = new Runtime();
+ }
+
+ /**
+ * Defines if should use STDERR redirection or not.
+ *
+ * Then $stderrRedirection is TRUE, STDERR is redirected to STDOUT.
+ *
+ * @throws PHPUnit_Framework_Exception
+ *
+ * @param bool $stderrRedirection
+ */
+ public function setUseStderrRedirection($stderrRedirection)
+ {
+ if (!is_bool($stderrRedirection)) {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+
+ $this->stderrRedirection = $stderrRedirection;
+ }
+
+ /**
+ * Returns TRUE if uses STDERR redirection or FALSE if not.
+ *
+ * @return bool
+ */
+ public function useStderrRedirection()
+ {
+ return $this->stderrRedirection;
+ }
+
+ /**
+ * Sets the input string to be sent via STDIN
+ *
+ * @param string $stdin
+ */
+ public function setStdin($stdin)
+ {
+ $this->stdin = (string) $stdin;
+ }
+
+ /**
+ * Returns the input string to be sent via STDIN
+ *
+ * @return string
+ */
+ public function getStdin()
+ {
+ return $this->stdin;
+ }
+
+ /**
+ * Sets the string of arguments to pass to the php job
+ *
+ * @param string $args
+ */
+ public function setArgs($args)
+ {
+ $this->args = (string) $args;
+ }
+
+ /**
+ * Returns the string of arguments to pass to the php job
+ *
+ * @retrun string
+ */
+ public function getArgs()
+ {
+ return $this->args;
+ }
+
+ /**
+ * Sets the array of environment variables to start the child process with
+ *
+ * @param array $env
+ */
+ public function setEnv(array $env)
+ {
+ $this->env = $env;
+ }
+
+ /**
+ * Returns the array of environment variables to start the child process with
+ *
+ * @return array
+ */
+ public function getEnv()
+ {
+ return $this->env;
+ }
+
+ /**
+ * Sets the amount of seconds to wait before timing out
+ *
+ * @param int $timeout
+ */
+ public function setTimeout($timeout)
+ {
+ $this->timeout = (int) $timeout;
+ }
+
+ /**
+ * Returns the amount of seconds to wait before timing out
+ *
+ * @return int
+ */
+ public function getTimeout()
+ {
+ return $this->timeout;
+ }
+
+ /**
+ * @return PHPUnit_Util_PHP
+ */
+ public static function factory()
+ {
+ if (DIRECTORY_SEPARATOR == '\\') {
+ return new PHPUnit_Util_PHP_Windows;
+ }
+
+ return new PHPUnit_Util_PHP_Default;
+ }
+
+ /**
+ * Runs a single test in a separate PHP process.
+ *
+ * @param string $job
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_TestResult $result
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function runTestJob($job, PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result)
+ {
+ $result->startTest($test);
+
+ $_result = $this->runJob($job);
+
+ $this->processChildResult(
+ $test,
+ $result,
+ $_result['stdout'],
+ $_result['stderr']
+ );
+ }
+
+ /**
+ * Returns the command based into the configurations.
+ *
+ * @param array $settings
+ * @param string|null $file
+ *
+ * @return string
+ */
+ public function getCommand(array $settings, $file = null)
+ {
+ $command = $this->runtime->getBinary();
+ $command .= $this->settingsToParameters($settings);
+
+ if ('phpdbg' === PHP_SAPI) {
+ $command .= ' -qrr ';
+
+ if ($file) {
+ $command .= '-e ' . escapeshellarg($file);
+ } else {
+ $command .= escapeshellarg(__DIR__ . '/PHP/eval-stdin.php');
+ }
+ } elseif ($file) {
+ $command .= ' -f ' . escapeshellarg($file);
+ }
+
+ if ($this->args) {
+ $command .= ' -- ' . $this->args;
+ }
+
+ if (true === $this->stderrRedirection) {
+ $command .= ' 2>&1';
+ }
+
+ return $command;
+ }
+
+ /**
+ * Runs a single job (PHP code) using a separate PHP process.
+ *
+ * @param string $job
+ * @param array $settings
+ *
+ * @return array
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ abstract public function runJob($job, array $settings = []);
+
+ /**
+ * @param array $settings
+ *
+ * @return string
+ */
+ protected function settingsToParameters(array $settings)
+ {
+ $buffer = '';
+
+ foreach ($settings as $setting) {
+ $buffer .= ' -d ' . $setting;
+ }
+
+ return $buffer;
+ }
+
+ /**
+ * Processes the TestResult object from an isolated process.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_TestResult $result
+ * @param string $stdout
+ * @param string $stderr
+ */
+ private function processChildResult(PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result, $stdout, $stderr)
+ {
+ $time = 0;
+
+ if (!empty($stderr)) {
+ $result->addError(
+ $test,
+ new PHPUnit_Framework_Exception(trim($stderr)),
+ $time
+ );
+ } else {
+ set_error_handler(function ($errno, $errstr, $errfile, $errline) {
+ throw new ErrorException($errstr, $errno, $errno, $errfile, $errline);
+ });
+ try {
+ if (strpos($stdout, "#!/usr/bin/env php\n") === 0) {
+ $stdout = substr($stdout, 19);
+ }
+
+ $childResult = unserialize(str_replace("#!/usr/bin/env php\n", '', $stdout));
+ restore_error_handler();
+ } catch (ErrorException $e) {
+ restore_error_handler();
+ $childResult = false;
+
+ $result->addError(
+ $test,
+ new PHPUnit_Framework_Exception(trim($stdout), 0, $e),
+ $time
+ );
+ }
+
+ if ($childResult !== false) {
+ if (!empty($childResult['output'])) {
+ $output = $childResult['output'];
+ }
+
+ $test->setResult($childResult['testResult']);
+ $test->addToAssertionCount($childResult['numAssertions']);
+
+ $childResult = $childResult['result'];
+ /* @var $childResult PHPUnit_Framework_TestResult */
+
+ if ($result->getCollectCodeCoverageInformation()) {
+ $result->getCodeCoverage()->merge(
+ $childResult->getCodeCoverage()
+ );
+ }
+
+ $time = $childResult->time();
+ $notImplemented = $childResult->notImplemented();
+ $risky = $childResult->risky();
+ $skipped = $childResult->skipped();
+ $errors = $childResult->errors();
+ $warnings = $childResult->warnings();
+ $failures = $childResult->failures();
+
+ if (!empty($notImplemented)) {
+ $result->addError(
+ $test,
+ $this->getException($notImplemented[0]),
+ $time
+ );
+ } elseif (!empty($risky)) {
+ $result->addError(
+ $test,
+ $this->getException($risky[0]),
+ $time
+ );
+ } elseif (!empty($skipped)) {
+ $result->addError(
+ $test,
+ $this->getException($skipped[0]),
+ $time
+ );
+ } elseif (!empty($errors)) {
+ $result->addError(
+ $test,
+ $this->getException($errors[0]),
+ $time
+ );
+ } elseif (!empty($warnings)) {
+ $result->addWarning(
+ $test,
+ $this->getException($warnings[0]),
+ $time
+ );
+ } elseif (!empty($failures)) {
+ $result->addFailure(
+ $test,
+ $this->getException($failures[0]),
+ $time
+ );
+ }
+ }
+ }
+
+ $result->endTest($test, $time);
+
+ if (!empty($output)) {
+ print $output;
+ }
+ }
+
+ /**
+ * Gets the thrown exception from a PHPUnit_Framework_TestFailure.
+ *
+ * @param PHPUnit_Framework_TestFailure $error
+ *
+ * @return Exception
+ *
+ * @see https://github.com/sebastianbergmann/phpunit/issues/74
+ */
+ private function getException(PHPUnit_Framework_TestFailure $error)
+ {
+ $exception = $error->thrownException();
+
+ if ($exception instanceof __PHP_Incomplete_Class) {
+ $exceptionArray = [];
+ foreach ((array) $exception as $key => $value) {
+ $key = substr($key, strrpos($key, "\0") + 1);
+ $exceptionArray[$key] = $value;
+ }
+
+ $exception = new PHPUnit_Framework_SyntheticError(
+ sprintf(
+ '%s: %s',
+ $exceptionArray['_PHP_Incomplete_Class_Name'],
+ $exceptionArray['message']
+ ),
+ $exceptionArray['code'],
+ $exceptionArray['file'],
+ $exceptionArray['line'],
+ $exceptionArray['trace']
+ );
+ }
+
+ return $exception;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/PHP/Default.php b/vendor/phpunit/phpunit/src/Util/PHP/Default.php
new file mode 100644
index 0000000..152daf6
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/PHP/Default.php
@@ -0,0 +1,208 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Default utility for PHP sub-processes.
+ */
+class PHPUnit_Util_PHP_Default extends PHPUnit_Util_PHP
+{
+ /**
+ * @var string
+ */
+ protected $tempFile;
+
+ /**
+ * @var bool
+ */
+ protected $useTempFile = false;
+
+ /**
+ * Runs a single job (PHP code) using a separate PHP process.
+ *
+ * @param string $job
+ * @param array $settings
+ *
+ * @return array
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function runJob($job, array $settings = [])
+ {
+ if ($this->useTempFile || $this->stdin) {
+ if (!($this->tempFile = tempnam(sys_get_temp_dir(), 'PHPUnit')) ||
+ file_put_contents($this->tempFile, $job) === false) {
+ throw new PHPUnit_Framework_Exception(
+ 'Unable to write temporary file'
+ );
+ }
+
+ $job = $this->stdin;
+ }
+
+ return $this->runProcess($job, $settings);
+ }
+
+ /**
+ * Returns an array of file handles to be used in place of pipes
+ *
+ * @return array
+ */
+ protected function getHandles()
+ {
+ return [];
+ }
+
+ /**
+ * Handles creating the child process and returning the STDOUT and STDERR
+ *
+ * @param string $job
+ * @param array $settings
+ *
+ * @return array
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ protected function runProcess($job, $settings)
+ {
+ $handles = $this->getHandles();
+
+ $env = null;
+ if ($this->env) {
+ $env = isset($_SERVER) ? $_SERVER : [];
+ unset($env['argv'], $env['argc']);
+ $env = array_merge($env, $this->env);
+
+ foreach ($env as $envKey => $envVar) {
+ if (is_array($envVar)) {
+ unset($env[$envKey]);
+ }
+ }
+ }
+
+ $pipeSpec = [
+ 0 => isset($handles[0]) ? $handles[0] : ['pipe', 'r'],
+ 1 => isset($handles[1]) ? $handles[1] : ['pipe', 'w'],
+ 2 => isset($handles[2]) ? $handles[2] : ['pipe', 'w'],
+ ];
+ $process = proc_open(
+ $this->getCommand($settings, $this->tempFile),
+ $pipeSpec,
+ $pipes,
+ null,
+ $env
+ );
+
+ if (!is_resource($process)) {
+ throw new PHPUnit_Framework_Exception(
+ 'Unable to spawn worker process'
+ );
+ }
+
+ if ($job) {
+ $this->process($pipes[0], $job);
+ }
+ fclose($pipes[0]);
+
+ if ($this->timeout) {
+ $stderr = $stdout = '';
+ unset($pipes[0]);
+
+ while (true) {
+ $r = $pipes;
+ $w = null;
+ $e = null;
+
+ $n = @stream_select($r, $w, $e, $this->timeout);
+
+ if ($n === false) {
+ break;
+ } elseif ($n === 0) {
+ proc_terminate($process, 9);
+ throw new PHPUnit_Framework_Exception(sprintf('Job execution aborted after %d seconds', $this->timeout));
+ } elseif ($n > 0) {
+ foreach ($r as $pipe) {
+ $pipeOffset = 0;
+ foreach ($pipes as $i => $origPipe) {
+ if ($pipe == $origPipe) {
+ $pipeOffset = $i;
+ break;
+ }
+ }
+
+ if (!$pipeOffset) {
+ break;
+ }
+
+ $line = fread($pipe, 8192);
+ if (strlen($line) == 0) {
+ fclose($pipes[$pipeOffset]);
+ unset($pipes[$pipeOffset]);
+ } else {
+ if ($pipeOffset == 1) {
+ $stdout .= $line;
+ } else {
+ $stderr .= $line;
+ }
+ }
+ }
+
+ if (empty($pipes)) {
+ break;
+ }
+ }
+ }
+ } else {
+ if (isset($pipes[1])) {
+ $stdout = stream_get_contents($pipes[1]);
+ fclose($pipes[1]);
+ }
+
+ if (isset($pipes[2])) {
+ $stderr = stream_get_contents($pipes[2]);
+ fclose($pipes[2]);
+ }
+ }
+
+ if (isset($handles[1])) {
+ rewind($handles[1]);
+ $stdout = stream_get_contents($handles[1]);
+ fclose($handles[1]);
+ }
+
+ if (isset($handles[2])) {
+ rewind($handles[2]);
+ $stderr = stream_get_contents($handles[2]);
+ fclose($handles[2]);
+ }
+
+ proc_close($process);
+ $this->cleanup();
+
+ return ['stdout' => $stdout, 'stderr' => $stderr];
+ }
+
+ /**
+ * @param resource $pipe
+ * @param string $job
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ protected function process($pipe, $job)
+ {
+ fwrite($pipe, $job);
+ }
+
+ protected function cleanup()
+ {
+ if ($this->tempFile) {
+ unlink($this->tempFile);
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/PHP/Template/TestCaseMethod.tpl.dist b/vendor/phpunit/phpunit/src/Util/PHP/Template/TestCaseMethod.tpl.dist
new file mode 100644
index 0000000..c7172b9
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/PHP/Template/TestCaseMethod.tpl.dist
@@ -0,0 +1,102 @@
+<?php
+use SebastianBergmann\CodeCoverage\CodeCoverage;
+
+if (!defined('STDOUT')) {
+ // php://stdout does not obey output buffering. Any output would break
+ // unserialization of child process results in the parent process.
+ define('STDOUT', fopen('php://temp', 'w+b'));
+ define('STDERR', fopen('php://stderr', 'wb'));
+}
+
+{iniSettings}
+ini_set('display_errors', 'stderr');
+set_include_path('{include_path}');
+
+$composerAutoload = {composerAutoload};
+$phar = {phar};
+
+ob_start();
+
+if ($composerAutoload) {
+ require_once $composerAutoload;
+ define('PHPUNIT_COMPOSER_INSTALL', $composerAutoload);
+} else if ($phar) {
+ require $phar;
+}
+
+function __phpunit_run_isolated_test()
+{
+ if (!class_exists('{className}')) {
+ require_once '{filename}';
+ }
+
+ $result = new PHPUnit_Framework_TestResult;
+
+ if ({collectCodeCoverageInformation}) {
+ $result->setCodeCoverage(
+ new CodeCoverage(
+ null,
+ unserialize('{codeCoverageFilter}')
+ )
+ );
+ }
+
+ $result->beStrictAboutTestsThatDoNotTestAnything({isStrictAboutTestsThatDoNotTestAnything});
+ $result->beStrictAboutOutputDuringTests({isStrictAboutOutputDuringTests});
+ $result->enforceTimeLimit({enforcesTimeLimit});
+ $result->beStrictAboutTodoAnnotatedTests({isStrictAboutTodoAnnotatedTests});
+ $result->beStrictAboutResourceUsageDuringSmallTests({isStrictAboutResourceUsageDuringSmallTests});
+
+ $test = new {className}('{methodName}', unserialize('{data}'), '{dataName}');
+ $test->setDependencyInput(unserialize('{dependencyInput}'));
+ $test->setInIsolation(TRUE);
+
+ ob_end_clean();
+ $test->run($result);
+ $output = '';
+ if (!$test->hasExpectationOnOutput()) {
+ $output = $test->getActualOutput();
+ }
+
+ @rewind(STDOUT); /* @ as not every STDOUT target stream is rewindable */
+ if ($stdout = stream_get_contents(STDOUT)) {
+ $output = $stdout . $output;
+ }
+
+ print serialize(
+ array(
+ 'testResult' => $test->getResult(),
+ 'numAssertions' => $test->getNumAssertions(),
+ 'result' => $result,
+ 'output' => $output
+ )
+ );
+}
+
+$configurationFilePath = '{configurationFilePath}';
+
+if ('' !== $configurationFilePath) {
+ $configuration = PHPUnit_Util_Configuration::getInstance($configurationFilePath);
+ $configuration->handlePHPConfiguration();
+ unset($configuration);
+}
+
+function __phpunit_error_handler($errno, $errstr, $errfile, $errline, $errcontext)
+{
+ return true;
+}
+
+set_error_handler("__phpunit_error_handler");
+
+{constants}
+{included_files}
+{globals}
+
+restore_error_handler();
+
+if (isset($GLOBALS['__PHPUNIT_BOOTSTRAP'])) {
+ require_once $GLOBALS['__PHPUNIT_BOOTSTRAP'];
+ unset($GLOBALS['__PHPUNIT_BOOTSTRAP']);
+}
+
+__phpunit_run_isolated_test();
diff --git a/vendor/phpunit/phpunit/src/Util/PHP/Windows.php b/vendor/phpunit/phpunit/src/Util/PHP/Windows.php
new file mode 100644
index 0000000..cc25e45
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/PHP/Windows.php
@@ -0,0 +1,40 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Windows utility for PHP sub-processes.
+ *
+ * Reading from STDOUT or STDERR hangs forever on Windows if the output is
+ * too large.
+ *
+ * @see https://bugs.php.net/bug.php?id=51800
+ */
+class PHPUnit_Util_PHP_Windows extends PHPUnit_Util_PHP_Default
+{
+ protected $useTempFile = true;
+
+ protected function getHandles()
+ {
+ if (false === $stdout_handle = tmpfile()) {
+ throw new PHPUnit_Framework_Exception(
+ 'A temporary file could not be created; verify that your TEMP environment variable is writable'
+ );
+ }
+
+ return [
+ 1 => $stdout_handle
+ ];
+ }
+
+ public function getCommand(array $settings, $file = null)
+ {
+ return '"' . parent::getCommand($settings, $file) . '"';
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php b/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
new file mode 100644
index 0000000..ccf8271
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
@@ -0,0 +1,10 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+eval('?>' . file_get_contents('php://stdin'));
diff --git a/vendor/phpunit/phpunit/src/Util/Printer.php b/vendor/phpunit/phpunit/src/Util/Printer.php
new file mode 100644
index 0000000..e40f34c
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/Printer.php
@@ -0,0 +1,144 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Utility class that can print to STDOUT or write to a file.
+ */
+class PHPUnit_Util_Printer
+{
+ /**
+ * If true, flush output after every write.
+ *
+ * @var bool
+ */
+ protected $autoFlush = false;
+
+ /**
+ * @var resource
+ */
+ protected $out;
+
+ /**
+ * @var string
+ */
+ protected $outTarget;
+
+ /**
+ * Constructor.
+ *
+ * @param mixed $out
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public function __construct($out = null)
+ {
+ if ($out !== null) {
+ if (is_string($out)) {
+ if (strpos($out, 'socket://') === 0) {
+ $out = explode(':', str_replace('socket://', '', $out));
+
+ if (count($out) != 2) {
+ throw new PHPUnit_Framework_Exception;
+ }
+
+ $this->out = fsockopen($out[0], $out[1]);
+ } else {
+ if (strpos($out, 'php://') === false &&
+ !is_dir(dirname($out))) {
+ mkdir(dirname($out), 0777, true);
+ }
+
+ $this->out = fopen($out, 'wt');
+ }
+
+ $this->outTarget = $out;
+ } else {
+ $this->out = $out;
+ }
+ }
+ }
+
+ /**
+ * Flush buffer and close output if it's not to a PHP stream
+ */
+ public function flush()
+ {
+ if ($this->out && strncmp($this->outTarget, 'php://', 6) !== 0) {
+ fclose($this->out);
+ }
+ }
+
+ /**
+ * Performs a safe, incremental flush.
+ *
+ * Do not confuse this function with the flush() function of this class,
+ * since the flush() function may close the file being written to, rendering
+ * the current object no longer usable.
+ */
+ public function incrementalFlush()
+ {
+ if ($this->out) {
+ fflush($this->out);
+ } else {
+ flush();
+ }
+ }
+
+ /**
+ * @param string $buffer
+ */
+ public function write($buffer)
+ {
+ if ($this->out) {
+ fwrite($this->out, $buffer);
+
+ if ($this->autoFlush) {
+ $this->incrementalFlush();
+ }
+ } else {
+ if (PHP_SAPI != 'cli' && PHP_SAPI != 'phpdbg') {
+ $buffer = htmlspecialchars($buffer, ENT_SUBSTITUTE);
+ }
+
+ print $buffer;
+
+ if ($this->autoFlush) {
+ $this->incrementalFlush();
+ }
+ }
+ }
+
+ /**
+ * Check auto-flush mode.
+ *
+ * @return bool
+ */
+ public function getAutoFlush()
+ {
+ return $this->autoFlush;
+ }
+
+ /**
+ * Set auto-flushing mode.
+ *
+ * If set, *incremental* flushes will be done after each write. This should
+ * not be confused with the different effects of this class' flush() method.
+ *
+ * @param bool $autoFlush
+ */
+ public function setAutoFlush($autoFlush)
+ {
+ if (is_bool($autoFlush)) {
+ $this->autoFlush = $autoFlush;
+ } else {
+ throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
+ }
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/Regex.php b/vendor/phpunit/phpunit/src/Util/Regex.php
new file mode 100644
index 0000000..c154901
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/Regex.php
@@ -0,0 +1,33 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Error handler that converts PHP errors and warnings to exceptions.
+ */
+class PHPUnit_Util_Regex
+{
+ /**
+ * @param string $pattern
+ * @param string $subject
+ * @param null $matches
+ * @param int $flags
+ * @param int $offset
+ *
+ * @return int
+ */
+ public static function pregMatchSafe($pattern, $subject, $matches = null, $flags = 0, $offset = 0)
+ {
+ $handler_terminator = PHPUnit_Util_ErrorHandler::handleErrorOnce(E_WARNING);
+ $match = preg_match($pattern, $subject, $matches, $flags, $offset);
+ $handler_terminator(); // cleaning
+
+ return $match;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/String.php b/vendor/phpunit/phpunit/src/Util/String.php
new file mode 100644
index 0000000..16621b8
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/String.php
@@ -0,0 +1,61 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * String helpers.
+ */
+class PHPUnit_Util_String
+{
+ /**
+ * Converts a string to UTF-8 encoding.
+ *
+ * @param string $string
+ *
+ * @return string
+ */
+ public static function convertToUtf8($string)
+ {
+ return mb_convert_encoding($string, 'UTF-8');
+ }
+
+ /**
+ * Checks a string for UTF-8 encoding.
+ *
+ * @param string $string
+ *
+ * @return bool
+ */
+ protected static function isUtf8($string)
+ {
+ $length = strlen($string);
+
+ for ($i = 0; $i < $length; $i++) {
+ if (ord($string[$i]) < 0x80) {
+ $n = 0;
+ } elseif ((ord($string[$i]) & 0xE0) == 0xC0) {
+ $n = 1;
+ } elseif ((ord($string[$i]) & 0xF0) == 0xE0) {
+ $n = 2;
+ } elseif ((ord($string[$i]) & 0xF0) == 0xF0) {
+ $n = 3;
+ } else {
+ return false;
+ }
+
+ for ($j = 0; $j < $n; $j++) {
+ if ((++$i == $length) || ((ord($string[$i]) & 0xC0) != 0x80)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/Test.php b/vendor/phpunit/phpunit/src/Util/Test.php
new file mode 100644
index 0000000..6bf1786
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/Test.php
@@ -0,0 +1,1099 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Test helpers.
+ */
+class PHPUnit_Util_Test
+{
+ const REGEX_DATA_PROVIDER = '/@dataProvider\s+([a-zA-Z0-9._:-\\\\x7f-\xff]+)/';
+ const REGEX_TEST_WITH = '/@testWith\s+/';
+ const REGEX_EXPECTED_EXCEPTION = '(@expectedException\s+([:.\w\\\\x7f-\xff]+)(?:[\t ]+(\S*))?(?:[\t ]+(\S*))?\s*$)m';
+ const REGEX_REQUIRES_VERSION = '/@requires\s+(?P<name>PHP(?:Unit)?)\s+(?P<operator>[<>=!]{0,2})\s*(?P<version>[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m';
+ const REGEX_REQUIRES_OS = '/@requires\s+OS\s+(?P<value>.+?)[ \t]*\r?$/m';
+ const REGEX_REQUIRES = '/@requires\s+(?P<name>function|extension)\s+(?P<value>([^ ]+?))\s*(?P<operator>[<>=!]{0,2})\s*(?P<version>[\d\.-]+[\d\.]?)?[ \t]*\r?$/m';
+
+ const UNKNOWN = -1;
+ const SMALL = 0;
+ const MEDIUM = 1;
+ const LARGE = 2;
+
+ private static $annotationCache = [];
+
+ private static $hookMethods = [];
+
+ /**
+ * @param PHPUnit_Framework_Test $test
+ * @param bool $asString
+ *
+ * @return mixed
+ */
+ public static function describe(PHPUnit_Framework_Test $test, $asString = true)
+ {
+ if ($asString) {
+ if ($test instanceof PHPUnit_Framework_SelfDescribing) {
+ return $test->toString();
+ } else {
+ return get_class($test);
+ }
+ } else {
+ if ($test instanceof PHPUnit_Framework_TestCase) {
+ return [
+ get_class($test), $test->getName()
+ ];
+ } elseif ($test instanceof PHPUnit_Framework_SelfDescribing) {
+ return ['', $test->toString()];
+ } else {
+ return ['', get_class($test)];
+ }
+ }
+ }
+
+ /**
+ * @param string $className
+ * @param string $methodName
+ *
+ * @return array|bool
+ *
+ * @throws PHPUnit_Framework_CodeCoverageException
+ */
+ public static function getLinesToBeCovered($className, $methodName)
+ {
+ $annotations = self::parseTestMethodAnnotations(
+ $className,
+ $methodName
+ );
+
+ if (isset($annotations['class']['coversNothing']) || isset($annotations['method']['coversNothing'])) {
+ return false;
+ }
+
+ return self::getLinesToBeCoveredOrUsed($className, $methodName, 'covers');
+ }
+
+ /**
+ * Returns lines of code specified with the @uses annotation.
+ *
+ * @param string $className
+ * @param string $methodName
+ *
+ * @return array
+ */
+ public static function getLinesToBeUsed($className, $methodName)
+ {
+ return self::getLinesToBeCoveredOrUsed($className, $methodName, 'uses');
+ }
+
+ /**
+ * @param string $className
+ * @param string $methodName
+ * @param string $mode
+ *
+ * @return array
+ *
+ * @throws PHPUnit_Framework_CodeCoverageException
+ */
+ private static function getLinesToBeCoveredOrUsed($className, $methodName, $mode)
+ {
+ $annotations = self::parseTestMethodAnnotations(
+ $className,
+ $methodName
+ );
+
+ $classShortcut = null;
+
+ if (!empty($annotations['class'][$mode . 'DefaultClass'])) {
+ if (count($annotations['class'][$mode . 'DefaultClass']) > 1) {
+ throw new PHPUnit_Framework_CodeCoverageException(
+ sprintf(
+ 'More than one @%sClass annotation in class or interface "%s".',
+ $mode,
+ $className
+ )
+ );
+ }
+
+ $classShortcut = $annotations['class'][$mode . 'DefaultClass'][0];
+ }
+
+ $list = [];
+
+ if (isset($annotations['class'][$mode])) {
+ $list = $annotations['class'][$mode];
+ }
+
+ if (isset($annotations['method'][$mode])) {
+ $list = array_merge($list, $annotations['method'][$mode]);
+ }
+
+ $codeList = [];
+
+ foreach (array_unique($list) as $element) {
+ if ($classShortcut && strncmp($element, '::', 2) === 0) {
+ $element = $classShortcut . $element;
+ }
+
+ $element = preg_replace('/[\s()]+$/', '', $element);
+ $element = explode(' ', $element);
+ $element = $element[0];
+
+ $codeList = array_merge(
+ $codeList,
+ self::resolveElementToReflectionObjects($element)
+ );
+ }
+
+ return self::resolveReflectionObjectsToLines($codeList);
+ }
+
+ /**
+ * Returns the requirements for a test.
+ *
+ * @param string $className
+ * @param string $methodName
+ *
+ * @return array
+ */
+ public static function getRequirements($className, $methodName)
+ {
+ $reflector = new ReflectionClass($className);
+ $docComment = $reflector->getDocComment();
+ $reflector = new ReflectionMethod($className, $methodName);
+ $docComment .= "\n" . $reflector->getDocComment();
+ $requires = [];
+
+ if ($count = preg_match_all(self::REGEX_REQUIRES_OS, $docComment, $matches)) {
+ $requires['OS'] = sprintf(
+ '/%s/i',
+ addcslashes($matches['value'][$count - 1], '/')
+ );
+ }
+ if ($count = preg_match_all(self::REGEX_REQUIRES_VERSION, $docComment, $matches)) {
+ for ($i = 0; $i < $count; $i++) {
+ $requires[$matches['name'][$i]] = [
+ 'version' => $matches['version'][$i],
+ 'operator' => $matches['operator'][$i]
+ ];
+ }
+ }
+
+ // https://bugs.php.net/bug.php?id=63055
+ $matches = [];
+
+ if ($count = preg_match_all(self::REGEX_REQUIRES, $docComment, $matches)) {
+ for ($i = 0; $i < $count; $i++) {
+ $name = $matches['name'][$i] . 's';
+ if (!isset($requires[$name])) {
+ $requires[$name] = [];
+ }
+ $requires[$name][] = $matches['value'][$i];
+ if (empty($matches['version'][$i]) || $name != 'extensions') {
+ continue;
+ }
+ $requires['extension_versions'][$matches['value'][$i]] = [
+ 'version' => $matches['version'][$i],
+ 'operator' => $matches['operator'][$i]
+ ];
+ }
+ }
+
+ return $requires;
+ }
+
+ /**
+ * Returns the missing requirements for a test.
+ *
+ * @param string $className
+ * @param string $methodName
+ *
+ * @return array
+ */
+ public static function getMissingRequirements($className, $methodName)
+ {
+ $required = static::getRequirements($className, $methodName);
+ $missing = [];
+
+ $operator = empty($required['PHP']['operator']) ? '>=' : $required['PHP']['operator'];
+ if (!empty($required['PHP']) && !version_compare(PHP_VERSION, $required['PHP']['version'], $operator)) {
+ $missing[] = sprintf('PHP %s %s is required.', $operator, $required['PHP']['version']);
+ }
+
+ if (!empty($required['PHPUnit'])) {
+ $phpunitVersion = PHPUnit_Runner_Version::id();
+
+ $operator = empty($required['PHPUnit']['operator']) ? '>=' : $required['PHPUnit']['operator'];
+ if (!version_compare($phpunitVersion, $required['PHPUnit']['version'], $operator)) {
+ $missing[] = sprintf('PHPUnit %s %s is required.', $operator, $required['PHPUnit']['version']);
+ }
+ }
+
+ if (!empty($required['OS']) && !preg_match($required['OS'], PHP_OS)) {
+ $missing[] = sprintf('Operating system matching %s is required.', $required['OS']);
+ }
+
+ if (!empty($required['functions'])) {
+ foreach ($required['functions'] as $function) {
+ $pieces = explode('::', $function);
+ if (2 === count($pieces) && method_exists($pieces[0], $pieces[1])) {
+ continue;
+ }
+ if (function_exists($function)) {
+ continue;
+ }
+ $missing[] = sprintf('Function %s is required.', $function);
+ }
+ }
+
+ if (!empty($required['extensions'])) {
+ foreach ($required['extensions'] as $extension) {
+ if (isset($required['extension_versions'][$extension])) {
+ continue;
+ }
+ if (!extension_loaded($extension)) {
+ $missing[] = sprintf('Extension %s is required.', $extension);
+ }
+ }
+ }
+
+ if (!empty($required['extension_versions'])) {
+ foreach ($required['extension_versions'] as $extension => $required) {
+ $actualVersion = phpversion($extension);
+
+ $operator = empty($required['operator']) ? '>=' : $required['operator'];
+ if (false === $actualVersion || !version_compare($actualVersion, $required['version'], $operator)) {
+ $missing[] = sprintf('Extension %s %s %s is required.', $extension, $operator, $required['version']);
+ }
+ }
+ }
+
+ return $missing;
+ }
+
+ /**
+ * Returns the expected exception for a test.
+ *
+ * @param string $className
+ * @param string $methodName
+ *
+ * @return array
+ */
+ public static function getExpectedException($className, $methodName)
+ {
+ $reflector = new ReflectionMethod($className, $methodName);
+ $docComment = $reflector->getDocComment();
+ $docComment = substr($docComment, 3, -2);
+
+ if (preg_match(self::REGEX_EXPECTED_EXCEPTION, $docComment, $matches)) {
+ $annotations = self::parseTestMethodAnnotations(
+ $className,
+ $methodName
+ );
+
+ $class = $matches[1];
+ $code = null;
+ $message = '';
+ $messageRegExp = '';
+
+ if (isset($matches[2])) {
+ $message = trim($matches[2]);
+ } elseif (isset($annotations['method']['expectedExceptionMessage'])) {
+ $message = self::parseAnnotationContent(
+ $annotations['method']['expectedExceptionMessage'][0]
+ );
+ }
+
+ if (isset($annotations['method']['expectedExceptionMessageRegExp'])) {
+ $messageRegExp = self::parseAnnotationContent(
+ $annotations['method']['expectedExceptionMessageRegExp'][0]
+ );
+ }
+
+ if (isset($matches[3])) {
+ $code = $matches[3];
+ } elseif (isset($annotations['method']['expectedExceptionCode'])) {
+ $code = self::parseAnnotationContent(
+ $annotations['method']['expectedExceptionCode'][0]
+ );
+ }
+
+ if (is_numeric($code)) {
+ $code = (int) $code;
+ } elseif (is_string($code) && defined($code)) {
+ $code = (int) constant($code);
+ }
+
+ return [
+ 'class' => $class, 'code' => $code, 'message' => $message, 'message_regex' => $messageRegExp
+ ];
+ }
+
+ return false;
+ }
+
+ /**
+ * Parse annotation content to use constant/class constant values
+ *
+ * Constants are specified using a starting '@'. For example: @ClassName::CONST_NAME
+ *
+ * If the constant is not found the string is used as is to ensure maximum BC.
+ *
+ * @param string $message
+ *
+ * @return string
+ */
+ private static function parseAnnotationContent($message)
+ {
+ if (strpos($message, '::') !== false && count(explode('::', $message)) == 2) {
+ if (defined($message)) {
+ $message = constant($message);
+ }
+ }
+
+ return $message;
+ }
+
+ /**
+ * Returns the provided data for a method.
+ *
+ * @param string $className
+ * @param string $methodName
+ *
+ * @return array When a data provider is specified and exists
+ * null When no data provider is specified
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ public static function getProvidedData($className, $methodName)
+ {
+ $reflector = new ReflectionMethod($className, $methodName);
+ $docComment = $reflector->getDocComment();
+
+ $data = self::getDataFromDataProviderAnnotation($docComment, $className, $methodName);
+
+ if ($data === null) {
+ $data = self::getDataFromTestWithAnnotation($docComment);
+ }
+
+ if (is_array($data) && empty($data)) {
+ throw new PHPUnit_Framework_SkippedTestError;
+ }
+
+ if ($data !== null) {
+ foreach ($data as $key => $value) {
+ if (!is_array($value)) {
+ throw new PHPUnit_Framework_Exception(
+ sprintf(
+ 'Data set %s is invalid.',
+ is_int($key) ? '#' . $key : '"' . $key . '"'
+ )
+ );
+ }
+ }
+ }
+
+ return $data;
+ }
+
+ /**
+ * Returns the provided data for a method.
+ *
+ * @param string $docComment
+ * @param string $className
+ * @param string $methodName
+ *
+ * @return array|Iterator when a data provider is specified and exists
+ * null when no data provider is specified
+ *
+ * @throws PHPUnit_Framework_Exception
+ */
+ private static function getDataFromDataProviderAnnotation($docComment, $className, $methodName)
+ {
+ if (preg_match_all(self::REGEX_DATA_PROVIDER, $docComment, $matches)) {
+ $result = [];
+
+ foreach ($matches[1] as $match) {
+ $dataProviderMethodNameNamespace = explode('\\', $match);
+ $leaf = explode('::', array_pop($dataProviderMethodNameNamespace));
+ $dataProviderMethodName = array_pop($leaf);
+
+ if (!empty($dataProviderMethodNameNamespace)) {
+ $dataProviderMethodNameNamespace = implode('\\', $dataProviderMethodNameNamespace) . '\\';
+ } else {
+ $dataProviderMethodNameNamespace = '';
+ }
+
+ if (!empty($leaf)) {
+ $dataProviderClassName = $dataProviderMethodNameNamespace . array_pop($leaf);
+ } else {
+ $dataProviderClassName = $className;
+ }
+
+ $dataProviderClass = new ReflectionClass($dataProviderClassName);
+ $dataProviderMethod = $dataProviderClass->getMethod(
+ $dataProviderMethodName
+ );
+
+ if ($dataProviderMethod->isStatic()) {
+ $object = null;
+ } else {
+ $object = $dataProviderClass->newInstance();
+ }
+
+ if ($dataProviderMethod->getNumberOfParameters() == 0) {
+ $data = $dataProviderMethod->invoke($object);
+ } else {
+ $data = $dataProviderMethod->invoke($object, $methodName);
+ }
+
+ if ($data instanceof Iterator) {
+ $data = iterator_to_array($data);
+ }
+
+ if (is_array($data)) {
+ $result = array_merge($result, $data);
+ }
+ }
+
+ return $result;
+ }
+ }
+
+ /**
+ * @param string $docComment full docComment string
+ *
+ * @return array when @testWith annotation is defined
+ * null when @testWith annotation is omitted
+ *
+ * @throws PHPUnit_Framework_Exception when @testWith annotation is defined but cannot be parsed
+ */
+ public static function getDataFromTestWithAnnotation($docComment)
+ {
+ $docComment = self::cleanUpMultiLineAnnotation($docComment);
+
+ if (preg_match(self::REGEX_TEST_WITH, $docComment, $matches, PREG_OFFSET_CAPTURE)) {
+ $offset = strlen($matches[0][0]) + $matches[0][1];
+ $annotationContent = substr($docComment, $offset);
+ $data = [];
+
+ foreach (explode("\n", $annotationContent) as $candidateRow) {
+ $candidateRow = trim($candidateRow);
+
+ if ($candidateRow[0] !== '[') {
+ break;
+ }
+
+ $dataSet = json_decode($candidateRow, true);
+
+ if (json_last_error() != JSON_ERROR_NONE) {
+ throw new PHPUnit_Framework_Exception(
+ 'The dataset for the @testWith annotation cannot be parsed: ' . json_last_error_msg()
+ );
+ }
+
+ $data[] = $dataSet;
+ }
+
+ if (!$data) {
+ throw new PHPUnit_Framework_Exception('The dataset for the @testWith annotation cannot be parsed.');
+ }
+
+ return $data;
+ }
+ }
+
+ private static function cleanUpMultiLineAnnotation($docComment)
+ {
+ //removing initial ' * ' for docComment
+ $docComment = str_replace("\r\n", "\n", $docComment);
+ $docComment = preg_replace('/' . '\n' . '\s*' . '\*' . '\s?' . '/', "\n", $docComment);
+ $docComment = substr($docComment, 0, -1);
+ $docComment = rtrim($docComment, "\n");
+
+ return $docComment;
+ }
+
+ /**
+ * @param string $className
+ * @param string $methodName
+ *
+ * @return array
+ *
+ * @throws ReflectionException
+ */
+ public static function parseTestMethodAnnotations($className, $methodName = '')
+ {
+ if (!isset(self::$annotationCache[$className])) {
+ $class = new ReflectionClass($className);
+ self::$annotationCache[$className] = self::parseAnnotations($class->getDocComment());
+ }
+
+ if (!empty($methodName) && !isset(self::$annotationCache[$className . '::' . $methodName])) {
+ try {
+ $method = new ReflectionMethod($className, $methodName);
+ $annotations = self::parseAnnotations($method->getDocComment());
+ } catch (ReflectionException $e) {
+ $annotations = [];
+ }
+ self::$annotationCache[$className . '::' . $methodName] = $annotations;
+ }
+
+ return [
+ 'class' => self::$annotationCache[$className],
+ 'method' => !empty($methodName) ? self::$annotationCache[$className . '::' . $methodName] : []
+ ];
+ }
+
+ /**
+ * @param string $className
+ * @param string $methodName
+ *
+ * @return array
+ */
+ public static function getInlineAnnotations($className, $methodName)
+ {
+ $method = new ReflectionMethod($className, $methodName);
+ $code = file($method->getFileName());
+ $lineNumber = $method->getStartLine();
+ $startLine = $method->getStartLine() - 1;
+ $endLine = $method->getEndLine() - 1;
+ $methodLines = array_slice($code, $startLine, $endLine - $startLine + 1);
+ $annotations = [];
+
+ foreach ($methodLines as $line) {
+ if (preg_match('#/\*\*?\s*@(?P<name>[A-Za-z_-]+)(?:[ \t]+(?P<value>.*?))?[ \t]*\r?\*/$#m', $line, $matches)) {
+ $annotations[strtolower($matches['name'])] = [
+ 'line' => $lineNumber,
+ 'value' => $matches['value']
+ ];
+ }
+
+ $lineNumber++;
+ }
+
+ return $annotations;
+ }
+
+ /**
+ * @param string $docblock
+ *
+ * @return array
+ */
+ private static function parseAnnotations($docblock)
+ {
+ $annotations = [];
+ // Strip away the docblock header and footer to ease parsing of one line annotations
+ $docblock = substr($docblock, 3, -2);
+
+ if (preg_match_all('/@(?P<name>[A-Za-z_-]+)(?:[ \t]+(?P<value>.*?))?[ \t]*\r?$/m', $docblock, $matches)) {
+ $numMatches = count($matches[0]);
+
+ for ($i = 0; $i < $numMatches; ++$i) {
+ $annotations[$matches['name'][$i]][] = (string) $matches['value'][$i];
+ }
+ }
+
+ return $annotations;
+ }
+
+ /**
+ * Returns the backup settings for a test.
+ *
+ * @param string $className
+ * @param string $methodName
+ *
+ * @return array
+ */
+ public static function getBackupSettings($className, $methodName)
+ {
+ return [
+ 'backupGlobals' => self::getBooleanAnnotationSetting(
+ $className,
+ $methodName,
+ 'backupGlobals'
+ ),
+ 'backupStaticAttributes' => self::getBooleanAnnotationSetting(
+ $className,
+ $methodName,
+ 'backupStaticAttributes'
+ )
+ ];
+ }
+
+ /**
+ * Returns the dependencies for a test class or method.
+ *
+ * @param string $className
+ * @param string $methodName
+ *
+ * @return array
+ */
+ public static function getDependencies($className, $methodName)
+ {
+ $annotations = self::parseTestMethodAnnotations(
+ $className,
+ $methodName
+ );
+
+ $dependencies = [];
+
+ if (isset($annotations['class']['depends'])) {
+ $dependencies = $annotations['class']['depends'];
+ }
+
+ if (isset($annotations['method']['depends'])) {
+ $dependencies = array_merge(
+ $dependencies,
+ $annotations['method']['depends']
+ );
+ }
+
+ return array_unique($dependencies);
+ }
+
+ /**
+ * Returns the error handler settings for a test.
+ *
+ * @param string $className
+ * @param string $methodName
+ *
+ * @return bool
+ */
+ public static function getErrorHandlerSettings($className, $methodName)
+ {
+ return self::getBooleanAnnotationSetting(
+ $className,
+ $methodName,
+ 'errorHandler'
+ );
+ }
+
+ /**
+ * Returns the groups for a test class or method.
+ *
+ * @param string $className
+ * @param string $methodName
+ *
+ * @return array
+ */
+ public static function getGroups($className, $methodName = '')
+ {
+ $annotations = self::parseTestMethodAnnotations(
+ $className,
+ $methodName
+ );
+
+ $groups = [];
+
+ if (isset($annotations['method']['author'])) {
+ $groups = $annotations['method']['author'];
+ } elseif (isset($annotations['class']['author'])) {
+ $groups = $annotations['class']['author'];
+ }
+
+ if (isset($annotations['class']['group'])) {
+ $groups = array_merge($groups, $annotations['class']['group']);
+ }
+
+ if (isset($annotations['method']['group'])) {
+ $groups = array_merge($groups, $annotations['method']['group']);
+ }
+
+ if (isset($annotations['class']['ticket'])) {
+ $groups = array_merge($groups, $annotations['class']['ticket']);
+ }
+
+ if (isset($annotations['method']['ticket'])) {
+ $groups = array_merge($groups, $annotations['method']['ticket']);
+ }
+
+ foreach (['method', 'class'] as $element) {
+ foreach (['small', 'medium', 'large'] as $size) {
+ if (isset($annotations[$element][$size])) {
+ $groups[] = $size;
+ break 2;
+ }
+ }
+ }
+
+ return array_unique($groups);
+ }
+
+ /**
+ * Returns the size of the test.
+ *
+ * @param string $className
+ * @param string $methodName
+ *
+ * @return int
+ */
+ public static function getSize($className, $methodName)
+ {
+ $groups = array_flip(self::getGroups($className, $methodName));
+ $size = self::UNKNOWN;
+ $class = new ReflectionClass($className);
+
+ if (isset($groups['large']) ||
+ (class_exists('PHPUnit_Extensions_Database_TestCase', false) &&
+ $class->isSubclassOf('PHPUnit_Extensions_Database_TestCase'))) {
+ $size = self::LARGE;
+ } elseif (isset($groups['medium'])) {
+ $size = self::MEDIUM;
+ } elseif (isset($groups['small'])) {
+ $size = self::SMALL;
+ }
+
+ return $size;
+ }
+
+ /**
+ * Returns the tickets for a test class or method.
+ *
+ * @param string $className
+ * @param string $methodName
+ *
+ * @return array
+ */
+ public static function getTickets($className, $methodName)
+ {
+ $annotations = self::parseTestMethodAnnotations(
+ $className,
+ $methodName
+ );
+
+ $tickets = [];
+
+ if (isset($annotations['class']['ticket'])) {
+ $tickets = $annotations['class']['ticket'];
+ }
+
+ if (isset($annotations['method']['ticket'])) {
+ $tickets = array_merge($tickets, $annotations['method']['ticket']);
+ }
+
+ return array_unique($tickets);
+ }
+
+ /**
+ * Returns the process isolation settings for a test.
+ *
+ * @param string $className
+ * @param string $methodName
+ *
+ * @return bool
+ */
+ public static function getProcessIsolationSettings($className, $methodName)
+ {
+ $annotations = self::parseTestMethodAnnotations(
+ $className,
+ $methodName
+ );
+
+ if (isset($annotations['class']['runTestsInSeparateProcesses']) ||
+ isset($annotations['method']['runInSeparateProcess'])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the preserve global state settings for a test.
+ *
+ * @param string $className
+ * @param string $methodName
+ *
+ * @return bool
+ */
+ public static function getPreserveGlobalStateSettings($className, $methodName)
+ {
+ return self::getBooleanAnnotationSetting(
+ $className,
+ $methodName,
+ 'preserveGlobalState'
+ );
+ }
+
+ /**
+ * @param string $className
+ *
+ * @return array
+ */
+ public static function getHookMethods($className)
+ {
+ if (!class_exists($className, false)) {
+ return self::emptyHookMethodsArray();
+ }
+
+ if (!isset(self::$hookMethods[$className])) {
+ self::$hookMethods[$className] = self::emptyHookMethodsArray();
+
+ try {
+ $class = new ReflectionClass($className);
+
+ foreach ($class->getMethods() as $method) {
+ if (self::isBeforeClassMethod($method)) {
+ self::$hookMethods[$className]['beforeClass'][] = $method->getName();
+ }
+
+ if (self::isBeforeMethod($method)) {
+ self::$hookMethods[$className]['before'][] = $method->getName();
+ }
+
+ if (self::isAfterMethod($method)) {
+ self::$hookMethods[$className]['after'][] = $method->getName();
+ }
+
+ if (self::isAfterClassMethod($method)) {
+ self::$hookMethods[$className]['afterClass'][] = $method->getName();
+ }
+ }
+ } catch (ReflectionException $e) {
+ }
+ }
+
+ return self::$hookMethods[$className];
+ }
+
+ /**
+ * @return array
+ */
+ private static function emptyHookMethodsArray()
+ {
+ return [
+ 'beforeClass' => ['setUpBeforeClass'],
+ 'before' => ['setUp'],
+ 'after' => ['tearDown'],
+ 'afterClass' => ['tearDownAfterClass']
+ ];
+ }
+
+ /**
+ * @param string $className
+ * @param string $methodName
+ * @param string $settingName
+ *
+ * @return bool
+ */
+ private static function getBooleanAnnotationSetting($className, $methodName, $settingName)
+ {
+ $annotations = self::parseTestMethodAnnotations(
+ $className,
+ $methodName
+ );
+
+ $result = null;
+
+ if (isset($annotations['class'][$settingName])) {
+ if ($annotations['class'][$settingName][0] == 'enabled') {
+ $result = true;
+ } elseif ($annotations['class'][$settingName][0] == 'disabled') {
+ $result = false;
+ }
+ }
+
+ if (isset($annotations['method'][$settingName])) {
+ if ($annotations['method'][$settingName][0] == 'enabled') {
+ $result = true;
+ } elseif ($annotations['method'][$settingName][0] == 'disabled') {
+ $result = false;
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param string $element
+ *
+ * @return array
+ *
+ * @throws PHPUnit_Framework_InvalidCoversTargetException
+ */
+ private static function resolveElementToReflectionObjects($element)
+ {
+ $codeToCoverList = [];
+
+ if (strpos($element, '\\') !== false && function_exists($element)) {
+ $codeToCoverList[] = new ReflectionFunction($element);
+ } elseif (strpos($element, '::') !== false) {
+ list($className, $methodName) = explode('::', $element);
+
+ if (isset($methodName[0]) && $methodName[0] == '<') {
+ $classes = [$className];
+
+ foreach ($classes as $className) {
+ if (!class_exists($className) &&
+ !interface_exists($className) &&
+ !trait_exists($className)) {
+ throw new PHPUnit_Framework_InvalidCoversTargetException(
+ sprintf(
+ 'Trying to @cover or @use not existing class or ' .
+ 'interface "%s".',
+ $className
+ )
+ );
+ }
+
+ $class = new ReflectionClass($className);
+ $methods = $class->getMethods();
+ $inverse = isset($methodName[1]) && $methodName[1] == '!';
+
+ if (strpos($methodName, 'protected')) {
+ $visibility = 'isProtected';
+ } elseif (strpos($methodName, 'private')) {
+ $visibility = 'isPrivate';
+ } elseif (strpos($methodName, 'public')) {
+ $visibility = 'isPublic';
+ }
+
+ foreach ($methods as $method) {
+ if ($inverse && !$method->$visibility()) {
+ $codeToCoverList[] = $method;
+ } elseif (!$inverse && $method->$visibility()) {
+ $codeToCoverList[] = $method;
+ }
+ }
+ }
+ } else {
+ $classes = [$className];
+
+ foreach ($classes as $className) {
+ if ($className == '' && function_exists($methodName)) {
+ $codeToCoverList[] = new ReflectionFunction(
+ $methodName
+ );
+ } else {
+ if (!((class_exists($className) ||
+ interface_exists($className) ||
+ trait_exists($className)) &&
+ method_exists($className, $methodName))) {
+ throw new PHPUnit_Framework_InvalidCoversTargetException(
+ sprintf(
+ 'Trying to @cover or @use not existing method "%s::%s".',
+ $className,
+ $methodName
+ )
+ );
+ }
+
+ $codeToCoverList[] = new ReflectionMethod(
+ $className,
+ $methodName
+ );
+ }
+ }
+ }
+ } else {
+ $extended = false;
+
+ if (strpos($element, '<extended>') !== false) {
+ $element = str_replace('<extended>', '', $element);
+ $extended = true;
+ }
+
+ $classes = [$element];
+
+ if ($extended) {
+ $classes = array_merge(
+ $classes,
+ class_implements($element),
+ class_parents($element)
+ );
+ }
+
+ foreach ($classes as $className) {
+ if (!class_exists($className) &&
+ !interface_exists($className) &&
+ !trait_exists($className)) {
+ throw new PHPUnit_Framework_InvalidCoversTargetException(
+ sprintf(
+ 'Trying to @cover or @use not existing class or ' .
+ 'interface "%s".',
+ $className
+ )
+ );
+ }
+
+ $codeToCoverList[] = new ReflectionClass($className);
+ }
+ }
+
+ return $codeToCoverList;
+ }
+
+ /**
+ * @param array $reflectors
+ *
+ * @return array
+ */
+ private static function resolveReflectionObjectsToLines(array $reflectors)
+ {
+ $result = [];
+
+ foreach ($reflectors as $reflector) {
+ $filename = $reflector->getFileName();
+
+ if (!isset($result[$filename])) {
+ $result[$filename] = [];
+ }
+
+ $result[$filename] = array_merge(
+ $result[$filename],
+ range($reflector->getStartLine(), $reflector->getEndLine())
+ );
+ }
+
+ foreach ($result as $filename => $lineNumbers) {
+ $result[$filename] = array_keys(array_flip($lineNumbers));
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param ReflectionMethod $method
+ *
+ * @return bool
+ */
+ private static function isBeforeClassMethod(ReflectionMethod $method)
+ {
+ return $method->isStatic() && strpos($method->getDocComment(), '@beforeClass') !== false;
+ }
+
+ /**
+ * @param ReflectionMethod $method
+ *
+ * @return bool
+ */
+ private static function isBeforeMethod(ReflectionMethod $method)
+ {
+ return preg_match('/@before\b/', $method->getDocComment());
+ }
+
+ /**
+ * @param ReflectionMethod $method
+ *
+ * @return bool
+ */
+ private static function isAfterClassMethod(ReflectionMethod $method)
+ {
+ return $method->isStatic() && strpos($method->getDocComment(), '@afterClass') !== false;
+ }
+
+ /**
+ * @param ReflectionMethod $method
+ *
+ * @return bool
+ */
+ private static function isAfterMethod(ReflectionMethod $method)
+ {
+ return preg_match('/@after\b/', $method->getDocComment());
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php b/vendor/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php
new file mode 100644
index 0000000..76a139b
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php
@@ -0,0 +1,142 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Prettifies class and method names for use in TestDox documentation.
+ */
+class PHPUnit_Util_TestDox_NamePrettifier
+{
+ /**
+ * @var string
+ */
+ protected $prefix = 'Test';
+
+ /**
+ * @var string
+ */
+ protected $suffix = 'Test';
+
+ /**
+ * @var array
+ */
+ protected $strings = [];
+
+ /**
+ * Prettifies the name of a test class.
+ *
+ * @param string $name
+ *
+ * @return string
+ */
+ public function prettifyTestClass($name)
+ {
+ $title = $name;
+
+ if ($this->suffix !== null &&
+ $this->suffix == substr($name, -1 * strlen($this->suffix))) {
+ $title = substr($title, 0, strripos($title, $this->suffix));
+ }
+
+ if ($this->prefix !== null &&
+ $this->prefix == substr($name, 0, strlen($this->prefix))) {
+ $title = substr($title, strlen($this->prefix));
+ }
+
+ if (substr($title, 0, 1) == '\\') {
+ $title = substr($title, 1);
+ }
+
+ return $title;
+ }
+
+ /**
+ * Prettifies the name of a test method.
+ *
+ * @param string $name
+ *
+ * @return string
+ */
+ public function prettifyTestMethod($name)
+ {
+ $buffer = '';
+
+ if (!is_string($name) || strlen($name) == 0) {
+ return $buffer;
+ }
+
+ $string = preg_replace('#\d+$#', '', $name, -1, $count);
+
+ if (in_array($string, $this->strings)) {
+ $name = $string;
+ } elseif ($count == 0) {
+ $this->strings[] = $string;
+ }
+
+ if (substr($name, 0, 4) == 'test') {
+ $name = substr($name, 4);
+ }
+
+ if (strlen($name) == 0) {
+ return $buffer;
+ }
+
+ $name[0] = strtoupper($name[0]);
+
+ if (strpos($name, '_') !== false) {
+ return trim(str_replace('_', ' ', $name));
+ }
+
+ $max = strlen($name);
+ $wasNumeric = false;
+
+ for ($i = 0; $i < $max; $i++) {
+ if ($i > 0 &&
+ ord($name[$i]) >= 65 &&
+ ord($name[$i]) <= 90) {
+ $buffer .= ' ' . strtolower($name[$i]);
+ } else {
+ $isNumeric = is_numeric($name[$i]);
+
+ if (!$wasNumeric && $isNumeric) {
+ $buffer .= ' ';
+ $wasNumeric = true;
+ }
+
+ if ($wasNumeric && !$isNumeric) {
+ $wasNumeric = false;
+ }
+
+ $buffer .= $name[$i];
+ }
+ }
+
+ return $buffer;
+ }
+
+ /**
+ * Sets the prefix of test names.
+ *
+ * @param string $prefix
+ */
+ public function setPrefix($prefix)
+ {
+ $this->prefix = $prefix;
+ }
+
+ /**
+ * Sets the suffix of test names.
+ *
+ * @param string $suffix
+ */
+ public function setSuffix($suffix)
+ {
+ $this->suffix = $suffix;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php b/vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php
new file mode 100644
index 0000000..d83998e
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php
@@ -0,0 +1,399 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Base class for printers of TestDox documentation.
+ */
+abstract class PHPUnit_Util_TestDox_ResultPrinter extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
+{
+ /**
+ * @var PHPUnit_Util_TestDox_NamePrettifier
+ */
+ protected $prettifier;
+
+ /**
+ * @var string
+ */
+ protected $testClass = '';
+
+ /**
+ * @var int
+ */
+ protected $testStatus = false;
+
+ /**
+ * @var array
+ */
+ protected $tests = [];
+
+ /**
+ * @var int
+ */
+ protected $successful = 0;
+
+ /**
+ * @var int
+ */
+ protected $warned = 0;
+
+ /**
+ * @var int
+ */
+ protected $failed = 0;
+
+ /**
+ * @var int
+ */
+ protected $risky = 0;
+
+ /**
+ * @var int
+ */
+ protected $skipped = 0;
+
+ /**
+ * @var int
+ */
+ protected $incomplete = 0;
+
+ /**
+ * @var string
+ */
+ protected $currentTestClassPrettified;
+
+ /**
+ * @var string
+ */
+ protected $currentTestMethodPrettified;
+
+ /**
+ * @var array
+ */
+ private $groups;
+
+ /**
+ * @var array
+ */
+ private $excludeGroups;
+
+ /**
+ * @param resource $out
+ * @param array $groups
+ * @param array $excludeGroups
+ */
+ public function __construct($out = null, array $groups = [], array $excludeGroups = [])
+ {
+ parent::__construct($out);
+
+ $this->groups = $groups;
+ $this->excludeGroups = $excludeGroups;
+
+ $this->prettifier = new PHPUnit_Util_TestDox_NamePrettifier;
+ $this->startRun();
+ }
+
+ /**
+ * Flush buffer and close output.
+ */
+ public function flush()
+ {
+ $this->doEndClass();
+ $this->endRun();
+
+ parent::flush();
+ }
+
+ /**
+ * An error occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ if (!$this->isOfInterest($test)) {
+ return;
+ }
+
+ $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_ERROR;
+ $this->failed++;
+ }
+
+ /**
+ * A warning occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_Warning $e
+ * @param float $time
+ */
+ public function addWarning(PHPUnit_Framework_Test $test, PHPUnit_Framework_Warning $e, $time)
+ {
+ if (!$this->isOfInterest($test)) {
+ return;
+ }
+
+ $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_WARNING;
+ $this->warned++;
+ }
+
+ /**
+ * A failure occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_AssertionFailedError $e
+ * @param float $time
+ */
+ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
+ {
+ if (!$this->isOfInterest($test)) {
+ return;
+ }
+
+ $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE;
+ $this->failed++;
+ }
+
+ /**
+ * Incomplete test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ if (!$this->isOfInterest($test)) {
+ return;
+ }
+
+ $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE;
+ $this->incomplete++;
+ }
+
+ /**
+ * Risky test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ if (!$this->isOfInterest($test)) {
+ return;
+ }
+
+ $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_RISKY;
+ $this->risky++;
+ }
+
+ /**
+ * Skipped test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ if (!$this->isOfInterest($test)) {
+ return;
+ }
+
+ $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED;
+ $this->skipped++;
+ }
+
+ /**
+ * A testsuite started.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ }
+
+ /**
+ * A testsuite ended.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ }
+
+ /**
+ * A test started.
+ *
+ * @param PHPUnit_Framework_Test $test
+ */
+ public function startTest(PHPUnit_Framework_Test $test)
+ {
+ if (!$this->isOfInterest($test)) {
+ return;
+ }
+
+ $class = get_class($test);
+
+ if ($this->testClass != $class) {
+ if ($this->testClass != '') {
+ $this->doEndClass();
+ }
+
+ $classAnnotations = PHPUnit_Util_Test::parseTestMethodAnnotations($class);
+ if (isset($classAnnotations['class']['testdox'][0])) {
+ $this->currentTestClassPrettified = $classAnnotations['class']['testdox'][0];
+ } else {
+ $this->currentTestClassPrettified = $this->prettifier->prettifyTestClass($class);
+ }
+
+ $this->startClass($class);
+
+ $this->testClass = $class;
+ $this->tests = [];
+ }
+
+ $annotations = $test->getAnnotations();
+
+ if (isset($annotations['method']['testdox'][0])) {
+ $this->currentTestMethodPrettified = $annotations['method']['testdox'][0];
+ } else {
+ $this->currentTestMethodPrettified = $this->prettifier->prettifyTestMethod($test->getName(false));
+ }
+
+ if ($test instanceof PHPUnit_Framework_TestCase && $test->usesDataProvider()) {
+ $this->currentTestMethodPrettified .= ' ' . $test->dataDescription();
+ }
+
+ $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_PASSED;
+ }
+
+ /**
+ * A test ended.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param float $time
+ */
+ public function endTest(PHPUnit_Framework_Test $test, $time)
+ {
+ if (!$this->isOfInterest($test)) {
+ return;
+ }
+
+ if (!isset($this->tests[$this->currentTestMethodPrettified])) {
+ if ($this->testStatus == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) {
+ $this->tests[$this->currentTestMethodPrettified]['success'] = 1;
+ $this->tests[$this->currentTestMethodPrettified]['failure'] = 0;
+ } else {
+ $this->tests[$this->currentTestMethodPrettified]['success'] = 0;
+ $this->tests[$this->currentTestMethodPrettified]['failure'] = 1;
+ }
+ } else {
+ if ($this->testStatus == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) {
+ $this->tests[$this->currentTestMethodPrettified]['success']++;
+ } else {
+ $this->tests[$this->currentTestMethodPrettified]['failure']++;
+ }
+ }
+
+ $this->currentTestClassPrettified = null;
+ $this->currentTestMethodPrettified = null;
+ }
+
+ protected function doEndClass()
+ {
+ foreach ($this->tests as $name => $data) {
+ $this->onTest($name, $data['failure'] == 0);
+ }
+
+ $this->endClass($this->testClass);
+ }
+
+ /**
+ * Handler for 'start run' event.
+ */
+ protected function startRun()
+ {
+ }
+
+ /**
+ * Handler for 'start class' event.
+ *
+ * @param string $name
+ */
+ protected function startClass($name)
+ {
+ }
+
+ /**
+ * Handler for 'on test' event.
+ *
+ * @param string $name
+ * @param bool $success
+ */
+ protected function onTest($name, $success = true)
+ {
+ }
+
+ /**
+ * Handler for 'end class' event.
+ *
+ * @param string $name
+ */
+ protected function endClass($name)
+ {
+ }
+
+ /**
+ * Handler for 'end run' event.
+ */
+ protected function endRun()
+ {
+ }
+
+ /**
+ * @param PHPUnit_Framework_Test $test
+ *
+ * @return bool
+ */
+ private function isOfInterest(PHPUnit_Framework_Test $test)
+ {
+ if (!$test instanceof PHPUnit_Framework_TestCase) {
+ return false;
+ }
+
+ if ($test instanceof PHPUnit_Framework_WarningTestCase) {
+ return false;
+ }
+
+ if (!empty($this->groups)) {
+ foreach ($test->getGroups() as $group) {
+ if (in_array($group, $this->groups)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ if (!empty($this->excludeGroups)) {
+ foreach ($test->getGroups() as $group) {
+ if (in_array($group, $this->excludeGroups)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter/HTML.php b/vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter/HTML.php
new file mode 100644
index 0000000..b46a02e
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter/HTML.php
@@ -0,0 +1,137 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Prints TestDox documentation in HTML format.
+ */
+class PHPUnit_Util_TestDox_ResultPrinter_HTML extends PHPUnit_Util_TestDox_ResultPrinter
+{
+ /**
+ * @var string
+ */
+ private $pageHeader = <<<EOT
+<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8"/>
+ <title>Test Documentation</title>
+ <style>
+ body {
+ text-rendering: optimizeLegibility;
+ font-variant-ligatures: common-ligatures;
+ font-kerning: normal;
+ margin-left: 2em;
+ }
+
+ body > ul > li {
+ font-family: Source Serif Pro, PT Sans, Trebuchet MS, Helvetica, Arial;
+ font-size: 2em;
+ }
+
+ h2 {
+ font-family: Tahoma, Helvetica, Arial;
+ font-size: 3em;
+ }
+
+ ul {
+ list-style: none;
+ margin-bottom: 1em;
+ }
+ </style>
+ </head>
+ <body>
+EOT;
+
+ /**
+ * @var string
+ */
+ private $classHeader = <<<EOT
+
+ <h2 id="%s">%s</h2>
+ <ul>
+
+EOT;
+
+ /**
+ * @var string
+ */
+ private $classFooter = <<<EOT
+ </ul>
+EOT;
+
+ /**
+ * @var string
+ */
+ private $pageFooter = <<<EOT
+
+ </body>
+</html>
+EOT;
+
+ /**
+ * Handler for 'start run' event.
+ */
+ protected function startRun()
+ {
+ $this->write($this->pageHeader);
+ }
+
+ /**
+ * Handler for 'start class' event.
+ *
+ * @param string $name
+ */
+ protected function startClass($name)
+ {
+ $this->write(
+ sprintf(
+ $this->classHeader,
+ $name,
+ $this->currentTestClassPrettified
+ )
+ );
+ }
+
+ /**
+ * Handler for 'on test' event.
+ *
+ * @param string $name
+ * @param bool $success
+ */
+ protected function onTest($name, $success = true)
+ {
+ $this->write(
+ sprintf(
+ " <li style=\"color: %s;\">%s %s</li>\n",
+ $success ? '#555753' : '#ef2929',
+ $success ? '✓' : '❌',
+ $name
+ )
+ );
+ }
+
+ /**
+ * Handler for 'end class' event.
+ *
+ * @param string $name
+ */
+ protected function endClass($name)
+ {
+ $this->write($this->classFooter);
+ }
+
+ /**
+ * Handler for 'end run' event.
+ */
+ protected function endRun()
+ {
+ $this->write($this->pageFooter);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter/Text.php b/vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter/Text.php
new file mode 100644
index 0000000..10ef904
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter/Text.php
@@ -0,0 +1,52 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Prints TestDox documentation in text format.
+ */
+class PHPUnit_Util_TestDox_ResultPrinter_Text extends PHPUnit_Util_TestDox_ResultPrinter
+{
+ /**
+ * Handler for 'start class' event.
+ *
+ * @param string $name
+ */
+ protected function startClass($name)
+ {
+ $this->write($this->currentTestClassPrettified . "\n");
+ }
+
+ /**
+ * Handler for 'on test' event.
+ *
+ * @param string $name
+ * @param bool $success
+ */
+ protected function onTest($name, $success = true)
+ {
+ if ($success) {
+ $this->write(' [x] ');
+ } else {
+ $this->write(' [ ] ');
+ }
+
+ $this->write($name . "\n");
+ }
+
+ /**
+ * Handler for 'end class' event.
+ *
+ * @param string $name
+ */
+ protected function endClass($name)
+ {
+ $this->write("\n");
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter/XML.php b/vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter/XML.php
new file mode 100644
index 0000000..aa3d3f6
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter/XML.php
@@ -0,0 +1,225 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Util_TestDox_ResultPrinter_XML extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
+{
+ /**
+ * @var DOMDocument
+ */
+ private $document;
+
+ /**
+ * @var DOMElement
+ */
+ private $root;
+
+ /**
+ * @var PHPUnit_Util_TestDox_NamePrettifier
+ */
+ private $prettifier;
+
+ /**
+ * @var Exception
+ */
+ private $exception;
+
+ /**
+ * @param string|resource $out
+ */
+ public function __construct($out = null)
+ {
+ $this->document = new DOMDocument('1.0', 'UTF-8');
+ $this->document->formatOutput = true;
+
+ $this->root = $this->document->createElement('tests');
+ $this->document->appendChild($this->root);
+
+ $this->prettifier = new PHPUnit_Util_TestDox_NamePrettifier;
+
+ parent::__construct($out);
+ }
+
+ /**
+ * Flush buffer and close output.
+ */
+ public function flush()
+ {
+ $this->write($this->document->saveXML());
+
+ parent::flush();
+ }
+
+ /**
+ * An error occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->exception = $e;
+ }
+
+ /**
+ * A warning occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_Warning $e
+ * @param float $time
+ */
+ public function addWarning(PHPUnit_Framework_Test $test, PHPUnit_Framework_Warning $e, $time)
+ {
+ }
+
+ /**
+ * A failure occurred.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param PHPUnit_Framework_AssertionFailedError $e
+ * @param float $time
+ */
+ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
+ {
+ $this->exception = $e;
+ }
+
+ /**
+ * Incomplete test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ }
+
+ /**
+ * Risky test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ }
+
+ /**
+ * Skipped test.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param Exception $e
+ * @param float $time
+ */
+ public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ }
+
+ /**
+ * A test suite started.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ }
+
+ /**
+ * A test suite ended.
+ *
+ * @param PHPUnit_Framework_TestSuite $suite
+ */
+ public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ }
+
+ /**
+ * A test started.
+ *
+ * @param PHPUnit_Framework_Test $test
+ */
+ public function startTest(PHPUnit_Framework_Test $test)
+ {
+ $this->exception = null;
+ }
+
+ /**
+ * A test ended.
+ *
+ * @param PHPUnit_Framework_Test $test
+ * @param float $time
+ */
+ public function endTest(PHPUnit_Framework_Test $test, $time)
+ {
+ if (!$test instanceof PHPUnit_Framework_TestCase) {
+ return;
+ }
+
+ /* @var PHPUnit_Framework_TestCase $test */
+
+ $groups = array_filter(
+ $test->getGroups(),
+ function ($group) {
+ if ($group == 'small' || $group == 'medium' || $group == 'large') {
+ return false;
+ }
+
+ return true;
+ }
+ );
+
+ $node = $this->document->createElement('test');
+
+ $node->setAttribute('className', get_class($test));
+ $node->setAttribute('methodName', $test->getName());
+ $node->setAttribute('prettifiedClassName', $this->prettifier->prettifyTestClass(get_class($test)));
+ $node->setAttribute('prettifiedMethodName', $this->prettifier->prettifyTestMethod($test->getName()));
+ $node->setAttribute('status', $test->getStatus());
+ $node->setAttribute('time', $time);
+ $node->setAttribute('size', $test->getSize());
+ $node->setAttribute('groups', implode(',', $groups));
+
+ $inlineAnnotations = PHPUnit_Util_Test::getInlineAnnotations(get_class($test), $test->getName());
+
+ if (isset($inlineAnnotations['given']) && isset($inlineAnnotations['when']) && isset($inlineAnnotations['then'])) {
+ $node->setAttribute('given', $inlineAnnotations['given']['value']);
+ $node->setAttribute('givenStartLine', $inlineAnnotations['given']['line']);
+ $node->setAttribute('when', $inlineAnnotations['when']['value']);
+ $node->setAttribute('whenStartLine', $inlineAnnotations['when']['line']);
+ $node->setAttribute('then', $inlineAnnotations['then']['value']);
+ $node->setAttribute('thenStartLine', $inlineAnnotations['then']['line']);
+ }
+
+ if ($this->exception !== null) {
+ if ($this->exception instanceof PHPUnit_Framework_Exception) {
+ $steps = $this->exception->getSerializableTrace();
+ } else {
+ $steps = $this->exception->getTrace();
+ }
+
+ $class = new ReflectionClass($test);
+ $file = $class->getFileName();
+
+ foreach ($steps as $step) {
+ if (isset($step['file']) && $step['file'] == $file) {
+ $node->setAttribute('exceptionLine', $step['line']);
+
+ break;
+ }
+ }
+
+ $node->setAttribute('exceptionMessage', $this->exception->getMessage());
+ }
+
+ $this->root->appendChild($node);
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/TestSuiteIterator.php b/vendor/phpunit/phpunit/src/Util/TestSuiteIterator.php
new file mode 100644
index 0000000..6c73b19
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/TestSuiteIterator.php
@@ -0,0 +1,101 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Iterator for test suites.
+ */
+class PHPUnit_Util_TestSuiteIterator implements RecursiveIterator
+{
+ /**
+ * @var int
+ */
+ protected $position;
+
+ /**
+ * @var PHPUnit_Framework_Test[]
+ */
+ protected $tests;
+
+ /**
+ * @param PHPUnit_Framework_TestSuite $testSuite
+ */
+ public function __construct(PHPUnit_Framework_TestSuite $testSuite)
+ {
+ $this->tests = $testSuite->tests();
+ }
+
+ /**
+ * Rewinds the Iterator to the first element.
+ */
+ public function rewind()
+ {
+ $this->position = 0;
+ }
+
+ /**
+ * Checks if there is a current element after calls to rewind() or next().
+ *
+ * @return bool
+ */
+ public function valid()
+ {
+ return $this->position < count($this->tests);
+ }
+
+ /**
+ * Returns the key of the current element.
+ *
+ * @return int
+ */
+ public function key()
+ {
+ return $this->position;
+ }
+
+ /**
+ * Returns the current element.
+ *
+ * @return PHPUnit_Framework_Test
+ */
+ public function current()
+ {
+ return $this->valid() ? $this->tests[$this->position] : null;
+ }
+
+ /**
+ * Moves forward to next element.
+ */
+ public function next()
+ {
+ $this->position++;
+ }
+
+ /**
+ * Returns the sub iterator for the current element.
+ *
+ * @return PHPUnit_Util_TestSuiteIterator
+ */
+ public function getChildren()
+ {
+ return new self(
+ $this->tests[$this->position]
+ );
+ }
+
+ /**
+ * Checks whether the current element has children.
+ *
+ * @return bool
+ */
+ public function hasChildren()
+ {
+ return $this->tests[$this->position] instanceof PHPUnit_Framework_TestSuite;
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/Type.php b/vendor/phpunit/phpunit/src/Util/Type.php
new file mode 100644
index 0000000..9a10aea
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/Type.php
@@ -0,0 +1,41 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Utility class for textual type (and value) representation.
+ */
+class PHPUnit_Util_Type
+{
+ /**
+ * @param string $type
+ *
+ * @return bool
+ */
+ public static function isType($type)
+ {
+ return in_array(
+ $type,
+ [
+ 'numeric',
+ 'integer',
+ 'int',
+ 'float',
+ 'string',
+ 'boolean',
+ 'bool',
+ 'null',
+ 'array',
+ 'object',
+ 'resource',
+ 'scalar'
+ ]
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/src/Util/XML.php b/vendor/phpunit/phpunit/src/Util/XML.php
new file mode 100644
index 0000000..81dce23
--- /dev/null
+++ b/vendor/phpunit/phpunit/src/Util/XML.php
@@ -0,0 +1,246 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * XML helpers.
+ */
+class PHPUnit_Util_XML
+{
+ /**
+ * Load an $actual document into a DOMDocument. This is called
+ * from the selector assertions.
+ *
+ * If $actual is already a DOMDocument, it is returned with
+ * no changes. Otherwise, $actual is loaded into a new DOMDocument
+ * as either HTML or XML, depending on the value of $isHtml. If $isHtml is
+ * false and $xinclude is true, xinclude is performed on the loaded
+ * DOMDocument.
+ *
+ * Note: prior to PHPUnit 3.3.0, this method loaded a file and
+ * not a string as it currently does. To load a file into a
+ * DOMDocument, use loadFile() instead.
+ *
+ * @param string|DOMDocument $actual
+ * @param bool $isHtml
+ * @param string $filename
+ * @param bool $xinclude
+ * @param bool $strict
+ *
+ * @return DOMDocument
+ */
+ public static function load($actual, $isHtml = false, $filename = '', $xinclude = false, $strict = false)
+ {
+ if ($actual instanceof DOMDocument) {
+ return $actual;
+ }
+
+ if (!is_string($actual)) {
+ throw new PHPUnit_Framework_Exception('Could not load XML from ' . gettype($actual));
+ }
+
+ if ($actual === '') {
+ throw new PHPUnit_Framework_Exception('Could not load XML from empty string');
+ }
+
+ // Required for XInclude on Windows.
+ if ($xinclude) {
+ $cwd = getcwd();
+ @chdir(dirname($filename));
+ }
+
+ $document = new DOMDocument;
+ $document->preserveWhiteSpace = false;
+
+ $internal = libxml_use_internal_errors(true);
+ $message = '';
+ $reporting = error_reporting(0);
+
+ if ('' !== $filename) {
+ // Necessary for xinclude
+ $document->documentURI = $filename;
+ }
+
+ if ($isHtml) {
+ $loaded = $document->loadHTML($actual);
+ } else {
+ $loaded = $document->loadXML($actual);
+ }
+
+ if (!$isHtml && $xinclude) {
+ $document->xinclude();
+ }
+
+ foreach (libxml_get_errors() as $error) {
+ $message .= "\n" . $error->message;
+ }
+
+ libxml_use_internal_errors($internal);
+ error_reporting($reporting);
+
+ if ($xinclude) {
+ @chdir($cwd);
+ }
+
+ if ($loaded === false || ($strict && $message !== '')) {
+ if ($filename !== '') {
+ throw new PHPUnit_Framework_Exception(
+ sprintf(
+ 'Could not load "%s".%s',
+ $filename,
+ $message != '' ? "\n" . $message : ''
+ )
+ );
+ } else {
+ if ($message === '') {
+ $message = 'Could not load XML for unknown reason';
+ }
+ throw new PHPUnit_Framework_Exception($message);
+ }
+ }
+
+ return $document;
+ }
+
+ /**
+ * Loads an XML (or HTML) file into a DOMDocument object.
+ *
+ * @param string $filename
+ * @param bool $isHtml
+ * @param bool $xinclude
+ * @param bool $strict
+ *
+ * @return DOMDocument
+ */
+ public static function loadFile($filename, $isHtml = false, $xinclude = false, $strict = false)
+ {
+ $reporting = error_reporting(0);
+ $contents = file_get_contents($filename);
+ error_reporting($reporting);
+
+ if ($contents === false) {
+ throw new PHPUnit_Framework_Exception(
+ sprintf(
+ 'Could not read "%s".',
+ $filename
+ )
+ );
+ }
+
+ return self::load($contents, $isHtml, $filename, $xinclude, $strict);
+ }
+
+ /**
+ * @param DOMNode $node
+ */
+ public static function removeCharacterDataNodes(DOMNode $node)
+ {
+ if ($node->hasChildNodes()) {
+ for ($i = $node->childNodes->length - 1; $i >= 0; $i--) {
+ if (($child = $node->childNodes->item($i)) instanceof DOMCharacterData) {
+ $node->removeChild($child);
+ }
+ }
+ }
+ }
+
+ /**
+ * Escapes a string for the use in XML documents
+ * Any Unicode character is allowed, excluding the surrogate blocks, FFFE,
+ * and FFFF (not even as character reference).
+ * See http://www.w3.org/TR/xml/#charsets
+ *
+ * @param string $string
+ *
+ * @return string
+ */
+ public static function prepareString($string)
+ {
+ return preg_replace(
+ '/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]/',
+ '',
+ htmlspecialchars(
+ PHPUnit_Util_String::convertToUtf8($string),
+ ENT_QUOTES,
+ 'UTF-8'
+ )
+ );
+ }
+
+ /**
+ * "Convert" a DOMElement object into a PHP variable.
+ *
+ * @param DOMElement $element
+ *
+ * @return mixed
+ */
+ public static function xmlToVariable(DOMElement $element)
+ {
+ $variable = null;
+
+ switch ($element->tagName) {
+ case 'array':
+ $variable = [];
+
+ foreach ($element->childNodes as $entry) {
+ if (!$entry instanceof DOMElement || $entry->tagName !== 'element') {
+ continue;
+ }
+ $item = $entry->childNodes->item(0);
+
+ if ($item instanceof DOMText) {
+ $item = $entry->childNodes->item(1);
+ }
+
+ $value = self::xmlToVariable($item);
+
+ if ($entry->hasAttribute('key')) {
+ $variable[(string) $entry->getAttribute('key')] = $value;
+ } else {
+ $variable[] = $value;
+ }
+ }
+ break;
+
+ case 'object':
+ $className = $element->getAttribute('class');
+
+ if ($element->hasChildNodes()) {
+ $arguments = $element->childNodes->item(1)->childNodes;
+ $constructorArgs = [];
+
+ foreach ($arguments as $argument) {
+ if ($argument instanceof DOMElement) {
+ $constructorArgs[] = self::xmlToVariable($argument);
+ }
+ }
+
+ $class = new ReflectionClass($className);
+ $variable = $class->newInstanceArgs($constructorArgs);
+ } else {
+ $variable = new $className;
+ }
+ break;
+
+ case 'boolean':
+ $variable = $element->textContent == 'true' ? true : false;
+ break;
+
+ case 'integer':
+ case 'double':
+ case 'string':
+ $variable = $element->textContent;
+
+ settype($variable, $element->tagName);
+ break;
+ }
+
+ return $variable;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Extensions/PhptTestCaseTest.php b/vendor/phpunit/phpunit/tests/Extensions/PhptTestCaseTest.php
new file mode 100644
index 0000000..8d830e6
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Extensions/PhptTestCaseTest.php
@@ -0,0 +1,263 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Extensions_PhptTestCaseTest extends \PHPUnit_Framework_TestCase
+{
+ const EXPECT_CONTENT = <<<EOF
+--TEST--
+EXPECT test
+--FILE--
+<?php echo "Hello PHPUnit!"; ?>
+--EXPECT--
+Hello PHPUnit!
+EOF;
+
+ const EXPECTF_CONTENT = <<<EOF
+--TEST--
+EXPECTF test
+--FILE--
+<?php echo "Hello PHPUnit!"; ?>
+--EXPECTF--
+Hello %s!
+EOF;
+
+ const EXPECTREGEX_CONTENT = <<<EOF
+--TEST--
+EXPECTREGEX test
+--FILE--
+<?php echo "Hello PHPUnit!"; ?>
+--EXPECTREGEX--
+Hello [HPU]{4}[nit]{3}!
+EOF;
+
+ const FILE_SECTION = <<<EOF
+<?php echo "Hello PHPUnit!"; ?>
+
+EOF;
+
+ protected $filename;
+ protected $testCase;
+ protected $phpUtil;
+
+ protected function setUp()
+ {
+ $this->filename = sys_get_temp_dir() . '/phpunit.phpt';
+ touch($this->filename);
+
+ $this->phpUtil = $this->getMockForAbstractClass('PHPUnit_Util_PHP', [], '', false);
+
+ $this->testCase = new PHPUnit_Extensions_PhptTestCase($this->filename, $this->phpUtil);
+ }
+
+ protected function tearDown()
+ {
+ @unlink($this->filename);
+
+ $this->filename = null;
+ $this->testCase = null;
+ }
+
+ /**
+ * Defines the content of the current PHPT test.
+ *
+ * @param string $content
+ */
+ private function setPhpContent($content)
+ {
+ file_put_contents($this->filename, $content);
+ }
+
+ public function testShouldRunFileSectionAsTest()
+ {
+ $this->setPhpContent(self::EXPECT_CONTENT);
+
+ $fileSection = '<?php echo "Hello PHPUnit!"; ?>' . PHP_EOL;
+
+ $this->phpUtil
+ ->expects($this->once())
+ ->method('runJob')
+ ->with($fileSection)
+ ->will($this->returnValue(['stdout' => '', 'stderr' => '']));
+
+ $this->testCase->run();
+ }
+
+ public function testShouldRunSkipifSectionWhenExists()
+ {
+ $skipifSection = '<?php /** Nothing **/ ?>' . PHP_EOL;
+
+ $phptContent = self::EXPECT_CONTENT . PHP_EOL;
+ $phptContent .= '--SKIPIF--' . PHP_EOL;
+ $phptContent .= $skipifSection;
+
+ $this->setPhpContent($phptContent);
+
+ $this->phpUtil
+ ->expects($this->at(0))
+ ->method('runJob')
+ ->with($skipifSection)
+ ->will($this->returnValue(['stdout' => '', 'stderr' => '']));
+
+ $this->testCase->run();
+ }
+
+ public function testShouldNotRunTestSectionIfSkipifSectionReturnsOutputWithSkipWord()
+ {
+ $skipifSection = '<?php echo "skip: Reason"; ?>' . PHP_EOL;
+
+ $phptContent = self::EXPECT_CONTENT . PHP_EOL;
+ $phptContent .= '--SKIPIF--' . PHP_EOL;
+ $phptContent .= $skipifSection;
+
+ $this->setPhpContent($phptContent);
+
+ $this->phpUtil
+ ->expects($this->once())
+ ->method('runJob')
+ ->with($skipifSection)
+ ->will($this->returnValue(['stdout' => 'skip: Reason', 'stderr' => '']));
+
+ $this->testCase->run();
+ }
+
+ public function testShouldRunCleanSectionWhenDefined()
+ {
+ $cleanSection = '<?php unlink("/tmp/something"); ?>' . PHP_EOL;
+
+ $phptContent = self::EXPECT_CONTENT . PHP_EOL;
+ $phptContent .= '--CLEAN--' . PHP_EOL;
+ $phptContent .= $cleanSection;
+
+ $this->setPhpContent($phptContent);
+
+ $this->phpUtil
+ ->expects($this->at(1))
+ ->method('runJob')
+ ->with($cleanSection);
+
+ $this->testCase->run();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ * @expectedExceptionMessage Invalid PHPT file
+ */
+ public function testShouldThrowsAnExceptionWhenPhptFileIsEmpty()
+ {
+ $this->setPhpContent('');
+
+ $this->testCase->run();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ * @expectedExceptionMessage Invalid PHPT file
+ */
+ public function testShouldThrowsAnExceptionWhenFileSectionIsMissing()
+ {
+ $this->setPhpContent(
+ <<<EOF
+--TEST--
+Something to decribe it
+--EXPECT--
+Something
+EOF
+ );
+ $this->testCase->run();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ * @expectedExceptionMessage Invalid PHPT file
+ */
+ public function testShouldThrowsAnExceptionWhenThereIsNoExpecOrExpectifOrExpecregexSectionInPhptFile()
+ {
+ $this->setPhpContent(
+ <<<EOF
+--TEST--
+Something to decribe it
+--FILE--
+<?php
+echo "Hello world!\n";
+?>
+EOF
+ );
+ $this->testCase->run();
+ }
+
+ public function testShouldValidateExpectSession()
+ {
+ $this->setPhpContent(self::EXPECT_CONTENT);
+
+ $this->phpUtil
+ ->expects($this->once())
+ ->method('runJob')
+ ->with(self::FILE_SECTION)
+ ->will($this->returnValue(['stdout' => 'Hello PHPUnit!', 'stderr' => '']));
+
+ $result = $this->testCase->run();
+
+ $this->assertTrue($result->wasSuccessful());
+ }
+
+ public function testShouldValidateExpectfSession()
+ {
+ $this->setPhpContent(self::EXPECTF_CONTENT);
+
+ $this->phpUtil
+ ->expects($this->once())
+ ->method('runJob')
+ ->with(self::FILE_SECTION)
+ ->will($this->returnValue(['stdout' => 'Hello PHPUnit!', 'stderr' => '']));
+
+ $result = $this->testCase->run();
+
+ $this->assertTrue($result->wasSuccessful());
+ }
+
+ public function testShouldValidateExpectregexSession()
+ {
+ $this->setPhpContent(self::EXPECTREGEX_CONTENT);
+
+ $this->phpUtil
+ ->expects($this->once())
+ ->method('runJob')
+ ->with(self::FILE_SECTION)
+ ->will($this->returnValue(['stdout' => 'Hello PHPUnit!', 'stderr' => '']));
+
+ $result = $this->testCase->run();
+
+ $this->assertTrue($result->wasSuccessful());
+ }
+
+ public function testParseIniSection()
+ {
+ $phptTestCase = new PhpTestCaseProxy(__FILE__);
+ $settings = $phptTestCase->parseIniSection("foo=1\nbar = 2\rbaz = 3\r\nempty=\nignore");
+
+ $expected = [
+ 'foo=1',
+ 'bar = 2',
+ 'baz = 3',
+ 'empty=',
+ 'ignore',
+ ];
+
+ $this->assertEquals($expected, $settings);
+ }
+}
+
+class PhpTestCaseProxy extends PHPUnit_Extensions_PhptTestCase
+{
+ public function parseIniSection($content)
+ {
+ return parent::parseIniSection($content);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Extensions/RepeatedTestTest.php b/vendor/phpunit/phpunit/tests/Extensions/RepeatedTestTest.php
new file mode 100644
index 0000000..ba494ae
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Extensions/RepeatedTestTest.php
@@ -0,0 +1,60 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Extensions_RepeatedTestTest extends PHPUnit_Framework_TestCase
+{
+ protected $suite;
+
+ public function __construct()
+ {
+ $this->suite = new PHPUnit_Framework_TestSuite;
+
+ $this->suite->addTest(new Success);
+ $this->suite->addTest(new Success);
+ }
+
+ public function testRepeatedOnce()
+ {
+ $test = new PHPUnit_Extensions_RepeatedTest($this->suite, 1);
+ $this->assertCount(2, $test);
+
+ $result = $test->run();
+ $this->assertCount(2, $result);
+ }
+
+ public function testRepeatedMoreThanOnce()
+ {
+ $test = new PHPUnit_Extensions_RepeatedTest($this->suite, 3);
+ $this->assertCount(6, $test);
+
+ $result = $test->run();
+ $this->assertCount(6, $result);
+ }
+
+ public function testRepeatedZero()
+ {
+ $test = new PHPUnit_Extensions_RepeatedTest($this->suite, 0);
+ $this->assertCount(0, $test);
+
+ $result = $test->run();
+ $this->assertCount(0, $result);
+ }
+
+ public function testRepeatedNegative()
+ {
+ try {
+ $test = new PHPUnit_Extensions_RepeatedTest($this->suite, -1);
+ } catch (Exception $e) {
+ return;
+ }
+
+ $this->fail('Should throw an Exception');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Fail/fail.phpt b/vendor/phpunit/phpunit/tests/Fail/fail.phpt
new file mode 100644
index 0000000..b88454f
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Fail/fail.phpt
@@ -0,0 +1,5 @@
+--TEST--
+// This test intentionally fails and it is checked by Travis.
+--FILE--
+--EXPECTF--
+unexpected
diff --git a/vendor/phpunit/phpunit/tests/Framework/AssertTest.php b/vendor/phpunit/phpunit/tests/Framework/AssertTest.php
new file mode 100644
index 0000000..eecd172
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Framework/AssertTest.php
@@ -0,0 +1,3768 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Framework_AssertTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @var string
+ */
+ private $filesDirectory;
+
+ protected function setUp()
+ {
+ $this->filesDirectory = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR;
+ }
+
+ public function testFail()
+ {
+ try {
+ $this->fail();
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ throw new PHPUnit_Framework_AssertionFailedError('Fail did not throw fail exception');
+ }
+
+ public function testAssertSplObjectStorageContainsObject()
+ {
+ $a = new stdClass;
+ $b = new stdClass;
+ $c = new SplObjectStorage;
+ $c->attach($a);
+
+ $this->assertContains($a, $c);
+
+ try {
+ $this->assertContains($b, $c);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertArrayContainsObject()
+ {
+ $a = new stdClass;
+ $b = new stdClass;
+
+ $this->assertContains($a, [$a]);
+
+ try {
+ $this->assertContains($a, [$b]);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertArrayContainsString()
+ {
+ $this->assertContains('foo', ['foo']);
+
+ try {
+ $this->assertContains('foo', ['bar']);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertArrayContainsNonObject()
+ {
+ $this->assertContains('foo', [true]);
+
+ try {
+ $this->assertContains('foo', [true], '', false, true, true);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertContainsOnlyInstancesOf()
+ {
+ $test = [
+ new Book(),
+ new Book
+ ];
+ $this->assertContainsOnlyInstancesOf('Book', $test);
+ $this->assertContainsOnlyInstancesOf('stdClass', [new stdClass()]);
+
+ $test2 = [
+ new Author('Test')
+ ];
+ try {
+ $this->assertContainsOnlyInstancesOf('Book', $test2);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertArrayHasKeyThrowsExceptionForInvalidFirstArgument()
+ {
+ $this->assertArrayHasKey(null, []);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertArrayHasKeyThrowsExceptionForInvalidSecondArgument()
+ {
+ $this->assertArrayHasKey(0, null);
+ }
+
+ public function testAssertArrayHasIntegerKey()
+ {
+ $this->assertArrayHasKey(0, ['foo']);
+
+ try {
+ $this->assertArrayHasKey(1, ['foo']);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertArraySubset()
+ {
+ $array = [
+ 'a' => 'item a',
+ 'b' => 'item b',
+ 'c' => ['a2' => 'item a2', 'b2' => 'item b2'],
+ 'd' => ['a2' => ['a3' => 'item a3', 'b3' => 'item b3']]
+ ];
+
+ $this->assertArraySubset(['a' => 'item a', 'c' => ['a2' => 'item a2']], $array);
+ $this->assertArraySubset(['a' => 'item a', 'd' => ['a2' => ['b3' => 'item b3']]], $array);
+
+ $arrayAccessData = new ArrayObject($array);
+
+ $this->assertArraySubset(['a' => 'item a', 'c' => ['a2' => 'item a2']], $arrayAccessData);
+ $this->assertArraySubset(['a' => 'item a', 'd' => ['a2' => ['b3' => 'item b3']]], $arrayAccessData);
+
+ try {
+ $this->assertArraySubset(['a' => 'bad value'], $array);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ }
+
+ try {
+ $this->assertArraySubset(['d' => ['a2' => ['bad index' => 'item b3']]], $array);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertArraySubsetWithDeepNestedArrays()
+ {
+ $array = [
+ 'path' => [
+ 'to' => [
+ 'the' => [
+ 'cake' => 'is a lie'
+ ]
+ ]
+ ]
+ ];
+
+ $this->assertArraySubset(['path' => []], $array);
+ $this->assertArraySubset(['path' => ['to' => []]], $array);
+ $this->assertArraySubset(['path' => ['to' => ['the' => []]]], $array);
+ $this->assertArraySubset(['path' => ['to' => ['the' => ['cake' => 'is a lie']]]], $array);
+
+ try {
+ $this->assertArraySubset(['path' => ['to' => ['the' => ['cake' => 'is not a lie']]]], $array);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertArraySubsetWithNoStrictCheckAndObjects()
+ {
+ $obj = new \stdClass;
+ $reference = &$obj;
+ $array = ['a' => $obj];
+
+ $this->assertArraySubset(['a' => $reference], $array);
+ $this->assertArraySubset(['a' => new \stdClass], $array);
+ }
+
+ public function testAssertArraySubsetWithStrictCheckAndObjects()
+ {
+ $obj = new \stdClass;
+ $reference = &$obj;
+ $array = ['a' => $obj];
+
+ $this->assertArraySubset(['a' => $reference], $array, true);
+
+ try {
+ $this->assertArraySubset(['a' => new \stdClass], $array, true);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail('Strict recursive array check fail.');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ * @expectedExceptionMessage array or ArrayAccess
+ * @dataProvider assertArraySubsetInvalidArgumentProvider
+ */
+ public function testAssertArraySubsetRaisesExceptionForInvalidArguments($partial, $subject)
+ {
+ $this->assertArraySubset($partial, $subject);
+ }
+
+ /**
+ * @return array
+ */
+ public function assertArraySubsetInvalidArgumentProvider()
+ {
+ return [
+ [false, []],
+ [[], false],
+ ];
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertArrayNotHasKeyThrowsExceptionForInvalidFirstArgument()
+ {
+ $this->assertArrayNotHasKey(null, []);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertArrayNotHasKeyThrowsExceptionForInvalidSecondArgument()
+ {
+ $this->assertArrayNotHasKey(0, null);
+ }
+
+ public function testAssertArrayNotHasIntegerKey()
+ {
+ $this->assertArrayNotHasKey(1, ['foo']);
+
+ try {
+ $this->assertArrayNotHasKey(0, ['foo']);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertArrayHasStringKey()
+ {
+ $this->assertArrayHasKey('foo', ['foo' => 'bar']);
+
+ try {
+ $this->assertArrayHasKey('bar', ['foo' => 'bar']);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertArrayNotHasStringKey()
+ {
+ $this->assertArrayNotHasKey('bar', ['foo' => 'bar']);
+
+ try {
+ $this->assertArrayNotHasKey('foo', ['foo' => 'bar']);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertArrayHasKeyAcceptsArrayObjectValue()
+ {
+ $array = new ArrayObject();
+ $array['foo'] = 'bar';
+ $this->assertArrayHasKey('foo', $array);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_AssertionFailedError
+ */
+ public function testAssertArrayHasKeyProperlyFailsWithArrayObjectValue()
+ {
+ $array = new ArrayObject();
+ $array['bar'] = 'bar';
+ $this->assertArrayHasKey('foo', $array);
+ }
+
+ public function testAssertArrayHasKeyAcceptsArrayAccessValue()
+ {
+ $array = new SampleArrayAccess();
+ $array['foo'] = 'bar';
+ $this->assertArrayHasKey('foo', $array);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_AssertionFailedError
+ */
+ public function testAssertArrayHasKeyProperlyFailsWithArrayAccessValue()
+ {
+ $array = new SampleArrayAccess();
+ $array['bar'] = 'bar';
+ $this->assertArrayHasKey('foo', $array);
+ }
+
+ public function testAssertArrayNotHasKeyAcceptsArrayAccessValue()
+ {
+ $array = new ArrayObject();
+ $array['foo'] = 'bar';
+ $this->assertArrayNotHasKey('bar', $array);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_AssertionFailedError
+ */
+ public function testAssertArrayNotHasKeyPropertlyFailsWithArrayAccessValue()
+ {
+ $array = new ArrayObject();
+ $array['bar'] = 'bar';
+ $this->assertArrayNotHasKey('bar', $array);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertContainsThrowsException()
+ {
+ $this->assertContains(null, null);
+ }
+
+ public function testAssertIteratorContainsObject()
+ {
+ $foo = new stdClass;
+
+ $this->assertContains($foo, new TestIterator([$foo]));
+
+ try {
+ $this->assertContains($foo, new TestIterator([new stdClass]));
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertIteratorContainsString()
+ {
+ $this->assertContains('foo', new TestIterator(['foo']));
+
+ try {
+ $this->assertContains('foo', new TestIterator(['bar']));
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertStringContainsString()
+ {
+ $this->assertContains('foo', 'foobar');
+
+ try {
+ $this->assertContains('foo', 'bar');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertStringContainsStringForUtf8()
+ {
+ $this->assertContains('oryginał', 'oryginał');
+
+ try {
+ $this->assertContains('ORYGINAŁ', 'oryginał');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertStringContainsStringForUtf8WhenIgnoreCase()
+ {
+ $this->assertContains('oryginał', 'oryginał', '', true);
+ $this->assertContains('ORYGINAŁ', 'oryginał', '', true);
+
+ try {
+ $this->assertContains('foo', 'oryginał', '', true);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertNotContainsThrowsException()
+ {
+ $this->assertNotContains(null, null);
+ }
+
+ public function testAssertSplObjectStorageNotContainsObject()
+ {
+ $a = new stdClass;
+ $b = new stdClass;
+ $c = new SplObjectStorage;
+ $c->attach($a);
+
+ $this->assertNotContains($b, $c);
+
+ try {
+ $this->assertNotContains($a, $c);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertArrayNotContainsObject()
+ {
+ $a = new stdClass;
+ $b = new stdClass;
+
+ $this->assertNotContains($a, [$b]);
+
+ try {
+ $this->assertNotContains($a, [$a]);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertArrayNotContainsString()
+ {
+ $this->assertNotContains('foo', ['bar']);
+
+ try {
+ $this->assertNotContains('foo', ['foo']);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertArrayNotContainsNonObject()
+ {
+ $this->assertNotContains('foo', [true], '', false, true, true);
+
+ try {
+ $this->assertNotContains('foo', [true]);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertStringNotContainsString()
+ {
+ $this->assertNotContains('foo', 'bar');
+
+ try {
+ $this->assertNotContains('foo', 'foo');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertStringNotContainsStringForUtf8()
+ {
+ $this->assertNotContains('ORYGINAŁ', 'oryginał');
+
+ try {
+ $this->assertNotContains('oryginał', 'oryginał');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertStringNotContainsStringForUtf8WhenIgnoreCase()
+ {
+ try {
+ $this->assertNotContains('ORYGINAŁ', 'oryginał', '', true);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertContainsOnlyThrowsException()
+ {
+ $this->assertContainsOnly(null, null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertNotContainsOnlyThrowsException()
+ {
+ $this->assertNotContainsOnly(null, null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertContainsOnlyInstancesOfThrowsException()
+ {
+ $this->assertContainsOnlyInstancesOf(null, null);
+ }
+
+ public function testAssertArrayContainsOnlyIntegers()
+ {
+ $this->assertContainsOnly('integer', [1, 2, 3]);
+
+ try {
+ $this->assertContainsOnly('integer', ['1', 2, 3]);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertArrayNotContainsOnlyIntegers()
+ {
+ $this->assertNotContainsOnly('integer', ['1', 2, 3]);
+
+ try {
+ $this->assertNotContainsOnly('integer', [1, 2, 3]);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertArrayContainsOnlyStdClass()
+ {
+ $this->assertContainsOnly('StdClass', [new stdClass]);
+
+ try {
+ $this->assertContainsOnly('StdClass', ['StdClass']);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertArrayNotContainsOnlyStdClass()
+ {
+ $this->assertNotContainsOnly('StdClass', ['StdClass']);
+
+ try {
+ $this->assertNotContainsOnly('StdClass', [new stdClass]);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ protected function sameValues()
+ {
+ $object = new SampleClass(4, 8, 15);
+ // cannot use $filesDirectory, because neither setUp() nor
+ // setUpBeforeClass() are executed before the data providers
+ $file = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'foo.xml';
+ $resource = fopen($file, 'r');
+
+ return [
+ // null
+ [null, null],
+ // strings
+ ['a', 'a'],
+ // integers
+ [0, 0],
+ // floats
+ [2.3, 2.3],
+ [1 / 3, 1 - 2 / 3],
+ [log(0), log(0)],
+ // arrays
+ [[], []],
+ [[0 => 1], [0 => 1]],
+ [[0 => null], [0 => null]],
+ [['a', 'b' => [1, 2]], ['a', 'b' => [1, 2]]],
+ // objects
+ [$object, $object],
+ // resources
+ [$resource, $resource],
+ ];
+ }
+
+ protected function notEqualValues()
+ {
+ // cyclic dependencies
+ $book1 = new Book;
+ $book1->author = new Author('Terry Pratchett');
+ $book1->author->books[] = $book1;
+ $book2 = new Book;
+ $book2->author = new Author('Terry Pratch');
+ $book2->author->books[] = $book2;
+
+ $book3 = new Book;
+ $book3->author = 'Terry Pratchett';
+ $book4 = new stdClass;
+ $book4->author = 'Terry Pratchett';
+
+ $object1 = new SampleClass(4, 8, 15);
+ $object2 = new SampleClass(16, 23, 42);
+ $object3 = new SampleClass(4, 8, 15);
+ $storage1 = new SplObjectStorage;
+ $storage1->attach($object1);
+ $storage2 = new SplObjectStorage;
+ $storage2->attach($object3); // same content, different object
+
+ // cannot use $filesDirectory, because neither setUp() nor
+ // setUpBeforeClass() are executed before the data providers
+ $file = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'foo.xml';
+
+ return [
+ // strings
+ ['a', 'b'],
+ ['a', 'A'],
+ // https://github.com/sebastianbergmann/phpunit/issues/1023
+ ['9E6666666','9E7777777'],
+ // integers
+ [1, 2],
+ [2, 1],
+ // floats
+ [2.3, 4.2],
+ [2.3, 4.2, 0.5],
+ [[2.3], [4.2], 0.5],
+ [[[2.3]], [[4.2]], 0.5],
+ [new Struct(2.3), new Struct(4.2), 0.5],
+ [[new Struct(2.3)], [new Struct(4.2)], 0.5],
+ // NAN
+ [NAN, NAN],
+ // arrays
+ [[], [0 => 1]],
+ [[0 => 1], []],
+ [[0 => null], []],
+ [[0 => 1, 1 => 2], [0 => 1, 1 => 3]],
+ [['a', 'b' => [1, 2]], ['a', 'b' => [2, 1]]],
+ // objects
+ [new SampleClass(4, 8, 15), new SampleClass(16, 23, 42)],
+ [$object1, $object2],
+ [$book1, $book2],
+ [$book3, $book4], // same content, different class
+ // resources
+ [fopen($file, 'r'), fopen($file, 'r')],
+ // SplObjectStorage
+ [$storage1, $storage2],
+ // DOMDocument
+ [
+ PHPUnit_Util_XML::load('<root></root>'),
+ PHPUnit_Util_XML::load('<bar/>'),
+ ],
+ [
+ PHPUnit_Util_XML::load('<foo attr1="bar"/>'),
+ PHPUnit_Util_XML::load('<foo attr1="foobar"/>'),
+ ],
+ [
+ PHPUnit_Util_XML::load('<foo> bar </foo>'),
+ PHPUnit_Util_XML::load('<foo />'),
+ ],
+ [
+ PHPUnit_Util_XML::load('<foo xmlns="urn:myns:bar"/>'),
+ PHPUnit_Util_XML::load('<foo xmlns="urn:notmyns:bar"/>'),
+ ],
+ [
+ PHPUnit_Util_XML::load('<foo> bar </foo>'),
+ PHPUnit_Util_XML::load('<foo> bir </foo>'),
+ ],
+ [
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/New_York')),
+ ],
+ [
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/New_York')),
+ 3500
+ ],
+ [
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 05:13:35', new DateTimeZone('America/New_York')),
+ 3500
+ ],
+ [
+ new DateTime('2013-03-29', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
+ ],
+ [
+ new DateTime('2013-03-29', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
+ 43200
+ ],
+ [
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/Chicago')),
+ ],
+ [
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/Chicago')),
+ 3500
+ ],
+ [
+ new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-30', new DateTimeZone('America/Chicago')),
+ ],
+ [
+ new DateTime('2013-03-29T05:13:35-0600'),
+ new DateTime('2013-03-29T04:13:35-0600'),
+ ],
+ [
+ new DateTime('2013-03-29T05:13:35-0600'),
+ new DateTime('2013-03-29T05:13:35-0500'),
+ ],
+ // Exception
+ //array(new Exception('Exception 1'), new Exception('Exception 2')),
+ // different types
+ [new SampleClass(4, 8, 15), false],
+ [false, new SampleClass(4, 8, 15)],
+ [[0 => 1, 1 => 2], false],
+ [false, [0 => 1, 1 => 2]],
+ [[], new stdClass],
+ [new stdClass, []],
+ // PHP: 0 == 'Foobar' => true!
+ // We want these values to differ
+ [0, 'Foobar'],
+ ['Foobar', 0],
+ [3, acos(8)],
+ [acos(8), 3]
+ ];
+ }
+
+ protected function equalValues()
+ {
+ // cyclic dependencies
+ $book1 = new Book;
+ $book1->author = new Author('Terry Pratchett');
+ $book1->author->books[] = $book1;
+ $book2 = new Book;
+ $book2->author = new Author('Terry Pratchett');
+ $book2->author->books[] = $book2;
+
+ $object1 = new SampleClass(4, 8, 15);
+ $object2 = new SampleClass(4, 8, 15);
+ $storage1 = new SplObjectStorage;
+ $storage1->attach($object1);
+ $storage2 = new SplObjectStorage;
+ $storage2->attach($object1);
+
+ return [
+ // strings
+ ['a', 'A', 0, false, true], // ignore case
+ // arrays
+ [['a' => 1, 'b' => 2], ['b' => 2, 'a' => 1]],
+ [[1], ['1']],
+ [[3, 2, 1], [2, 3, 1], 0, true], // canonicalized comparison
+ // floats
+ [2.3, 2.5, 0.5],
+ [[2.3], [2.5], 0.5],
+ [[[2.3]], [[2.5]], 0.5],
+ [new Struct(2.3), new Struct(2.5), 0.5],
+ [[new Struct(2.3)], [new Struct(2.5)], 0.5],
+ // numeric with delta
+ [1, 2, 1],
+ // objects
+ [$object1, $object2],
+ [$book1, $book2],
+ // SplObjectStorage
+ [$storage1, $storage2],
+ // DOMDocument
+ [
+ PHPUnit_Util_XML::load('<root></root>'),
+ PHPUnit_Util_XML::load('<root/>'),
+ ],
+ [
+ PHPUnit_Util_XML::load('<root attr="bar"></root>'),
+ PHPUnit_Util_XML::load('<root attr="bar"/>'),
+ ],
+ [
+ PHPUnit_Util_XML::load('<root><foo attr="bar"></foo></root>'),
+ PHPUnit_Util_XML::load('<root><foo attr="bar"/></root>'),
+ ],
+ [
+ PHPUnit_Util_XML::load("<root>\n <child/>\n</root>"),
+ PHPUnit_Util_XML::load('<root><child/></root>'),
+ ],
+ [
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ ],
+ [
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 04:13:25', new DateTimeZone('America/New_York')),
+ 10
+ ],
+ [
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 04:14:40', new DateTimeZone('America/New_York')),
+ 65
+ ],
+ [
+ new DateTime('2013-03-29', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29', new DateTimeZone('America/New_York')),
+ ],
+ [
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/Chicago')),
+ ],
+ [
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 03:13:49', new DateTimeZone('America/Chicago')),
+ 15
+ ],
+ [
+ new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 23:00:00', new DateTimeZone('America/Chicago')),
+ ],
+ [
+ new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 23:01:30', new DateTimeZone('America/Chicago')),
+ 100
+ ],
+ [
+ new DateTime('@1364616000'),
+ new DateTime('2013-03-29 23:00:00', new DateTimeZone('America/Chicago')),
+ ],
+ [
+ new DateTime('2013-03-29T05:13:35-0500'),
+ new DateTime('2013-03-29T04:13:35-0600'),
+ ],
+ // Exception
+ //array(new Exception('Exception 1'), new Exception('Exception 1')),
+ // mixed types
+ [0, '0'],
+ ['0', 0],
+ [2.3, '2.3'],
+ ['2.3', 2.3],
+ [(string) (1 / 3), 1 - 2 / 3],
+ [1 / 3, (string) (1 - 2 / 3)],
+ ['string representation', new ClassWithToString],
+ [new ClassWithToString, 'string representation'],
+ ];
+ }
+
+ public function equalProvider()
+ {
+ // same |= equal
+ return array_merge($this->equalValues(), $this->sameValues());
+ }
+
+ public function notEqualProvider()
+ {
+ return $this->notEqualValues();
+ }
+
+ public function sameProvider()
+ {
+ return $this->sameValues();
+ }
+
+ public function notSameProvider()
+ {
+ // not equal |= not same
+ // equal, ¬same |= not same
+ return array_merge($this->notEqualValues(), $this->equalValues());
+ }
+
+ /**
+ * @dataProvider equalProvider
+ */
+ public function testAssertEqualsSucceeds($a, $b, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
+ {
+ $this->assertEquals($a, $b, '', $delta, 10, $canonicalize, $ignoreCase);
+ }
+
+ /**
+ * @dataProvider notEqualProvider
+ */
+ public function testAssertEqualsFails($a, $b, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
+ {
+ try {
+ $this->assertEquals($a, $b, '', $delta, 10, $canonicalize, $ignoreCase);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @dataProvider notEqualProvider
+ */
+ public function testAssertNotEqualsSucceeds($a, $b, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
+ {
+ $this->assertNotEquals($a, $b, '', $delta, 10, $canonicalize, $ignoreCase);
+ }
+
+ /**
+ * @dataProvider equalProvider
+ */
+ public function testAssertNotEqualsFails($a, $b, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
+ {
+ try {
+ $this->assertNotEquals($a, $b, '', $delta, 10, $canonicalize, $ignoreCase);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @dataProvider sameProvider
+ */
+ public function testAssertSameSucceeds($a, $b)
+ {
+ $this->assertSame($a, $b);
+ }
+
+ /**
+ * @dataProvider notSameProvider
+ */
+ public function testAssertSameFails($a, $b)
+ {
+ try {
+ $this->assertSame($a, $b);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @dataProvider notSameProvider
+ */
+ public function testAssertNotSameSucceeds($a, $b)
+ {
+ $this->assertNotSame($a, $b);
+ }
+
+ /**
+ * @dataProvider sameProvider
+ */
+ public function testAssertNotSameFails($a, $b)
+ {
+ try {
+ $this->assertNotSame($a, $b);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertXmlFileEqualsXmlFile()
+ {
+ $this->assertXmlFileEqualsXmlFile(
+ $this->filesDirectory . 'foo.xml',
+ $this->filesDirectory . 'foo.xml'
+ );
+
+ try {
+ $this->assertXmlFileEqualsXmlFile(
+ $this->filesDirectory . 'foo.xml',
+ $this->filesDirectory . 'bar.xml'
+ );
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertXmlFileNotEqualsXmlFile()
+ {
+ $this->assertXmlFileNotEqualsXmlFile(
+ $this->filesDirectory . 'foo.xml',
+ $this->filesDirectory . 'bar.xml'
+ );
+
+ try {
+ $this->assertXmlFileNotEqualsXmlFile(
+ $this->filesDirectory . 'foo.xml',
+ $this->filesDirectory . 'foo.xml'
+ );
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertXmlStringEqualsXmlFile()
+ {
+ $this->assertXmlStringEqualsXmlFile(
+ $this->filesDirectory . 'foo.xml',
+ file_get_contents($this->filesDirectory . 'foo.xml')
+ );
+
+ try {
+ $this->assertXmlStringEqualsXmlFile(
+ $this->filesDirectory . 'foo.xml',
+ file_get_contents($this->filesDirectory . 'bar.xml')
+ );
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testXmlStringNotEqualsXmlFile()
+ {
+ $this->assertXmlStringNotEqualsXmlFile(
+ $this->filesDirectory . 'foo.xml',
+ file_get_contents($this->filesDirectory . 'bar.xml')
+ );
+
+ try {
+ $this->assertXmlStringNotEqualsXmlFile(
+ $this->filesDirectory . 'foo.xml',
+ file_get_contents($this->filesDirectory . 'foo.xml')
+ );
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertXmlStringEqualsXmlString()
+ {
+ $this->assertXmlStringEqualsXmlString('<root/>', '<root/>');
+
+ try {
+ $this->assertXmlStringEqualsXmlString('<foo/>', '<bar/>');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ * @ticket 1860
+ */
+ public function testAssertXmlStringEqualsXmlString2()
+ {
+ $this->assertXmlStringEqualsXmlString('<a></b>', '<c></d>');
+ }
+
+ /**
+ * @ticket 1860
+ */
+ public function testAssertXmlStringEqualsXmlString3()
+ {
+ $expected = <<<XML
+<?xml version="1.0"?>
+<root>
+ <node />
+</root>
+XML;
+
+ $actual = <<<XML
+<?xml version="1.0"?>
+<root>
+<node />
+</root>
+XML;
+
+ $this->assertXmlStringEqualsXmlString($expected, $actual);
+ }
+
+ public function testAssertXmlStringNotEqualsXmlString()
+ {
+ $this->assertXmlStringNotEqualsXmlString('<foo/>', '<bar/>');
+
+ try {
+ $this->assertXmlStringNotEqualsXmlString('<root/>', '<root/>');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testXMLStructureIsSame()
+ {
+ $expected = new DOMDocument;
+ $expected->load($this->filesDirectory . 'structureExpected.xml');
+
+ $actual = new DOMDocument;
+ $actual->load($this->filesDirectory . 'structureExpected.xml');
+
+ $this->assertEqualXMLStructure(
+ $expected->firstChild, $actual->firstChild, true
+ );
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_ExpectationFailedException
+ */
+ public function testXMLStructureWrongNumberOfAttributes()
+ {
+ $expected = new DOMDocument;
+ $expected->load($this->filesDirectory . 'structureExpected.xml');
+
+ $actual = new DOMDocument;
+ $actual->load($this->filesDirectory . 'structureWrongNumberOfAttributes.xml');
+
+ $this->assertEqualXMLStructure(
+ $expected->firstChild, $actual->firstChild, true
+ );
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_ExpectationFailedException
+ */
+ public function testXMLStructureWrongNumberOfNodes()
+ {
+ $expected = new DOMDocument;
+ $expected->load($this->filesDirectory . 'structureExpected.xml');
+
+ $actual = new DOMDocument;
+ $actual->load($this->filesDirectory . 'structureWrongNumberOfNodes.xml');
+
+ $this->assertEqualXMLStructure(
+ $expected->firstChild, $actual->firstChild, true
+ );
+ }
+
+ public function testXMLStructureIsSameButDataIsNot()
+ {
+ $expected = new DOMDocument;
+ $expected->load($this->filesDirectory . 'structureExpected.xml');
+
+ $actual = new DOMDocument;
+ $actual->load($this->filesDirectory . 'structureIsSameButDataIsNot.xml');
+
+ $this->assertEqualXMLStructure(
+ $expected->firstChild, $actual->firstChild, true
+ );
+ }
+
+ public function testXMLStructureAttributesAreSameButValuesAreNot()
+ {
+ $expected = new DOMDocument;
+ $expected->load($this->filesDirectory . 'structureExpected.xml');
+
+ $actual = new DOMDocument;
+ $actual->load($this->filesDirectory . 'structureAttributesAreSameButValuesAreNot.xml');
+
+ $this->assertEqualXMLStructure(
+ $expected->firstChild, $actual->firstChild, true
+ );
+ }
+
+ public function testXMLStructureIgnoreTextNodes()
+ {
+ $expected = new DOMDocument;
+ $expected->load($this->filesDirectory . 'structureExpected.xml');
+
+ $actual = new DOMDocument;
+ $actual->load($this->filesDirectory . 'structureIgnoreTextNodes.xml');
+
+ $this->assertEqualXMLStructure(
+ $expected->firstChild, $actual->firstChild, true
+ );
+ }
+
+ public function testAssertStringEqualsNumeric()
+ {
+ $this->assertEquals('0', 0);
+
+ try {
+ $this->assertEquals('0', 1);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertStringEqualsNumeric2()
+ {
+ $this->assertNotEquals('A', 0);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertIsReadableThrowsException()
+ {
+ $this->assertIsReadable(null);
+ }
+
+ public function testAssertIsReadable()
+ {
+ $this->assertIsReadable(__FILE__);
+
+ try {
+ $this->assertIsReadable(__DIR__ . DIRECTORY_SEPARATOR . 'NotExisting');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertNotIsReadableThrowsException()
+ {
+ $this->assertNotIsReadable(null);
+ }
+
+ public function testAssertNotIsReadable()
+ {
+ try {
+ $this->assertNotIsReadable(__FILE__);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertIsWritableThrowsException()
+ {
+ $this->assertIsWritable(null);
+ }
+
+ public function testAssertIsWritable()
+ {
+ $this->assertIsWritable(__FILE__);
+
+ try {
+ $this->assertIsWritable(__DIR__ . DIRECTORY_SEPARATOR . 'NotExisting');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertNotIsWritableThrowsException()
+ {
+ $this->assertNotIsWritable(null);
+ }
+
+ public function testAssertNotIsWritable()
+ {
+ try {
+ $this->assertNotIsWritable(__FILE__);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertDirectoryExistsThrowsException()
+ {
+ $this->assertDirectoryExists(null);
+ }
+
+ public function testAssertDirectoryExists()
+ {
+ $this->assertDirectoryExists(__DIR__);
+
+ try {
+ $this->assertDirectoryExists(__DIR__ . DIRECTORY_SEPARATOR . 'NotExisting');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertDirectoryNotExistsThrowsException()
+ {
+ $this->assertDirectoryNotExists(null);
+ }
+
+ public function testAssertDirectoryNotExists()
+ {
+ $this->assertDirectoryNotExists(__DIR__ . DIRECTORY_SEPARATOR . 'NotExisting');
+
+ try {
+ $this->assertDirectoryNotExists(__DIR__);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertDirectoryIsReadableThrowsException()
+ {
+ $this->assertDirectoryIsReadable(null);
+ }
+
+ public function testAssertDirectoryIsReadable()
+ {
+ $this->assertDirectoryIsReadable(__DIR__);
+
+ try {
+ $this->assertDirectoryIsReadable(__DIR__ . DIRECTORY_SEPARATOR . 'NotExisting');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertDirectoryNotIsReadableThrowsException()
+ {
+ $this->assertDirectoryNotIsReadable(null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertDirectoryIsWritableThrowsException()
+ {
+ $this->assertDirectoryIsWritable(null);
+ }
+
+ public function testAssertDirectoryIsWritable()
+ {
+ $this->assertDirectoryIsWritable(__DIR__);
+
+ try {
+ $this->assertDirectoryIsWritable(__DIR__ . DIRECTORY_SEPARATOR . 'NotExisting');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertDirectoryNotIsWritableThrowsException()
+ {
+ $this->assertDirectoryNotIsWritable(null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertFileExistsThrowsException()
+ {
+ $this->assertFileExists(null);
+ }
+
+ public function testAssertFileExists()
+ {
+ $this->assertFileExists(__FILE__);
+
+ try {
+ $this->assertFileExists(__DIR__ . DIRECTORY_SEPARATOR . 'NotExisting');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertFileNotExistsThrowsException()
+ {
+ $this->assertFileNotExists(null);
+ }
+
+ public function testAssertFileNotExists()
+ {
+ $this->assertFileNotExists(__DIR__ . DIRECTORY_SEPARATOR . 'NotExisting');
+
+ try {
+ $this->assertFileNotExists(__FILE__);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertFileIsReadableThrowsException()
+ {
+ $this->assertFileIsReadable(null);
+ }
+
+ public function testAssertFileIsReadable()
+ {
+ $this->assertFileIsReadable(__FILE__);
+
+ try {
+ $this->assertFileIsReadable(__DIR__ . DIRECTORY_SEPARATOR . 'NotExisting');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertFileNotIsReadableThrowsException()
+ {
+ $this->assertFileNotIsReadable(null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertFileIsWritableThrowsException()
+ {
+ $this->assertFileIsWritable(null);
+ }
+
+ public function testAssertFileIsWritable()
+ {
+ $this->assertFileIsWritable(__FILE__);
+
+ try {
+ $this->assertFileIsWritable(__DIR__ . DIRECTORY_SEPARATOR . 'NotExisting');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertFileNotIsWritableThrowsException()
+ {
+ $this->assertFileNotIsWritable(null);
+ }
+
+ public function testAssertObjectHasAttribute()
+ {
+ $o = new Author('Terry Pratchett');
+
+ $this->assertObjectHasAttribute('name', $o);
+
+ try {
+ $this->assertObjectHasAttribute('foo', $o);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertObjectNotHasAttribute()
+ {
+ $o = new Author('Terry Pratchett');
+
+ $this->assertObjectNotHasAttribute('foo', $o);
+
+ try {
+ $this->assertObjectNotHasAttribute('name', $o);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertFinite()
+ {
+ $this->assertFinite(1);
+
+ try {
+ $this->assertFinite(INF);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertInfinite()
+ {
+ $this->assertInfinite(INF);
+
+ try {
+ $this->assertInfinite(1);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertNan()
+ {
+ $this->assertNan(NAN);
+
+ try {
+ $this->assertNan(1);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertNull()
+ {
+ $this->assertNull(null);
+
+ try {
+ $this->assertNull(new stdClass);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertNotNull()
+ {
+ $this->assertNotNull(new stdClass);
+
+ try {
+ $this->assertNotNull(null);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertTrue()
+ {
+ $this->assertTrue(true);
+
+ try {
+ $this->assertTrue(false);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertNotTrue()
+ {
+ $this->assertNotTrue(false);
+ $this->assertNotTrue(1);
+ $this->assertNotTrue('true');
+
+ try {
+ $this->assertNotTrue(true);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertFalse()
+ {
+ $this->assertFalse(false);
+
+ try {
+ $this->assertFalse(true);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertNotFalse()
+ {
+ $this->assertNotFalse(true);
+ $this->assertNotFalse(0);
+ $this->assertNotFalse('');
+
+ try {
+ $this->assertNotFalse(false);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertRegExpThrowsException()
+ {
+ $this->assertRegExp(null, null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertRegExpThrowsException2()
+ {
+ $this->assertRegExp('', null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertNotRegExpThrowsException()
+ {
+ $this->assertNotRegExp(null, null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertNotRegExpThrowsException2()
+ {
+ $this->assertNotRegExp('', null);
+ }
+
+ public function testAssertRegExp()
+ {
+ $this->assertRegExp('/foo/', 'foobar');
+
+ try {
+ $this->assertRegExp('/foo/', 'bar');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertNotRegExp()
+ {
+ $this->assertNotRegExp('/foo/', 'bar');
+
+ try {
+ $this->assertNotRegExp('/foo/', 'foobar');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertSame()
+ {
+ $o = new stdClass;
+
+ $this->assertSame($o, $o);
+
+ try {
+ $this->assertSame(
+ new stdClass,
+ new stdClass
+ );
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertSame2()
+ {
+ $this->assertSame(true, true);
+ $this->assertSame(false, false);
+
+ try {
+ $this->assertSame(true, false);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertNotSame()
+ {
+ $this->assertNotSame(
+ new stdClass,
+ null
+ );
+
+ $this->assertNotSame(
+ null,
+ new stdClass
+ );
+
+ $this->assertNotSame(
+ new stdClass,
+ new stdClass
+ );
+
+ $o = new stdClass;
+
+ try {
+ $this->assertNotSame($o, $o);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertNotSame2()
+ {
+ $this->assertNotSame(true, false);
+ $this->assertNotSame(false, true);
+
+ try {
+ $this->assertNotSame(true, true);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertNotSameFailsNull()
+ {
+ try {
+ $this->assertNotSame(null, null);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testGreaterThan()
+ {
+ $this->assertGreaterThan(1, 2);
+
+ try {
+ $this->assertGreaterThan(2, 1);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAttributeGreaterThan()
+ {
+ $this->assertAttributeGreaterThan(
+ 1, 'bar', new ClassWithNonPublicAttributes
+ );
+
+ try {
+ $this->assertAttributeGreaterThan(
+ 1, 'foo', new ClassWithNonPublicAttributes
+ );
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testGreaterThanOrEqual()
+ {
+ $this->assertGreaterThanOrEqual(1, 2);
+
+ try {
+ $this->assertGreaterThanOrEqual(2, 1);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAttributeGreaterThanOrEqual()
+ {
+ $this->assertAttributeGreaterThanOrEqual(
+ 1, 'bar', new ClassWithNonPublicAttributes
+ );
+
+ try {
+ $this->assertAttributeGreaterThanOrEqual(
+ 2, 'foo', new ClassWithNonPublicAttributes
+ );
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testLessThan()
+ {
+ $this->assertLessThan(2, 1);
+
+ try {
+ $this->assertLessThan(1, 2);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAttributeLessThan()
+ {
+ $this->assertAttributeLessThan(
+ 2, 'foo', new ClassWithNonPublicAttributes
+ );
+
+ try {
+ $this->assertAttributeLessThan(
+ 1, 'bar', new ClassWithNonPublicAttributes
+ );
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testLessThanOrEqual()
+ {
+ $this->assertLessThanOrEqual(2, 1);
+
+ try {
+ $this->assertLessThanOrEqual(1, 2);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAttributeLessThanOrEqual()
+ {
+ $this->assertAttributeLessThanOrEqual(
+ 2, 'foo', new ClassWithNonPublicAttributes
+ );
+
+ try {
+ $this->assertAttributeLessThanOrEqual(
+ 1, 'bar', new ClassWithNonPublicAttributes
+ );
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testReadAttribute()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertEquals('foo', $this->readAttribute($obj, 'publicAttribute'));
+ $this->assertEquals('bar', $this->readAttribute($obj, 'protectedAttribute'));
+ $this->assertEquals('baz', $this->readAttribute($obj, 'privateAttribute'));
+ $this->assertEquals('bar', $this->readAttribute($obj, 'protectedParentAttribute'));
+ //$this->assertEquals('bar', $this->readAttribute($obj, 'privateParentAttribute'));
+ }
+
+ public function testReadAttribute2()
+ {
+ $this->assertEquals('foo', $this->readAttribute('ClassWithNonPublicAttributes', 'publicStaticAttribute'));
+ $this->assertEquals('bar', $this->readAttribute('ClassWithNonPublicAttributes', 'protectedStaticAttribute'));
+ $this->assertEquals('baz', $this->readAttribute('ClassWithNonPublicAttributes', 'privateStaticAttribute'));
+ $this->assertEquals('foo', $this->readAttribute('ClassWithNonPublicAttributes', 'protectedStaticParentAttribute'));
+ $this->assertEquals('foo', $this->readAttribute('ClassWithNonPublicAttributes', 'privateStaticParentAttribute'));
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testReadAttribute3()
+ {
+ $this->readAttribute('StdClass', null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testReadAttribute4()
+ {
+ $this->readAttribute('NotExistingClass', 'foo');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testReadAttribute5()
+ {
+ $this->readAttribute(null, 'foo');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testReadAttributeIfAttributeNameIsNotValid()
+ {
+ $this->readAttribute('StdClass', '2');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testGetStaticAttributeRaisesExceptionForInvalidFirstArgument()
+ {
+ $this->getStaticAttribute(null, 'foo');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testGetStaticAttributeRaisesExceptionForInvalidFirstArgument2()
+ {
+ $this->getStaticAttribute('NotExistingClass', 'foo');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testGetStaticAttributeRaisesExceptionForInvalidSecondArgument()
+ {
+ $this->getStaticAttribute('stdClass', null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testGetStaticAttributeRaisesExceptionForInvalidSecondArgument2()
+ {
+ $this->getStaticAttribute('stdClass', '0');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testGetStaticAttributeRaisesExceptionForInvalidSecondArgument3()
+ {
+ $this->getStaticAttribute('stdClass', 'foo');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testGetObjectAttributeRaisesExceptionForInvalidFirstArgument()
+ {
+ $this->getObjectAttribute(null, 'foo');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testGetObjectAttributeRaisesExceptionForInvalidSecondArgument()
+ {
+ $this->getObjectAttribute(new stdClass, null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testGetObjectAttributeRaisesExceptionForInvalidSecondArgument2()
+ {
+ $this->getObjectAttribute(new stdClass, '0');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testGetObjectAttributeRaisesExceptionForInvalidSecondArgument3()
+ {
+ $this->getObjectAttribute(new stdClass, 'foo');
+ }
+
+ public function testGetObjectAttributeWorksForInheritedAttributes()
+ {
+ $this->assertEquals(
+ 'bar',
+ $this->getObjectAttribute(new ClassWithNonPublicAttributes, 'privateParentAttribute')
+ );
+ }
+
+ public function testAssertPublicAttributeContains()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertAttributeContains('foo', 'publicArray', $obj);
+
+ try {
+ $this->assertAttributeContains('bar', 'publicArray', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertPublicAttributeContainsOnly()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertAttributeContainsOnly('string', 'publicArray', $obj);
+
+ try {
+ $this->assertAttributeContainsOnly('integer', 'publicArray', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertPublicAttributeNotContains()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertAttributeNotContains('bar', 'publicArray', $obj);
+
+ try {
+ $this->assertAttributeNotContains('foo', 'publicArray', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertPublicAttributeNotContainsOnly()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertAttributeNotContainsOnly('integer', 'publicArray', $obj);
+
+ try {
+ $this->assertAttributeNotContainsOnly('string', 'publicArray', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertProtectedAttributeContains()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertAttributeContains('bar', 'protectedArray', $obj);
+
+ try {
+ $this->assertAttributeContains('foo', 'protectedArray', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertProtectedAttributeNotContains()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertAttributeNotContains('foo', 'protectedArray', $obj);
+
+ try {
+ $this->assertAttributeNotContains('bar', 'protectedArray', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertPrivateAttributeContains()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertAttributeContains('baz', 'privateArray', $obj);
+
+ try {
+ $this->assertAttributeContains('foo', 'privateArray', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertPrivateAttributeNotContains()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertAttributeNotContains('foo', 'privateArray', $obj);
+
+ try {
+ $this->assertAttributeNotContains('baz', 'privateArray', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertAttributeContainsNonObject()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertAttributeContains(true, 'privateArray', $obj);
+
+ try {
+ $this->assertAttributeContains(true, 'privateArray', $obj, '', false, true, true);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertAttributeNotContainsNonObject()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertAttributeNotContains(true, 'privateArray', $obj, '', false, true, true);
+
+ try {
+ $this->assertAttributeNotContains(true, 'privateArray', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertPublicAttributeEquals()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertAttributeEquals('foo', 'publicAttribute', $obj);
+
+ try {
+ $this->assertAttributeEquals('bar', 'publicAttribute', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertPublicAttributeNotEquals()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertAttributeNotEquals('bar', 'publicAttribute', $obj);
+
+ try {
+ $this->assertAttributeNotEquals('foo', 'publicAttribute', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertPublicAttributeSame()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertAttributeSame('foo', 'publicAttribute', $obj);
+
+ try {
+ $this->assertAttributeSame('bar', 'publicAttribute', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertPublicAttributeNotSame()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertAttributeNotSame('bar', 'publicAttribute', $obj);
+
+ try {
+ $this->assertAttributeNotSame('foo', 'publicAttribute', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertProtectedAttributeEquals()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertAttributeEquals('bar', 'protectedAttribute', $obj);
+
+ try {
+ $this->assertAttributeEquals('foo', 'protectedAttribute', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertProtectedAttributeNotEquals()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertAttributeNotEquals('foo', 'protectedAttribute', $obj);
+
+ try {
+ $this->assertAttributeNotEquals('bar', 'protectedAttribute', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertPrivateAttributeEquals()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertAttributeEquals('baz', 'privateAttribute', $obj);
+
+ try {
+ $this->assertAttributeEquals('foo', 'privateAttribute', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertPrivateAttributeNotEquals()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertAttributeNotEquals('foo', 'privateAttribute', $obj);
+
+ try {
+ $this->assertAttributeNotEquals('baz', 'privateAttribute', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertPublicStaticAttributeEquals()
+ {
+ $this->assertAttributeEquals('foo', 'publicStaticAttribute', 'ClassWithNonPublicAttributes');
+
+ try {
+ $this->assertAttributeEquals('bar', 'publicStaticAttribute', 'ClassWithNonPublicAttributes');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertPublicStaticAttributeNotEquals()
+ {
+ $this->assertAttributeNotEquals('bar', 'publicStaticAttribute', 'ClassWithNonPublicAttributes');
+
+ try {
+ $this->assertAttributeNotEquals('foo', 'publicStaticAttribute', 'ClassWithNonPublicAttributes');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertProtectedStaticAttributeEquals()
+ {
+ $this->assertAttributeEquals('bar', 'protectedStaticAttribute', 'ClassWithNonPublicAttributes');
+
+ try {
+ $this->assertAttributeEquals('foo', 'protectedStaticAttribute', 'ClassWithNonPublicAttributes');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertProtectedStaticAttributeNotEquals()
+ {
+ $this->assertAttributeNotEquals('foo', 'protectedStaticAttribute', 'ClassWithNonPublicAttributes');
+
+ try {
+ $this->assertAttributeNotEquals('bar', 'protectedStaticAttribute', 'ClassWithNonPublicAttributes');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertPrivateStaticAttributeEquals()
+ {
+ $this->assertAttributeEquals('baz', 'privateStaticAttribute', 'ClassWithNonPublicAttributes');
+
+ try {
+ $this->assertAttributeEquals('foo', 'privateStaticAttribute', 'ClassWithNonPublicAttributes');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertPrivateStaticAttributeNotEquals()
+ {
+ $this->assertAttributeNotEquals('foo', 'privateStaticAttribute', 'ClassWithNonPublicAttributes');
+
+ try {
+ $this->assertAttributeNotEquals('baz', 'privateStaticAttribute', 'ClassWithNonPublicAttributes');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertClassHasAttributeThrowsException()
+ {
+ $this->assertClassHasAttribute(null, null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertClassHasAttributeThrowsException2()
+ {
+ $this->assertClassHasAttribute('foo', null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertClassHasAttributeThrowsExceptionIfAttributeNameIsNotValid()
+ {
+ $this->assertClassHasAttribute('1', 'ClassWithNonPublicAttributes');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertClassNotHasAttributeThrowsException()
+ {
+ $this->assertClassNotHasAttribute(null, null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertClassNotHasAttributeThrowsException2()
+ {
+ $this->assertClassNotHasAttribute('foo', null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertClassNotHasAttributeThrowsExceptionIfAttributeNameIsNotValid()
+ {
+ $this->assertClassNotHasAttribute('1', 'ClassWithNonPublicAttributes');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertClassHasStaticAttributeThrowsException()
+ {
+ $this->assertClassHasStaticAttribute(null, null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertClassHasStaticAttributeThrowsException2()
+ {
+ $this->assertClassHasStaticAttribute('foo', null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertClassHasStaticAttributeThrowsExceptionIfAttributeNameIsNotValid()
+ {
+ $this->assertClassHasStaticAttribute('1', 'ClassWithNonPublicAttributes');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertClassNotHasStaticAttributeThrowsException()
+ {
+ $this->assertClassNotHasStaticAttribute(null, null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertClassNotHasStaticAttributeThrowsException2()
+ {
+ $this->assertClassNotHasStaticAttribute('foo', null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertClassNotHasStaticAttributeThrowsExceptionIfAttributeNameIsNotValid()
+ {
+ $this->assertClassNotHasStaticAttribute('1', 'ClassWithNonPublicAttributes');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertObjectHasAttributeThrowsException()
+ {
+ $this->assertObjectHasAttribute(null, null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertObjectHasAttributeThrowsException2()
+ {
+ $this->assertObjectHasAttribute('foo', null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertObjectHasAttributeThrowsExceptionIfAttributeNameIsNotValid()
+ {
+ $this->assertObjectHasAttribute('1', 'ClassWithNonPublicAttributes');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertObjectNotHasAttributeThrowsException()
+ {
+ $this->assertObjectNotHasAttribute(null, null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertObjectNotHasAttributeThrowsException2()
+ {
+ $this->assertObjectNotHasAttribute('foo', null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertObjectNotHasAttributeThrowsExceptionIfAttributeNameIsNotValid()
+ {
+ $this->assertObjectNotHasAttribute('1', 'ClassWithNonPublicAttributes');
+ }
+
+ public function testClassHasPublicAttribute()
+ {
+ $this->assertClassHasAttribute('publicAttribute', 'ClassWithNonPublicAttributes');
+
+ try {
+ $this->assertClassHasAttribute('attribute', 'ClassWithNonPublicAttributes');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testClassNotHasPublicAttribute()
+ {
+ $this->assertClassNotHasAttribute('attribute', 'ClassWithNonPublicAttributes');
+
+ try {
+ $this->assertClassNotHasAttribute('publicAttribute', 'ClassWithNonPublicAttributes');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testClassHasPublicStaticAttribute()
+ {
+ $this->assertClassHasStaticAttribute('publicStaticAttribute', 'ClassWithNonPublicAttributes');
+
+ try {
+ $this->assertClassHasStaticAttribute('attribute', 'ClassWithNonPublicAttributes');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testClassNotHasPublicStaticAttribute()
+ {
+ $this->assertClassNotHasStaticAttribute('attribute', 'ClassWithNonPublicAttributes');
+
+ try {
+ $this->assertClassNotHasStaticAttribute('publicStaticAttribute', 'ClassWithNonPublicAttributes');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testObjectHasPublicAttribute()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertObjectHasAttribute('publicAttribute', $obj);
+
+ try {
+ $this->assertObjectHasAttribute('attribute', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testObjectNotHasPublicAttribute()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertObjectNotHasAttribute('attribute', $obj);
+
+ try {
+ $this->assertObjectNotHasAttribute('publicAttribute', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testObjectHasOnTheFlyAttribute()
+ {
+ $obj = new stdClass;
+ $obj->foo = 'bar';
+
+ $this->assertObjectHasAttribute('foo', $obj);
+
+ try {
+ $this->assertObjectHasAttribute('bar', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testObjectNotHasOnTheFlyAttribute()
+ {
+ $obj = new stdClass;
+ $obj->foo = 'bar';
+
+ $this->assertObjectNotHasAttribute('bar', $obj);
+
+ try {
+ $this->assertObjectNotHasAttribute('foo', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testObjectHasProtectedAttribute()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertObjectHasAttribute('protectedAttribute', $obj);
+
+ try {
+ $this->assertObjectHasAttribute('attribute', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testObjectNotHasProtectedAttribute()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertObjectNotHasAttribute('attribute', $obj);
+
+ try {
+ $this->assertObjectNotHasAttribute('protectedAttribute', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testObjectHasPrivateAttribute()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertObjectHasAttribute('privateAttribute', $obj);
+
+ try {
+ $this->assertObjectHasAttribute('attribute', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testObjectNotHasPrivateAttribute()
+ {
+ $obj = new ClassWithNonPublicAttributes;
+
+ $this->assertObjectNotHasAttribute('attribute', $obj);
+
+ try {
+ $this->assertObjectNotHasAttribute('privateAttribute', $obj);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertThatAttributeEquals()
+ {
+ $this->assertThat(
+ new ClassWithNonPublicAttributes,
+ $this->attribute(
+ $this->equalTo('foo'),
+ 'publicAttribute'
+ )
+ );
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_AssertionFailedError
+ */
+ public function testAssertThatAttributeEquals2()
+ {
+ $this->assertThat(
+ new ClassWithNonPublicAttributes,
+ $this->attribute(
+ $this->equalTo('bar'),
+ 'publicAttribute'
+ )
+ );
+ }
+
+ public function testAssertThatAttributeEqualTo()
+ {
+ $this->assertThat(
+ new ClassWithNonPublicAttributes,
+ $this->attributeEqualTo('publicAttribute', 'foo')
+ );
+ }
+
+ public function testAssertThatAnything()
+ {
+ $this->assertThat('anything', $this->anything());
+ }
+
+ public function testAssertThatIsTrue()
+ {
+ $this->assertThat(true, $this->isTrue());
+ }
+
+ public function testAssertThatIsFalse()
+ {
+ $this->assertThat(false, $this->isFalse());
+ }
+
+ public function testAssertThatIsJson()
+ {
+ $this->assertThat('{}', $this->isJson());
+ }
+
+ public function testAssertThatAnythingAndAnything()
+ {
+ $this->assertThat(
+ 'anything',
+ $this->logicalAnd(
+ $this->anything(), $this->anything()
+ )
+ );
+ }
+
+ public function testAssertThatAnythingOrAnything()
+ {
+ $this->assertThat(
+ 'anything',
+ $this->logicalOr(
+ $this->anything(), $this->anything()
+ )
+ );
+ }
+
+ public function testAssertThatAnythingXorNotAnything()
+ {
+ $this->assertThat(
+ 'anything',
+ $this->logicalXor(
+ $this->anything(),
+ $this->logicalNot($this->anything())
+ )
+ );
+ }
+
+ public function testAssertThatContains()
+ {
+ $this->assertThat(['foo'], $this->contains('foo'));
+ }
+
+ public function testAssertThatStringContains()
+ {
+ $this->assertThat('barfoobar', $this->stringContains('foo'));
+ }
+
+ public function testAssertThatContainsOnly()
+ {
+ $this->assertThat(['foo'], $this->containsOnly('string'));
+ }
+
+ public function testAssertThatContainsOnlyInstancesOf()
+ {
+ $this->assertThat([new Book], $this->containsOnlyInstancesOf('Book'));
+ }
+
+ public function testAssertThatArrayHasKey()
+ {
+ $this->assertThat(['foo' => 'bar'], $this->arrayHasKey('foo'));
+ }
+
+ public function testAssertThatClassHasAttribute()
+ {
+ $this->assertThat(
+ new ClassWithNonPublicAttributes,
+ $this->classHasAttribute('publicAttribute')
+ );
+ }
+
+ public function testAssertThatClassHasStaticAttribute()
+ {
+ $this->assertThat(
+ new ClassWithNonPublicAttributes,
+ $this->classHasStaticAttribute('publicStaticAttribute')
+ );
+ }
+
+ public function testAssertThatObjectHasAttribute()
+ {
+ $this->assertThat(
+ new ClassWithNonPublicAttributes,
+ $this->objectHasAttribute('publicAttribute')
+ );
+ }
+
+ public function testAssertThatEqualTo()
+ {
+ $this->assertThat('foo', $this->equalTo('foo'));
+ }
+
+ public function testAssertThatIdenticalTo()
+ {
+ $value = new stdClass;
+ $constraint = $this->identicalTo($value);
+
+ $this->assertThat($value, $constraint);
+ }
+
+ public function testAssertThatIsInstanceOf()
+ {
+ $this->assertThat(new stdClass, $this->isInstanceOf('StdClass'));
+ }
+
+ public function testAssertThatIsType()
+ {
+ $this->assertThat('string', $this->isType('string'));
+ }
+
+ public function testAssertThatIsEmpty()
+ {
+ $this->assertThat([], $this->isEmpty());
+ }
+
+ public function testAssertThatFileExists()
+ {
+ $this->assertThat(__FILE__, $this->fileExists());
+ }
+
+ public function testAssertThatGreaterThan()
+ {
+ $this->assertThat(2, $this->greaterThan(1));
+ }
+
+ public function testAssertThatGreaterThanOrEqual()
+ {
+ $this->assertThat(2, $this->greaterThanOrEqual(1));
+ }
+
+ public function testAssertThatLessThan()
+ {
+ $this->assertThat(1, $this->lessThan(2));
+ }
+
+ public function testAssertThatLessThanOrEqual()
+ {
+ $this->assertThat(1, $this->lessThanOrEqual(2));
+ }
+
+ public function testAssertThatMatchesRegularExpression()
+ {
+ $this->assertThat('foobar', $this->matchesRegularExpression('/foo/'));
+ }
+
+ public function testAssertThatCallback()
+ {
+ $this->assertThat(
+ null,
+ $this->callback(function ($other) {
+ return true;
+ })
+ );
+ }
+
+ public function testAssertThatCountOf()
+ {
+ $this->assertThat([1], $this->countOf(1));
+ }
+
+ public function testAssertFileEquals()
+ {
+ $this->assertFileEquals(
+ $this->filesDirectory . 'foo.xml',
+ $this->filesDirectory . 'foo.xml'
+ );
+
+ try {
+ $this->assertFileEquals(
+ $this->filesDirectory . 'foo.xml',
+ $this->filesDirectory . 'bar.xml'
+ );
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertFileNotEquals()
+ {
+ $this->assertFileNotEquals(
+ $this->filesDirectory . 'foo.xml',
+ $this->filesDirectory . 'bar.xml'
+ );
+
+ try {
+ $this->assertFileNotEquals(
+ $this->filesDirectory . 'foo.xml',
+ $this->filesDirectory . 'foo.xml'
+ );
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertStringEqualsFile()
+ {
+ $this->assertStringEqualsFile(
+ $this->filesDirectory . 'foo.xml',
+ file_get_contents($this->filesDirectory . 'foo.xml')
+ );
+
+ try {
+ $this->assertStringEqualsFile(
+ $this->filesDirectory . 'foo.xml',
+ file_get_contents($this->filesDirectory . 'bar.xml')
+ );
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertStringNotEqualsFile()
+ {
+ $this->assertStringNotEqualsFile(
+ $this->filesDirectory . 'foo.xml',
+ file_get_contents($this->filesDirectory . 'bar.xml')
+ );
+
+ try {
+ $this->assertStringNotEqualsFile(
+ $this->filesDirectory . 'foo.xml',
+ file_get_contents($this->filesDirectory . 'foo.xml')
+ );
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertStringStartsWithThrowsException()
+ {
+ $this->assertStringStartsWith(null, null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertStringStartsWithThrowsException2()
+ {
+ $this->assertStringStartsWith('', null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertStringStartsNotWithThrowsException()
+ {
+ $this->assertStringStartsNotWith(null, null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertStringStartsNotWithThrowsException2()
+ {
+ $this->assertStringStartsNotWith('', null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertStringEndsWithThrowsException()
+ {
+ $this->assertStringEndsWith(null, null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertStringEndsWithThrowsException2()
+ {
+ $this->assertStringEndsWith('', null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertStringEndsNotWithThrowsException()
+ {
+ $this->assertStringEndsNotWith(null, null);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertStringEndsNotWithThrowsException2()
+ {
+ $this->assertStringEndsNotWith('', null);
+ }
+
+ public function testAssertStringStartsWith()
+ {
+ $this->assertStringStartsWith('prefix', 'prefixfoo');
+
+ try {
+ $this->assertStringStartsWith('prefix', 'foo');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertStringStartsNotWith()
+ {
+ $this->assertStringStartsNotWith('prefix', 'foo');
+
+ try {
+ $this->assertStringStartsNotWith('prefix', 'prefixfoo');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertStringEndsWith()
+ {
+ $this->assertStringEndsWith('suffix', 'foosuffix');
+
+ try {
+ $this->assertStringEndsWith('suffix', 'foo');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertStringEndsNotWith()
+ {
+ $this->assertStringEndsNotWith('suffix', 'foo');
+
+ try {
+ $this->assertStringEndsNotWith('suffix', 'foosuffix');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertStringMatchesFormatRaisesExceptionForInvalidFirstArgument()
+ {
+ $this->assertStringMatchesFormat(null, '');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertStringMatchesFormatRaisesExceptionForInvalidSecondArgument()
+ {
+ $this->assertStringMatchesFormat('', null);
+ }
+
+ public function testAssertStringMatchesFormat()
+ {
+ $this->assertStringMatchesFormat('*%s*', '***');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_AssertionFailedError
+ */
+ public function testAssertStringMatchesFormatFailure()
+ {
+ $this->assertStringMatchesFormat('*%s*', '**');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertStringNotMatchesFormatRaisesExceptionForInvalidFirstArgument()
+ {
+ $this->assertStringNotMatchesFormat(null, '');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertStringNotMatchesFormatRaisesExceptionForInvalidSecondArgument()
+ {
+ $this->assertStringNotMatchesFormat('', null);
+ }
+
+ public function testAssertStringNotMatchesFormat()
+ {
+ $this->assertStringNotMatchesFormat('*%s*', '**');
+
+ try {
+ $this->assertStringMatchesFormat('*%s*', '**');
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertEmpty()
+ {
+ $this->assertEmpty([]);
+
+ try {
+ $this->assertEmpty(['foo']);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertNotEmpty()
+ {
+ $this->assertNotEmpty(['foo']);
+
+ try {
+ $this->assertNotEmpty([]);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertAttributeEmpty()
+ {
+ $o = new stdClass;
+ $o->a = [];
+
+ $this->assertAttributeEmpty('a', $o);
+
+ try {
+ $o->a = ['b'];
+ $this->assertAttributeEmpty('a', $o);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertAttributeNotEmpty()
+ {
+ $o = new stdClass;
+ $o->a = ['b'];
+
+ $this->assertAttributeNotEmpty('a', $o);
+
+ try {
+ $o->a = [];
+ $this->assertAttributeNotEmpty('a', $o);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testMarkTestIncomplete()
+ {
+ try {
+ $this->markTestIncomplete('incomplete');
+ } catch (PHPUnit_Framework_IncompleteTestError $e) {
+ $this->assertEquals('incomplete', $e->getMessage());
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testMarkTestSkipped()
+ {
+ try {
+ $this->markTestSkipped('skipped');
+ } catch (PHPUnit_Framework_SkippedTestError $e) {
+ $this->assertEquals('skipped', $e->getMessage());
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertCount()
+ {
+ $this->assertCount(2, [1, 2]);
+
+ try {
+ $this->assertCount(2, [1, 2, 3]);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertCountTraversable()
+ {
+ $this->assertCount(2, new ArrayIterator([1, 2]));
+
+ try {
+ $this->assertCount(2, new ArrayIterator([1, 2, 3]));
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertCountThrowsExceptionIfExpectedCountIsNoInteger()
+ {
+ try {
+ $this->assertCount('a', []);
+ } catch (PHPUnit_Framework_Exception $e) {
+ $this->assertEquals('Argument #1 (No Value) of PHPUnit_Framework_Assert::assertCount() must be a integer', $e->getMessage());
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertCountThrowsExceptionIfElementIsNotCountable()
+ {
+ try {
+ $this->assertCount(2, '');
+ } catch (PHPUnit_Framework_Exception $e) {
+ $this->assertEquals('Argument #2 (No Value) of PHPUnit_Framework_Assert::assertCount() must be a countable or traversable', $e->getMessage());
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertAttributeCount()
+ {
+ $o = new stdClass;
+ $o->a = [];
+
+ $this->assertAttributeCount(0, 'a', $o);
+ }
+
+ public function testAssertNotCount()
+ {
+ $this->assertNotCount(2, [1, 2, 3]);
+
+ try {
+ $this->assertNotCount(2, [1, 2]);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertNotCountThrowsExceptionIfExpectedCountIsNoInteger()
+ {
+ $this->assertNotCount('a', []);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertNotCountThrowsExceptionIfElementIsNotCountable()
+ {
+ $this->assertNotCount(2, '');
+ }
+
+ public function testAssertAttributeNotCount()
+ {
+ $o = new stdClass;
+ $o->a = [];
+
+ $this->assertAttributeNotCount(1, 'a', $o);
+ }
+
+ public function testAssertSameSize()
+ {
+ $this->assertSameSize([1, 2], [3, 4]);
+
+ try {
+ $this->assertSameSize([1, 2], [1, 2, 3]);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertSameSizeThrowsExceptionIfExpectedIsNotCountable()
+ {
+ try {
+ $this->assertSameSize('a', []);
+ } catch (PHPUnit_Framework_Exception $e) {
+ $this->assertEquals('Argument #1 (No Value) of PHPUnit_Framework_Assert::assertSameSize() must be a countable or traversable', $e->getMessage());
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertSameSizeThrowsExceptionIfActualIsNotCountable()
+ {
+ try {
+ $this->assertSameSize([], '');
+ } catch (PHPUnit_Framework_Exception $e) {
+ $this->assertEquals('Argument #2 (No Value) of PHPUnit_Framework_Assert::assertSameSize() must be a countable or traversable', $e->getMessage());
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertNotSameSize()
+ {
+ $this->assertNotSameSize([1, 2], [1, 2, 3]);
+
+ try {
+ $this->assertNotSameSize([1, 2], [3, 4]);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertNotSameSizeThrowsExceptionIfExpectedIsNotCountable()
+ {
+ $this->assertNotSameSize('a', []);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertNotSameSizeThrowsExceptionIfActualIsNotCountable()
+ {
+ $this->assertNotSameSize([], '');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertJsonRaisesExceptionForInvalidArgument()
+ {
+ $this->assertJson(null);
+ }
+
+ public function testAssertJson()
+ {
+ $this->assertJson('{}');
+ }
+
+ public function testAssertJsonStringEqualsJsonString()
+ {
+ $expected = '{"Mascott" : "Tux"}';
+ $actual = '{"Mascott" : "Tux"}';
+ $message = 'Given Json strings do not match';
+
+ $this->assertJsonStringEqualsJsonString($expected, $actual, $message);
+ }
+
+ /**
+ * @dataProvider validInvalidJsonDataprovider
+ */
+ public function testAssertJsonStringEqualsJsonStringErrorRaised($expected, $actual)
+ {
+ try {
+ $this->assertJsonStringEqualsJsonString($expected, $actual);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+ $this->fail('Expected exception not found');
+ }
+
+ public function testAssertJsonStringNotEqualsJsonString()
+ {
+ $expected = '{"Mascott" : "Beastie"}';
+ $actual = '{"Mascott" : "Tux"}';
+ $message = 'Given Json strings do match';
+
+ $this->assertJsonStringNotEqualsJsonString($expected, $actual, $message);
+ }
+
+ /**
+ * @dataProvider validInvalidJsonDataprovider
+ */
+ public function testAssertJsonStringNotEqualsJsonStringErrorRaised($expected, $actual)
+ {
+ try {
+ $this->assertJsonStringNotEqualsJsonString($expected, $actual);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+ $this->fail('Expected exception not found');
+ }
+
+ public function testAssertJsonStringEqualsJsonFile()
+ {
+ $file = __DIR__ . '/../_files/JsonData/simpleObject.json';
+ $actual = json_encode(['Mascott' => 'Tux']);
+ $message = '';
+ $this->assertJsonStringEqualsJsonFile($file, $actual, $message);
+ }
+
+ public function testAssertJsonStringEqualsJsonFileExpectingExpectationFailedException()
+ {
+ $file = __DIR__ . '/../_files/JsonData/simpleObject.json';
+ $actual = json_encode(['Mascott' => 'Beastie']);
+ $message = '';
+ try {
+ $this->assertJsonStringEqualsJsonFile($file, $actual, $message);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ 'Failed asserting that \'{"Mascott":"Beastie"}\' matches JSON string "{"Mascott":"Tux"}".',
+ $e->getMessage()
+ );
+
+ return;
+ }
+
+ $this->fail('Expected Exception not thrown.');
+ }
+
+ public function testAssertJsonStringEqualsJsonFileExpectingException()
+ {
+ $file = __DIR__ . '/../_files/JsonData/simpleObject.json';
+ try {
+ $this->assertJsonStringEqualsJsonFile($file, null);
+ } catch (PHPUnit_Framework_Exception $e) {
+ return;
+ }
+ $this->fail('Expected Exception not thrown.');
+ }
+
+ public function testAssertJsonStringNotEqualsJsonFile()
+ {
+ $file = __DIR__ . '/../_files/JsonData/simpleObject.json';
+ $actual = json_encode(['Mascott' => 'Beastie']);
+ $message = '';
+ $this->assertJsonStringNotEqualsJsonFile($file, $actual, $message);
+ }
+
+ public function testAssertJsonStringNotEqualsJsonFileExpectingException()
+ {
+ $file = __DIR__ . '/../_files/JsonData/simpleObject.json';
+ try {
+ $this->assertJsonStringNotEqualsJsonFile($file, null);
+ } catch (PHPUnit_Framework_Exception $e) {
+ return;
+ }
+ $this->fail('Expected exception not found.');
+ }
+
+ public function testAssertJsonFileNotEqualsJsonFile()
+ {
+ $fileExpected = __DIR__ . '/../_files/JsonData/simpleObject.json';
+ $fileActual = __DIR__ . '/../_files/JsonData/arrayObject.json';
+ $message = '';
+ $this->assertJsonFileNotEqualsJsonFile($fileExpected, $fileActual, $message);
+ }
+
+ public function testAssertJsonFileEqualsJsonFile()
+ {
+ $file = __DIR__ . '/../_files/JsonData/simpleObject.json';
+ $message = '';
+ $this->assertJsonFileEqualsJsonFile($file, $file, $message);
+ }
+
+ public function testAssertInstanceOf()
+ {
+ $this->assertInstanceOf('stdClass', new stdClass);
+
+ try {
+ $this->assertInstanceOf('Exception', new stdClass);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertInstanceOfThrowsExceptionForInvalidArgument()
+ {
+ $this->assertInstanceOf(null, new stdClass);
+ }
+
+ public function testAssertAttributeInstanceOf()
+ {
+ $o = new stdClass;
+ $o->a = new stdClass;
+
+ $this->assertAttributeInstanceOf('stdClass', 'a', $o);
+ }
+
+ public function testAssertNotInstanceOf()
+ {
+ $this->assertNotInstanceOf('Exception', new stdClass);
+
+ try {
+ $this->assertNotInstanceOf('stdClass', new stdClass);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertNotInstanceOfThrowsExceptionForInvalidArgument()
+ {
+ $this->assertNotInstanceOf(null, new stdClass);
+ }
+
+ public function testAssertAttributeNotInstanceOf()
+ {
+ $o = new stdClass;
+ $o->a = new stdClass;
+
+ $this->assertAttributeNotInstanceOf('Exception', 'a', $o);
+ }
+
+ public function testAssertInternalType()
+ {
+ $this->assertInternalType('integer', 1);
+
+ try {
+ $this->assertInternalType('string', 1);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAssertInternalTypeDouble()
+ {
+ $this->assertInternalType('double', 1.0);
+
+ try {
+ $this->assertInternalType('double', 1);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertInternalTypeThrowsExceptionForInvalidArgument()
+ {
+ $this->assertInternalType(null, 1);
+ }
+
+ public function testAssertAttributeInternalType()
+ {
+ $o = new stdClass;
+ $o->a = 1;
+
+ $this->assertAttributeInternalType('integer', 'a', $o);
+ }
+
+ public function testAssertNotInternalType()
+ {
+ $this->assertNotInternalType('string', 1);
+
+ try {
+ $this->assertNotInternalType('integer', 1);
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertNotInternalTypeThrowsExceptionForInvalidArgument()
+ {
+ $this->assertNotInternalType(null, 1);
+ }
+
+ public function testAssertAttributeNotInternalType()
+ {
+ $o = new stdClass;
+ $o->a = 1;
+
+ $this->assertAttributeNotInternalType('string', 'a', $o);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertStringMatchesFormatFileThrowsExceptionForInvalidArgument()
+ {
+ $this->assertStringMatchesFormatFile('not_existing_file', '');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertStringMatchesFormatFileThrowsExceptionForInvalidArgument2()
+ {
+ $this->assertStringMatchesFormatFile($this->filesDirectory . 'expectedFileFormat.txt', null);
+ }
+
+ public function testAssertStringMatchesFormatFile()
+ {
+ $this->assertStringMatchesFormatFile($this->filesDirectory . 'expectedFileFormat.txt', "FOO\n");
+
+ try {
+ $this->assertStringMatchesFormatFile($this->filesDirectory . 'expectedFileFormat.txt', "BAR\n");
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertStringNotMatchesFormatFileThrowsExceptionForInvalidArgument()
+ {
+ $this->assertStringNotMatchesFormatFile('not_existing_file', '');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testAssertStringNotMatchesFormatFileThrowsExceptionForInvalidArgument2()
+ {
+ $this->assertStringNotMatchesFormatFile($this->filesDirectory . 'expectedFileFormat.txt', null);
+ }
+
+ public function testAssertStringNotMatchesFormatFile()
+ {
+ $this->assertStringNotMatchesFormatFile($this->filesDirectory . 'expectedFileFormat.txt', "BAR\n");
+
+ try {
+ $this->assertStringNotMatchesFormatFile($this->filesDirectory . 'expectedFileFormat.txt', "FOO\n");
+ } catch (PHPUnit_Framework_AssertionFailedError $e) {
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @return array
+ */
+ public static function validInvalidJsonDataprovider()
+ {
+ return [
+ 'error syntax in expected JSON' => ['{"Mascott"::}', '{"Mascott" : "Tux"}'],
+ 'error UTF-8 in actual JSON' => ['{"Mascott" : "Tux"}', '{"Mascott" : :}'],
+ ];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Framework/BaseTestListenerTest.php b/vendor/phpunit/phpunit/tests/Framework/BaseTestListenerTest.php
new file mode 100644
index 0000000..c168e71
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Framework/BaseTestListenerTest.php
@@ -0,0 +1,28 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Framework_BaseTestListenerTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @var PHPUnit_Framework_TestResult
+ */
+ private $result;
+
+ public function testEndEventsAreCounted()
+ {
+ $this->result = new PHPUnit_Framework_TestResult;
+ $listener = new BaseTestListenerSample();
+ $this->result->addListener($listener);
+ $test = new Success;
+ $test->run($this->result);
+
+ $this->assertEquals(1, $listener->endCount);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Framework/Constraint/ArraySubsetTest.php b/vendor/phpunit/phpunit/tests/Framework/Constraint/ArraySubsetTest.php
new file mode 100644
index 0000000..39d5a8d
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Framework/Constraint/ArraySubsetTest.php
@@ -0,0 +1,65 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class PHPUnit_Framework_Constraint_ArraySubsetTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @param bool $expected
+ * @param array|Traversable $subset
+ * @param array|Traversable $other
+ * @param bool $strict
+ * @dataProvider evaluateDataProvider
+ */
+ public function testEvaluate($expected, $subset, $other, $strict)
+ {
+ $constraint = new PHPUnit_Framework_Constraint_ArraySubset($subset, $strict);
+
+ $this->assertSame($expected, $constraint->evaluate($other, '', true));
+ }
+
+ public static function evaluateDataProvider()
+ {
+ return [
+ 'loose array subset and array other' => [
+ 'expected' => true,
+ 'subset' => ['bar' => 0],
+ 'other' => ['foo' => '', 'bar' => '0'],
+ 'strict' => false
+ ],
+ 'strict array subset and array other' => [
+ 'expected' => false,
+ 'subset' => ['bar' => 0],
+ 'other' => ['foo' => '', 'bar' => '0'],
+ 'strict' => true
+ ],
+ 'loose array subset and ArrayObject other' => [
+ 'expected' => true,
+ 'subset' => ['bar' => 0],
+ 'other' => new ArrayObject(['foo' => '', 'bar' => '0']),
+ 'strict' => false
+ ],
+ 'strict ArrayObject subset and array other' => [
+ 'expected' => true,
+ 'subset' => new ArrayObject(['bar' => 0]),
+ 'other' => ['foo' => '', 'bar' => 0],
+ 'strict' => true
+ ],
+ ];
+ }
+
+ public function testEvaluateWithArrayAccess()
+ {
+ $arrayAccess = new ArrayAccessible(['foo' => 'bar']);
+
+ $constraint = new PHPUnit_Framework_Constraint_ArraySubset(['foo' => 'bar']);
+
+ $this->assertTrue($constraint->evaluate($arrayAccess, '', true));
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Framework/Constraint/CountTest.php b/vendor/phpunit/phpunit/tests/Framework/Constraint/CountTest.php
new file mode 100644
index 0000000..e127e8d
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Framework/Constraint/CountTest.php
@@ -0,0 +1,92 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class CountTest extends PHPUnit_Framework_TestCase
+{
+ public function testCount()
+ {
+ $countConstraint = new PHPUnit_Framework_Constraint_Count(3);
+ $this->assertTrue($countConstraint->evaluate([1, 2, 3], '', true));
+
+ $countConstraint = new PHPUnit_Framework_Constraint_Count(0);
+ $this->assertTrue($countConstraint->evaluate([], '', true));
+
+ $countConstraint = new PHPUnit_Framework_Constraint_Count(2);
+ $it = new TestIterator([1, 2]);
+
+ $this->assertTrue($countConstraint->evaluate($it, '', true));
+ }
+
+ public function testCountDoesNotChangeIteratorKey()
+ {
+ $countConstraint = new PHPUnit_Framework_Constraint_Count(2);
+
+ // test with 1st implementation of Iterator
+ $it = new TestIterator([1, 2]);
+
+ $countConstraint->evaluate($it, '', true);
+ $this->assertEquals(1, $it->current());
+
+ $it->next();
+ $countConstraint->evaluate($it, '', true);
+ $this->assertEquals(2, $it->current());
+
+ $it->next();
+ $countConstraint->evaluate($it, '', true);
+ $this->assertFalse($it->valid());
+
+ // test with 2nd implementation of Iterator
+ $it = new TestIterator2([1, 2]);
+
+ $countConstraint = new PHPUnit_Framework_Constraint_Count(2);
+ $countConstraint->evaluate($it, '', true);
+ $this->assertEquals(1, $it->current());
+
+ $it->next();
+ $countConstraint->evaluate($it, '', true);
+ $this->assertEquals(2, $it->current());
+
+ $it->next();
+ $countConstraint->evaluate($it, '', true);
+ $this->assertFalse($it->valid());
+ }
+
+ public function testCountGeneratorsDoNotRewind()
+ {
+ $generatorMaker = new TestGeneratorMaker();
+
+ $countConstraint = new PHPUnit_Framework_Constraint_Count(3);
+
+ $generator = $generatorMaker->create([1, 2, 3]);
+ $this->assertEquals(1, $generator->current());
+ $countConstraint->evaluate($generator, '', true);
+ $this->assertEquals(null, $generator->current());
+
+ $countConstraint = new PHPUnit_Framework_Constraint_Count(2);
+
+ $generator = $generatorMaker->create([1, 2, 3]);
+ $this->assertEquals(1, $generator->current());
+ $generator->next();
+ $this->assertEquals(2, $generator->current());
+ $countConstraint->evaluate($generator, '', true);
+ $this->assertEquals(null, $generator->current());
+
+ $countConstraint = new PHPUnit_Framework_Constraint_Count(1);
+
+ $generator = $generatorMaker->create([1, 2, 3]);
+ $this->assertEquals(1, $generator->current());
+ $generator->next();
+ $this->assertEquals(2, $generator->current());
+ $generator->next();
+ $this->assertEquals(3, $generator->current());
+ $countConstraint->evaluate($generator, '', true);
+ $this->assertEquals(null, $generator->current());
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Framework/Constraint/ExceptionMessageRegExpTest.php b/vendor/phpunit/phpunit/tests/Framework/Constraint/ExceptionMessageRegExpTest.php
new file mode 100644
index 0000000..3a99654
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Framework/Constraint/ExceptionMessageRegExpTest.php
@@ -0,0 +1,51 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class ExceptionMessageRegExpTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessageRegExp /^A polymorphic \w+ message/
+ */
+ public function testRegexMessage()
+ {
+ throw new Exception('A polymorphic exception message');
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessageRegExp /^a poly[a-z]+ [a-zA-Z0-9_]+ me(s){2}age$/i
+ */
+ public function testRegexMessageExtreme()
+ {
+ throw new Exception('A polymorphic exception message');
+ }
+
+ /**
+ * @runInSeparateProcess
+ * @requires extension xdebug
+ * @expectedException \Exception
+ * @expectedExceptionMessageRegExp #Screaming preg_match#
+ */
+ public function testMessageXdebugScreamCompatibility()
+ {
+ ini_set('xdebug.scream', '1');
+ throw new Exception('Screaming preg_match');
+ }
+
+ /**
+ * @expectedException \Exception variadic
+ * @expectedExceptionMessageRegExp /^A variadic \w+ message/
+ */
+ public function testSimultaneousLiteralAndRegExpExceptionMessage()
+ {
+ throw new Exception('A variadic exception message');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Framework/Constraint/ExceptionMessageTest.php b/vendor/phpunit/phpunit/tests/Framework/Constraint/ExceptionMessageTest.php
new file mode 100644
index 0000000..fcab5c0
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Framework/Constraint/ExceptionMessageTest.php
@@ -0,0 +1,48 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class ExceptionMessageTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage A literal exception message
+ */
+ public function testLiteralMessage()
+ {
+ throw new Exception('A literal exception message');
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage A partial
+ */
+ public function testPartialMessageBegin()
+ {
+ throw new Exception('A partial exception message');
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage partial exception
+ */
+ public function testPartialMessageMiddle()
+ {
+ throw new Exception('A partial exception message');
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage exception message
+ */
+ public function testPartialMessageEnd()
+ {
+ throw new Exception('A partial exception message');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Framework/Constraint/IsJsonTest.php b/vendor/phpunit/phpunit/tests/Framework/Constraint/IsJsonTest.php
new file mode 100644
index 0000000..535faa9
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Framework/Constraint/IsJsonTest.php
@@ -0,0 +1,29 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Framework_Constraint_IsJsonTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider evaluateDataprovider
+ */
+ public function testEvaluate($expected, $jsonOther)
+ {
+ $constraint = new PHPUnit_Framework_Constraint_IsJson();
+ $this->assertEquals($expected, $constraint->evaluate($jsonOther, '', true));
+ }
+
+ public static function evaluateDataprovider()
+ {
+ return [
+ 'valid JSON' => [true, '{}'],
+ 'empty string should be treated as invalid JSON' => [false, ''],
+ ];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Framework/Constraint/JsonMatches/ErrorMessageProviderTest.php b/vendor/phpunit/phpunit/tests/Framework/Constraint/JsonMatches/ErrorMessageProviderTest.php
new file mode 100644
index 0000000..8770a6e
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Framework/Constraint/JsonMatches/ErrorMessageProviderTest.php
@@ -0,0 +1,78 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Framework_Constraint_JsonMatches_ErrorMessageProviderTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider translateTypeToPrefixDataprovider
+ */
+ public function testTranslateTypeToPrefix($expected, $type)
+ {
+ $this->assertEquals(
+ $expected,
+ PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider::translateTypeToPrefix($type)
+ );
+ }
+
+ /**
+ * @dataProvider determineJsonErrorDataprovider
+ */
+ public function testDetermineJsonError($expected, $error, $prefix)
+ {
+ $this->assertEquals(
+ $expected,
+ PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider::determineJsonError(
+ $error,
+ $prefix
+ )
+ );
+ }
+
+ public static function determineJsonErrorDataprovider()
+ {
+ return [
+ 'JSON_ERROR_NONE' => [
+ null, 'json_error_none', ''
+ ],
+ 'JSON_ERROR_DEPTH' => [
+ 'Maximum stack depth exceeded', JSON_ERROR_DEPTH, ''
+ ],
+ 'prefixed JSON_ERROR_DEPTH' => [
+ 'TUX: Maximum stack depth exceeded', JSON_ERROR_DEPTH, 'TUX: '
+ ],
+ 'JSON_ERROR_STATE_MISMatch' => [
+ 'Underflow or the modes mismatch', JSON_ERROR_STATE_MISMATCH, ''
+ ],
+ 'JSON_ERROR_CTRL_CHAR' => [
+ 'Unexpected control character found', JSON_ERROR_CTRL_CHAR, ''
+ ],
+ 'JSON_ERROR_SYNTAX' => [
+ 'Syntax error, malformed JSON', JSON_ERROR_SYNTAX, ''
+ ],
+ 'JSON_ERROR_UTF8`' => [
+ 'Malformed UTF-8 characters, possibly incorrectly encoded',
+ JSON_ERROR_UTF8,
+ ''
+ ],
+ 'Invalid error indicator' => [
+ 'Unknown error', 55, ''
+ ],
+ ];
+ }
+
+ public static function translateTypeToPrefixDataprovider()
+ {
+ return [
+ 'expected' => ['Expected value JSON decode error - ', 'expected'],
+ 'actual' => ['Actual value JSON decode error - ', 'actual'],
+ 'default' => ['', ''],
+ ];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Framework/Constraint/JsonMatchesTest.php b/vendor/phpunit/phpunit/tests/Framework/Constraint/JsonMatchesTest.php
new file mode 100644
index 0000000..c0920eb
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Framework/Constraint/JsonMatchesTest.php
@@ -0,0 +1,39 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Framework_Constraint_JsonMatchesTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider evaluateDataprovider
+ */
+ public function testEvaluate($expected, $jsonOther, $jsonValue)
+ {
+ $constraint = new PHPUnit_Framework_Constraint_JsonMatches($jsonValue);
+ $this->assertEquals($expected, $constraint->evaluate($jsonOther, '', true));
+ }
+
+ public function testToString()
+ {
+ $jsonValue = json_encode(['Mascott' => 'Tux']);
+ $constraint = new PHPUnit_Framework_Constraint_JsonMatches($jsonValue);
+
+ $this->assertEquals('matches JSON string "' . $jsonValue . '"', $constraint->toString());
+ }
+
+ public static function evaluateDataprovider()
+ {
+ return [
+ 'valid JSON' => [true, json_encode(['Mascott' => 'Tux']), json_encode(['Mascott' => 'Tux'])],
+ 'error syntax' => [false, '{"Mascott"::}', json_encode(['Mascott' => 'Tux'])],
+ 'error UTF-8' => [false, json_encode('\xB1\x31'), json_encode(['Mascott' => 'Tux'])],
+ 'invalid JSON in class instantiation' => [false, json_encode(['Mascott' => 'Tux']), '{"Mascott"::}'],
+ ];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Framework/ConstraintTest.php b/vendor/phpunit/phpunit/tests/Framework/ConstraintTest.php
new file mode 100644
index 0000000..e8d98fc
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Framework/ConstraintTest.php
@@ -0,0 +1,3053 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Framework_ConstraintTest extends PHPUnit_Framework_TestCase
+{
+ public function testConstraintArrayHasKey()
+ {
+ $constraint = PHPUnit_Framework_Assert::arrayHasKey(0);
+
+ $this->assertFalse($constraint->evaluate([], '', true));
+ $this->assertEquals('has the key 0', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate([]);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+Failed asserting that an array has the key 0.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintArrayHasKey2()
+ {
+ $constraint = PHPUnit_Framework_Assert::arrayHasKey(0);
+
+ try {
+ $constraint->evaluate([], 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message\nFailed asserting that an array has the key 0.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintArrayNotHasKey()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::arrayHasKey(0)
+ );
+
+ $this->assertFalse($constraint->evaluate([0 => 1], '', true));
+ $this->assertEquals('does not have the key 0', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate([0 => 1]);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that an array does not have the key 0.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintArrayNotHasKey2()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::arrayHasKey(0)
+ );
+
+ try {
+ $constraint->evaluate([0], 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message
+Failed asserting that an array does not have the key 0.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsReadable()
+ {
+ $constraint = PHPUnit_Framework_Assert::isReadable();
+
+ $this->assertFalse($constraint->evaluate('foo', '', true));
+ $this->assertEquals('is readable', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate('foo');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that "foo" is readable.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsWritable()
+ {
+ $constraint = PHPUnit_Framework_Assert::isWritable();
+
+ $this->assertFalse($constraint->evaluate('foo', '', true));
+ $this->assertEquals('is writable', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate('foo');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that "foo" is writable.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintDirectoryExists()
+ {
+ $constraint = PHPUnit_Framework_Assert::directoryExists();
+
+ $this->assertFalse($constraint->evaluate('foo', '', true));
+ $this->assertEquals('directory exists', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate('foo');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that directory "foo" exists.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintFileExists()
+ {
+ $constraint = PHPUnit_Framework_Assert::fileExists();
+
+ $this->assertFalse($constraint->evaluate('foo', '', true));
+ $this->assertEquals('file exists', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate('foo');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that file "foo" exists.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintFileExists2()
+ {
+ $constraint = PHPUnit_Framework_Assert::fileExists();
+
+ try {
+ $constraint->evaluate('foo', 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that file "foo" exists.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintFileNotExists()
+ {
+ $file = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'ClassWithNonPublicAttributes.php';
+
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::fileExists()
+ );
+
+ $this->assertFalse($constraint->evaluate($file, '', true));
+ $this->assertEquals('file does not exist', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate($file);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that file "$file" does not exist.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintFileNotExists2()
+ {
+ $file = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'ClassWithNonPublicAttributes.php';
+
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::fileExists()
+ );
+
+ try {
+ $constraint->evaluate($file, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that file "$file" does not exist.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintGreaterThan()
+ {
+ $constraint = PHPUnit_Framework_Assert::greaterThan(1);
+
+ $this->assertFalse($constraint->evaluate(0, '', true));
+ $this->assertTrue($constraint->evaluate(2, '', true));
+ $this->assertEquals('is greater than 1', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate(0);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 0 is greater than 1.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintGreaterThan2()
+ {
+ $constraint = PHPUnit_Framework_Assert::greaterThan(1);
+
+ try {
+ $constraint->evaluate(0, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message
+Failed asserting that 0 is greater than 1.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintNotGreaterThan()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::greaterThan(1)
+ );
+
+ $this->assertTrue($constraint->evaluate(1, '', true));
+ $this->assertEquals('is not greater than 1', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate(2);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 2 is not greater than 1.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintNotGreaterThan2()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::greaterThan(1)
+ );
+
+ try {
+ $constraint->evaluate(2, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message
+Failed asserting that 2 is not greater than 1.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintGreaterThanOrEqual()
+ {
+ $constraint = PHPUnit_Framework_Assert::greaterThanOrEqual(1);
+
+ $this->assertTrue($constraint->evaluate(1, '', true));
+ $this->assertFalse($constraint->evaluate(0, '', true));
+ $this->assertEquals('is equal to 1 or is greater than 1', $constraint->toString());
+ $this->assertCount(2, $constraint);
+
+ try {
+ $constraint->evaluate(0);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 0 is equal to 1 or is greater than 1.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintGreaterThanOrEqual2()
+ {
+ $constraint = PHPUnit_Framework_Assert::greaterThanOrEqual(1);
+
+ try {
+ $constraint->evaluate(0, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message
+Failed asserting that 0 is equal to 1 or is greater than 1.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintNotGreaterThanOrEqual()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::greaterThanOrEqual(1)
+ );
+
+ $this->assertFalse($constraint->evaluate(1, '', true));
+ $this->assertEquals('not( is equal to 1 or is greater than 1 )', $constraint->toString());
+ $this->assertCount(2, $constraint);
+
+ try {
+ $constraint->evaluate(1);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that not( 1 is equal to 1 or is greater than 1 ).
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintNotGreaterThanOrEqual2()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::greaterThanOrEqual(1)
+ );
+
+ try {
+ $constraint->evaluate(1, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message
+Failed asserting that not( 1 is equal to 1 or is greater than 1 ).
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsAnything()
+ {
+ $constraint = PHPUnit_Framework_Assert::anything();
+
+ $this->assertTrue($constraint->evaluate(null, '', true));
+ $this->assertNull($constraint->evaluate(null));
+ $this->assertEquals('is anything', $constraint->toString());
+ $this->assertCount(0, $constraint);
+ }
+
+ public function testConstraintNotIsAnything()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::anything()
+ );
+
+ $this->assertFalse($constraint->evaluate(null, '', true));
+ $this->assertEquals('is not anything', $constraint->toString());
+ $this->assertCount(0, $constraint);
+
+ try {
+ $constraint->evaluate(null);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that null is not anything.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsEqual()
+ {
+ $constraint = PHPUnit_Framework_Assert::equalTo(1);
+
+ $this->assertTrue($constraint->evaluate(1, '', true));
+ $this->assertFalse($constraint->evaluate(0, '', true));
+ $this->assertEquals('is equal to 1', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate(0);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 0 matches expected 1.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function isEqualProvider()
+ {
+ $a = new stdClass;
+ $a->foo = 'bar';
+ $b = new stdClass;
+ $ahash = spl_object_hash($a);
+ $bhash = spl_object_hash($b);
+
+ $c = new stdClass;
+ $c->foo = 'bar';
+ $c->int = 1;
+ $c->array = [0, [1], [2], 3];
+ $c->related = new stdClass;
+ $c->related->foo = "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk";
+ $c->self = $c;
+ $c->c = $c;
+ $d = new stdClass;
+ $d->foo = 'bar';
+ $d->int = 2;
+ $d->array = [0, [4], [2], 3];
+ $d->related = new stdClass;
+ $d->related->foo = "a\np\nc\nd\ne\nf\ng\nh\ni\nw\nk";
+ $d->self = $d;
+ $d->c = $c;
+
+ $storage1 = new SplObjectStorage;
+ $storage1->attach($a);
+ $storage1->attach($b);
+ $storage2 = new SplObjectStorage;
+ $storage2->attach($b);
+ $storage1hash = spl_object_hash($storage1);
+ $storage2hash = spl_object_hash($storage2);
+
+ $dom1 = new DOMDocument;
+ $dom1->preserveWhiteSpace = false;
+ $dom1->loadXML('<root></root>');
+ $dom2 = new DOMDocument;
+ $dom2->preserveWhiteSpace = false;
+ $dom2->loadXML('<root><foo/></root>');
+
+ $data = [
+ [1, 0, <<<EOF
+Failed asserting that 0 matches expected 1.
+
+EOF
+ ],
+ [1.1, 0, <<<EOF
+Failed asserting that 0 matches expected 1.1.
+
+EOF
+ ],
+ ['a', 'b', <<<EOF
+Failed asserting that two strings are equal.
+--- Expected
++++ Actual
+@@ @@
+-'a'
++'b'
+
+EOF
+ ],
+ ["a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk", "a\np\nc\nd\ne\nf\ng\nh\ni\nw\nk", <<<EOF
+Failed asserting that two strings are equal.
+--- Expected
++++ Actual
+@@ @@
+ 'a
+-b
++p
+@@ @@
+ i
+-j
++w
+ k'
+
+EOF
+ ],
+ [1, [0], <<<EOF
+Array (...) does not match expected type "integer".
+
+EOF
+ ],
+ [[0], 1, <<<EOF
+1 does not match expected type "array".
+
+EOF
+ ],
+ [[0], [1], <<<EOF
+Failed asserting that two arrays are equal.
+--- Expected
++++ Actual
+@@ @@
+ Array (
+- 0 => 0
++ 0 => 1
+ )
+
+EOF
+ ],
+ [[true], ['true'], <<<EOF
+Failed asserting that two arrays are equal.
+--- Expected
++++ Actual
+@@ @@
+ Array (
+- 0 => true
++ 0 => 'true'
+ )
+
+EOF
+ ],
+ [[0, [1], [2], 3], [0, [4], [2], 3], <<<EOF
+Failed asserting that two arrays are equal.
+--- Expected
++++ Actual
+@@ @@
+ Array (
+ 0 => 0
+ 1 => Array (
+- 0 => 1
++ 0 => 4
+ )
+ 2 => Array (...)
+ 3 => 3
+ )
+
+EOF
+ ],
+ [$a, [0], <<<EOF
+Array (...) does not match expected type "object".
+
+EOF
+ ],
+ [[0], $a, <<<EOF
+stdClass Object (...) does not match expected type "array".
+
+EOF
+ ],
+ [$a, $b, <<<EOF
+Failed asserting that two objects are equal.
+--- Expected
++++ Actual
+@@ @@
+ stdClass Object (
+- 'foo' => 'bar'
+ )
+
+EOF
+ ],
+ [$c, $d, <<<EOF
+Failed asserting that two objects are equal.
+--- Expected
++++ Actual
+@@ @@
+ stdClass Object (
+ 'foo' => 'bar'
+- 'int' => 1
++ 'int' => 2
+ 'array' => Array (
+ 0 => 0
+ 1 => Array (
+- 0 => 1
++ 0 => 4
+@@ @@
+ 'foo' => 'a
+- b
++ p
+@@ @@
+ i
+- j
++ w
+ k'
+ )
+ 'self' => stdClass Object (...)
+ 'c' => stdClass Object (...)
+ )
+
+EOF
+ ],
+ [$dom1, $dom2, <<<EOF
+Failed asserting that two DOM documents are equal.
+--- Expected
++++ Actual
+@@ @@
+ <?xml version="1.0"?>
+-<root/>
++<root>
++ <foo/>
++</root>
+
+EOF
+ ],
+ [
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/Chicago')),
+ <<<EOF
+Failed asserting that two DateTime objects are equal.
+--- Expected
++++ Actual
+@@ @@
+-2013-03-29T04:13:35.000000-0400
++2013-03-29T04:13:35.000000-0500
+
+EOF
+ ],
+ ];
+
+ if (PHP_MAJOR_VERSION < 7) {
+ $data[] = [$storage1, $storage2, <<<EOF
+Failed asserting that two objects are equal.
+--- Expected
++++ Actual
+@@ @@
+-SplObjectStorage Object &$storage1hash (
+- '$ahash' => Array &0 (
+- 'obj' => stdClass Object &$ahash (
+- 'foo' => 'bar'
+- )
+- 'inf' => null
+- )
+- '$bhash' => Array &1 (
++SplObjectStorage Object &$storage2hash (
++ '$bhash' => Array &0 (
+ 'obj' => stdClass Object &$bhash ()
+ 'inf' => null
+ )
+ )
+
+EOF
+ ];
+ } else {
+ $data[] = [$storage1, $storage2, <<<EOF
+Failed asserting that two objects are equal.
+--- Expected
++++ Actual
+@@ @@
+-SplObjectStorage Object &$storage1hash (
+- '$ahash' => Array &0 (
+- 'obj' => stdClass Object &$ahash (
+- 'foo' => 'bar'
+- )
+- 'inf' => null
+- )
+- '$bhash' => Array &1 (
++SplObjectStorage Object &$storage2hash (
++ '$bhash' => Array &0 (
+ 'obj' => stdClass Object &$bhash ()
+ 'inf' => null
+ )
+ )
+
+EOF
+ ];
+ }
+
+ return $data;
+ }
+
+ /**
+ * @dataProvider isEqualProvider
+ */
+ public function testConstraintIsEqual2($expected, $actual, $message)
+ {
+ $constraint = PHPUnit_Framework_Assert::equalTo($expected);
+
+ try {
+ $constraint->evaluate($actual, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ "custom message\n$message",
+ $this->trimnl(PHPUnit_Framework_TestFailure::exceptionToString($e))
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsNotEqual()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::equalTo(1)
+ );
+
+ $this->assertTrue($constraint->evaluate(0, '', true));
+ $this->assertFalse($constraint->evaluate(1, '', true));
+ $this->assertEquals('is not equal to 1', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate(1);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 1 is not equal to 1.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsNotEqual2()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::equalTo(1)
+ );
+
+ try {
+ $constraint->evaluate(1, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message
+Failed asserting that 1 is not equal to 1.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsIdentical()
+ {
+ $a = new stdClass;
+ $b = new stdClass;
+
+ $constraint = PHPUnit_Framework_Assert::identicalTo($a);
+
+ $this->assertFalse($constraint->evaluate($b, '', true));
+ $this->assertTrue($constraint->evaluate($a, '', true));
+ $this->assertEquals('is identical to an object of class "stdClass"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate($b);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+Failed asserting that two variables reference the same object.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsIdentical2()
+ {
+ $a = new stdClass;
+ $b = new stdClass;
+
+ $constraint = PHPUnit_Framework_Assert::identicalTo($a);
+
+ try {
+ $constraint->evaluate($b, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that two variables reference the same object.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsIdentical3()
+ {
+ $constraint = PHPUnit_Framework_Assert::identicalTo('a');
+
+ try {
+ $constraint->evaluate('b', 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that two strings are identical.
+--- Expected
++++ Actual
+@@ @@
+-a
++b
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsNotIdentical()
+ {
+ $a = new stdClass;
+ $b = new stdClass;
+
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::identicalTo($a)
+ );
+
+ $this->assertTrue($constraint->evaluate($b, '', true));
+ $this->assertFalse($constraint->evaluate($a, '', true));
+ $this->assertEquals('is not identical to an object of class "stdClass"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate($a);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+Failed asserting that two variables don't reference the same object.
+
+EOF
+ ,
+ $this->trimnl(PHPUnit_Framework_TestFailure::exceptionToString($e))
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsNotIdentical2()
+ {
+ $a = new stdClass;
+
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::identicalTo($a)
+ );
+
+ try {
+ $constraint->evaluate($a, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that two variables don't reference the same object.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsNotIdentical3()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::identicalTo('a')
+ );
+
+ try {
+ $constraint->evaluate('a', 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that two strings are not identical.
+
+EOF
+ ,
+ $this->trimnl(PHPUnit_Framework_TestFailure::exceptionToString($e))
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsInstanceOf()
+ {
+ $constraint = PHPUnit_Framework_Assert::isInstanceOf('Exception');
+
+ $this->assertFalse($constraint->evaluate(new stdClass, '', true));
+ $this->assertTrue($constraint->evaluate(new Exception, '', true));
+ $this->assertEquals('is instance of class "Exception"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ $interfaceConstraint = PHPUnit_Framework_Assert::isInstanceOf('Countable');
+ $this->assertFalse($interfaceConstraint->evaluate(new stdClass, '', true));
+ $this->assertTrue($interfaceConstraint->evaluate(new ArrayObject, '', true));
+ $this->assertEquals('is instance of interface "Countable"', $interfaceConstraint->toString());
+
+ try {
+ $constraint->evaluate(new stdClass);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that stdClass Object () is an instance of class "Exception".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsInstanceOf2()
+ {
+ $constraint = PHPUnit_Framework_Assert::isInstanceOf('Exception');
+
+ try {
+ $constraint->evaluate(new stdClass, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that stdClass Object () is an instance of class "Exception".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsNotInstanceOf()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::isInstanceOf('stdClass')
+ );
+
+ $this->assertFalse($constraint->evaluate(new stdClass, '', true));
+ $this->assertTrue($constraint->evaluate(new Exception, '', true));
+ $this->assertEquals('is not instance of class "stdClass"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate(new stdClass);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that stdClass Object () is not an instance of class "stdClass".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsNotInstanceOf2()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::isInstanceOf('stdClass')
+ );
+
+ try {
+ $constraint->evaluate(new stdClass, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that stdClass Object () is not an instance of class "stdClass".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsType()
+ {
+ $constraint = PHPUnit_Framework_Assert::isType('string');
+
+ $this->assertFalse($constraint->evaluate(0, '', true));
+ $this->assertTrue($constraint->evaluate('', '', true));
+ $this->assertEquals('is of type "string"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate(new stdClass);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertStringMatchesFormat(<<<EOF
+Failed asserting that stdClass Object &%x () is of type "string".
+
+EOF
+ ,
+ $this->trimnl(PHPUnit_Framework_TestFailure::exceptionToString($e))
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsType2()
+ {
+ $constraint = PHPUnit_Framework_Assert::isType('string');
+
+ try {
+ $constraint->evaluate(new stdClass, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertStringMatchesFormat(<<<EOF
+custom message
+Failed asserting that stdClass Object &%x () is of type "string".
+
+EOF
+ ,
+ $this->trimnl(PHPUnit_Framework_TestFailure::exceptionToString($e))
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function resources()
+ {
+ $fh = fopen(__FILE__, 'r');
+ fclose($fh);
+
+ return [
+ 'open resource' => [fopen(__FILE__, 'r')],
+ 'closed resource' => [$fh],
+ ];
+ }
+
+ /**
+ * @dataProvider resources
+ */
+ public function testConstraintIsResourceTypeEvaluatesCorrectlyWithResources($resource)
+ {
+ $constraint = PHPUnit_Framework_Assert::isType('resource');
+
+ $this->assertTrue($constraint->evaluate($resource, '', true));
+
+ @fclose($resource);
+ }
+
+ public function testConstraintIsNotType()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::isType('string')
+ );
+
+ $this->assertTrue($constraint->evaluate(0, '', true));
+ $this->assertFalse($constraint->evaluate('', '', true));
+ $this->assertEquals('is not of type "string"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate('');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that '' is not of type "string".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsNotType2()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::isType('string')
+ );
+
+ try {
+ $constraint->evaluate('', 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that '' is not of type "string".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsNull()
+ {
+ $constraint = PHPUnit_Framework_Assert::isNull();
+
+ $this->assertFalse($constraint->evaluate(0, '', true));
+ $this->assertTrue($constraint->evaluate(null, '', true));
+ $this->assertEquals('is null', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate(0);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+Failed asserting that 0 is null.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsNull2()
+ {
+ $constraint = PHPUnit_Framework_Assert::isNull();
+
+ try {
+ $constraint->evaluate(0, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that 0 is null.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsNotNull()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::isNull()
+ );
+
+ $this->assertFalse($constraint->evaluate(null, '', true));
+ $this->assertTrue($constraint->evaluate(0, '', true));
+ $this->assertEquals('is not null', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate(null);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+Failed asserting that null is not null.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsNotNull2()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::isNull()
+ );
+
+ try {
+ $constraint->evaluate(null, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that null is not null.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintLessThan()
+ {
+ $constraint = PHPUnit_Framework_Assert::lessThan(1);
+
+ $this->assertTrue($constraint->evaluate(0, '', true));
+ $this->assertFalse($constraint->evaluate(1, '', true));
+ $this->assertEquals('is less than 1', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate(1);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 1 is less than 1.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintLessThan2()
+ {
+ $constraint = PHPUnit_Framework_Assert::lessThan(1);
+
+ try {
+ $constraint->evaluate(1, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message
+Failed asserting that 1 is less than 1.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintNotLessThan()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::lessThan(1)
+ );
+
+ $this->assertTrue($constraint->evaluate(1, '', true));
+ $this->assertFalse($constraint->evaluate(0, '', true));
+ $this->assertEquals('is not less than 1', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate(0);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 0 is not less than 1.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintNotLessThan2()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::lessThan(1)
+ );
+
+ try {
+ $constraint->evaluate(0, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message
+Failed asserting that 0 is not less than 1.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintLessThanOrEqual()
+ {
+ $constraint = PHPUnit_Framework_Assert::lessThanOrEqual(1);
+
+ $this->assertTrue($constraint->evaluate(1, '', true));
+ $this->assertFalse($constraint->evaluate(2, '', true));
+ $this->assertEquals('is equal to 1 or is less than 1', $constraint->toString());
+ $this->assertCount(2, $constraint);
+
+ try {
+ $constraint->evaluate(2);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 2 is equal to 1 or is less than 1.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintCallback()
+ {
+ $closureReflect = function ($parameter) {
+ return $parameter;
+ };
+
+ $closureWithoutParameter = function () {
+ return true;
+ };
+
+ $constraint = PHPUnit_Framework_Assert::callback($closureWithoutParameter);
+ $this->assertTrue($constraint->evaluate('', '', true));
+
+ $constraint = PHPUnit_Framework_Assert::callback($closureReflect);
+ $this->assertTrue($constraint->evaluate(true, '', true));
+ $this->assertFalse($constraint->evaluate(false, '', true));
+
+ $callback = [$this, 'callbackReturningTrue'];
+ $constraint = PHPUnit_Framework_Assert::callback($callback);
+ $this->assertTrue($constraint->evaluate(false, '', true));
+
+ $callback = ['Framework_ConstraintTest', 'staticCallbackReturningTrue'];
+ $constraint = PHPUnit_Framework_Assert::callback($callback);
+ $this->assertTrue($constraint->evaluate(null, '', true));
+
+ $this->assertEquals('is accepted by specified callback', $constraint->toString());
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_ExpectationFailedException
+ * @expectedExceptionMessage Failed asserting that 'This fails' is accepted by specified callback.
+ */
+ public function testConstraintCallbackFailure()
+ {
+ $constraint = PHPUnit_Framework_Assert::callback(function () {
+ return false;
+ });
+ $constraint->evaluate('This fails');
+ }
+
+ public function callbackReturningTrue()
+ {
+ return true;
+ }
+
+ public static function staticCallbackReturningTrue()
+ {
+ return true;
+ }
+
+ public function testConstraintLessThanOrEqual2()
+ {
+ $constraint = PHPUnit_Framework_Assert::lessThanOrEqual(1);
+
+ try {
+ $constraint->evaluate(2, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message
+Failed asserting that 2 is equal to 1 or is less than 1.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintNotLessThanOrEqual()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::lessThanOrEqual(1)
+ );
+
+ $this->assertTrue($constraint->evaluate(2, '', true));
+ $this->assertFalse($constraint->evaluate(1, '', true));
+ $this->assertEquals('not( is equal to 1 or is less than 1 )', $constraint->toString());
+ $this->assertCount(2, $constraint);
+
+ try {
+ $constraint->evaluate(1);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that not( 1 is equal to 1 or is less than 1 ).
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintNotLessThanOrEqual2()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::lessThanOrEqual(1)
+ );
+
+ try {
+ $constraint->evaluate(1, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message
+Failed asserting that not( 1 is equal to 1 or is less than 1 ).
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintClassHasAttribute()
+ {
+ $constraint = PHPUnit_Framework_Assert::classHasAttribute('privateAttribute');
+
+ $this->assertTrue($constraint->evaluate('ClassWithNonPublicAttributes', '', true));
+ $this->assertFalse($constraint->evaluate('stdClass', '', true));
+ $this->assertEquals('has attribute "privateAttribute"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate('stdClass');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that class "stdClass" has attribute "privateAttribute".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintClassHasAttribute2()
+ {
+ $constraint = PHPUnit_Framework_Assert::classHasAttribute('privateAttribute');
+
+ try {
+ $constraint->evaluate('stdClass', 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that class "stdClass" has attribute "privateAttribute".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintClassNotHasAttribute()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::classHasAttribute('privateAttribute')
+ );
+
+ $this->assertTrue($constraint->evaluate('stdClass', '', true));
+ $this->assertFalse($constraint->evaluate('ClassWithNonPublicAttributes', '', true));
+ $this->assertEquals('does not have attribute "privateAttribute"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate('ClassWithNonPublicAttributes');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that class "ClassWithNonPublicAttributes" does not have attribute "privateAttribute".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintClassNotHasAttribute2()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::classHasAttribute('privateAttribute')
+ );
+
+ try {
+ $constraint->evaluate('ClassWithNonPublicAttributes', 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that class "ClassWithNonPublicAttributes" does not have attribute "privateAttribute".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintClassHasStaticAttribute()
+ {
+ $constraint = PHPUnit_Framework_Assert::classHasStaticAttribute('privateStaticAttribute');
+
+ $this->assertTrue($constraint->evaluate('ClassWithNonPublicAttributes', '', true));
+ $this->assertFalse($constraint->evaluate('stdClass', '', true));
+ $this->assertEquals('has static attribute "privateStaticAttribute"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate('stdClass');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that class "stdClass" has static attribute "privateStaticAttribute".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintClassHasStaticAttribute2()
+ {
+ $constraint = PHPUnit_Framework_Assert::classHasStaticAttribute('foo');
+
+ try {
+ $constraint->evaluate('stdClass', 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that class "stdClass" has static attribute "foo".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintClassNotHasStaticAttribute()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::classHasStaticAttribute('privateStaticAttribute')
+ );
+
+ $this->assertTrue($constraint->evaluate('stdClass', '', true));
+ $this->assertFalse($constraint->evaluate('ClassWithNonPublicAttributes', '', true));
+ $this->assertEquals('does not have static attribute "privateStaticAttribute"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate('ClassWithNonPublicAttributes');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that class "ClassWithNonPublicAttributes" does not have static attribute "privateStaticAttribute".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintClassNotHasStaticAttribute2()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::classHasStaticAttribute('privateStaticAttribute')
+ );
+
+ try {
+ $constraint->evaluate('ClassWithNonPublicAttributes', 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that class "ClassWithNonPublicAttributes" does not have static attribute "privateStaticAttribute".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintObjectHasAttribute()
+ {
+ $constraint = PHPUnit_Framework_Assert::objectHasAttribute('privateAttribute');
+
+ $this->assertTrue($constraint->evaluate(new ClassWithNonPublicAttributes, '', true));
+ $this->assertFalse($constraint->evaluate(new stdClass, '', true));
+ $this->assertEquals('has attribute "privateAttribute"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate(new stdClass);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that object of class "stdClass" has attribute "privateAttribute".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintObjectHasAttribute2()
+ {
+ $constraint = PHPUnit_Framework_Assert::objectHasAttribute('privateAttribute');
+
+ try {
+ $constraint->evaluate(new stdClass, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that object of class "stdClass" has attribute "privateAttribute".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintObjectNotHasAttribute()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::objectHasAttribute('privateAttribute')
+ );
+
+ $this->assertTrue($constraint->evaluate(new stdClass, '', true));
+ $this->assertFalse($constraint->evaluate(new ClassWithNonPublicAttributes, '', true));
+ $this->assertEquals('does not have attribute "privateAttribute"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate(new ClassWithNonPublicAttributes);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that object of class "ClassWithNonPublicAttributes" does not have attribute "privateAttribute".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintObjectNotHasAttribute2()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::objectHasAttribute('privateAttribute')
+ );
+
+ try {
+ $constraint->evaluate(new ClassWithNonPublicAttributes, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that object of class "ClassWithNonPublicAttributes" does not have attribute "privateAttribute".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintPCREMatch()
+ {
+ $constraint = PHPUnit_Framework_Assert::matchesRegularExpression('/foo/');
+
+ $this->assertFalse($constraint->evaluate('barbazbar', '', true));
+ $this->assertTrue($constraint->evaluate('barfoobar', '', true));
+ $this->assertEquals('matches PCRE pattern "/foo/"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate('barbazbar');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 'barbazbar' matches PCRE pattern "/foo/".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintPCREMatch2()
+ {
+ $constraint = PHPUnit_Framework_Assert::matchesRegularExpression('/foo/');
+
+ try {
+ $constraint->evaluate('barbazbar', 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that 'barbazbar' matches PCRE pattern "/foo/".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintPCRENotMatch()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::matchesRegularExpression('/foo/')
+ );
+
+ $this->assertTrue($constraint->evaluate('barbazbar', '', true));
+ $this->assertFalse($constraint->evaluate('barfoobar', '', true));
+ $this->assertEquals('does not match PCRE pattern "/foo/"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate('barfoobar');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 'barfoobar' does not match PCRE pattern "/foo/".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintPCRENotMatch2()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::matchesRegularExpression('/foo/')
+ );
+
+ try {
+ $constraint->evaluate('barfoobar', 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(<<<EOF
+custom message
+Failed asserting that 'barfoobar' does not match PCRE pattern "/foo/".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintStringMatches()
+ {
+ $constraint = PHPUnit_Framework_Assert::matches('*%c*');
+ $this->assertFalse($constraint->evaluate('**', '', true));
+ $this->assertTrue($constraint->evaluate('***', '', true));
+ $this->assertEquals('matches PCRE pattern "/^\*.\*$/s"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+ }
+
+ public function testConstraintStringMatches2()
+ {
+ $constraint = PHPUnit_Framework_Assert::matches('*%s*');
+ $this->assertFalse($constraint->evaluate('**', '', true));
+ $this->assertTrue($constraint->evaluate('***', '', true));
+ $this->assertEquals('matches PCRE pattern "/^\*[^\r\n]+\*$/s"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+ }
+
+ public function testConstraintStringMatches3()
+ {
+ $constraint = PHPUnit_Framework_Assert::matches('*%i*');
+ $this->assertFalse($constraint->evaluate('**', '', true));
+ $this->assertTrue($constraint->evaluate('*0*', '', true));
+ $this->assertEquals('matches PCRE pattern "/^\*[+-]?\d+\*$/s"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+ }
+
+ public function testConstraintStringMatches4()
+ {
+ $constraint = PHPUnit_Framework_Assert::matches('*%d*');
+ $this->assertFalse($constraint->evaluate('**', '', true));
+ $this->assertTrue($constraint->evaluate('*0*', '', true));
+ $this->assertEquals('matches PCRE pattern "/^\*\d+\*$/s"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+ }
+
+ public function testConstraintStringMatches5()
+ {
+ $constraint = PHPUnit_Framework_Assert::matches('*%x*');
+ $this->assertFalse($constraint->evaluate('**', '', true));
+ $this->assertTrue($constraint->evaluate('*0f0f0f*', '', true));
+ $this->assertEquals('matches PCRE pattern "/^\*[0-9a-fA-F]+\*$/s"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+ }
+
+ public function testConstraintStringMatches6()
+ {
+ $constraint = PHPUnit_Framework_Assert::matches('*%f*');
+ $this->assertFalse($constraint->evaluate('**', '', true));
+ $this->assertTrue($constraint->evaluate('*1.0*', '', true));
+ $this->assertEquals('matches PCRE pattern "/^\*[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?\*$/s"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+ }
+
+ public function testConstraintStringStartsWith()
+ {
+ $constraint = PHPUnit_Framework_Assert::stringStartsWith('prefix');
+
+ $this->assertFalse($constraint->evaluate('foo', '', true));
+ $this->assertTrue($constraint->evaluate('prefixfoo', '', true));
+ $this->assertEquals('starts with "prefix"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate('foo');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 'foo' starts with "prefix".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintStringStartsWith2()
+ {
+ $constraint = PHPUnit_Framework_Assert::stringStartsWith('prefix');
+
+ try {
+ $constraint->evaluate('foo', 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message\nFailed asserting that 'foo' starts with "prefix".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintStringStartsNotWith()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::stringStartsWith('prefix')
+ );
+
+ $this->assertTrue($constraint->evaluate('foo', '', true));
+ $this->assertFalse($constraint->evaluate('prefixfoo', '', true));
+ $this->assertEquals('starts not with "prefix"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate('prefixfoo');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 'prefixfoo' starts not with "prefix".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintStringStartsNotWith2()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::stringStartsWith('prefix')
+ );
+
+ try {
+ $constraint->evaluate('prefixfoo', 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message
+Failed asserting that 'prefixfoo' starts not with "prefix".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintStringContains()
+ {
+ $constraint = PHPUnit_Framework_Assert::stringContains('foo');
+
+ $this->assertFalse($constraint->evaluate('barbazbar', '', true));
+ $this->assertTrue($constraint->evaluate('barfoobar', '', true));
+ $this->assertEquals('contains "foo"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate('barbazbar');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 'barbazbar' contains "foo".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintStringContainsWhenIgnoreCase()
+ {
+ $constraint = PHPUnit_Framework_Assert::stringContains('oryginał', true);
+
+ $this->assertFalse($constraint->evaluate('oryginal', '', true));
+ $this->assertTrue($constraint->evaluate('ORYGINAŁ', '', true));
+ $this->assertTrue($constraint->evaluate('oryginał', '', true));
+ $this->assertEquals('contains "oryginał"', $constraint->toString());
+ $this->assertEquals(1, count($constraint));
+
+ try {
+ $constraint->evaluate('oryginal');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 'oryginal' contains "oryginał".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintStringContainsForUtf8StringWhenNotIgnoreCase()
+ {
+ $constraint = PHPUnit_Framework_Assert::stringContains('oryginał', false);
+
+ $this->assertFalse($constraint->evaluate('oryginal', '', true));
+ $this->assertFalse($constraint->evaluate('ORYGINAŁ', '', true));
+ $this->assertTrue($constraint->evaluate('oryginał', '', true));
+ $this->assertEquals('contains "oryginał"', $constraint->toString());
+ $this->assertEquals(1, count($constraint));
+
+ try {
+ $constraint->evaluate('oryginal');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 'oryginal' contains "oryginał".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintStringContains2()
+ {
+ $constraint = PHPUnit_Framework_Assert::stringContains('foo');
+
+ try {
+ $constraint->evaluate('barbazbar', 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message
+Failed asserting that 'barbazbar' contains "foo".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintStringNotContains()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::stringContains('foo')
+ );
+
+ $this->assertTrue($constraint->evaluate('barbazbar', '', true));
+ $this->assertFalse($constraint->evaluate('barfoobar', '', true));
+ $this->assertEquals('does not contain "foo"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate('barfoobar');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 'barfoobar' does not contain "foo".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintStringNotContainsWhenIgnoreCase()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::stringContains('oryginał')
+ );
+
+ $this->assertTrue($constraint->evaluate('original', '', true));
+ $this->assertFalse($constraint->evaluate('ORYGINAŁ', '', true));
+ $this->assertFalse($constraint->evaluate('oryginał', '', true));
+ $this->assertEquals('does not contain "oryginał"', $constraint->toString());
+ $this->assertEquals(1, count($constraint));
+
+ try {
+ $constraint->evaluate('ORYGINAŁ');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 'ORYGINAŁ' does not contain "oryginał".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintStringNotContainsForUtf8StringWhenNotIgnoreCase()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::stringContains('oryginał', false)
+ );
+
+ $this->assertTrue($constraint->evaluate('original', '', true));
+ $this->assertTrue($constraint->evaluate('ORYGINAŁ', '', true));
+ $this->assertFalse($constraint->evaluate('oryginał', '', true));
+ $this->assertEquals('does not contain "oryginał"', $constraint->toString());
+ $this->assertEquals(1, count($constraint));
+
+ try {
+ $constraint->evaluate('oryginał');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 'oryginał' does not contain "oryginał".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintStringNotContains2()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::stringContains('foo')
+ );
+
+ try {
+ $constraint->evaluate('barfoobar', 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message
+Failed asserting that 'barfoobar' does not contain "foo".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintStringEndsWith()
+ {
+ $constraint = PHPUnit_Framework_Assert::stringEndsWith('suffix');
+
+ $this->assertFalse($constraint->evaluate('foo', '', true));
+ $this->assertTrue($constraint->evaluate('foosuffix', '', true));
+ $this->assertEquals('ends with "suffix"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate('foo');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 'foo' ends with "suffix".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintStringEndsWith2()
+ {
+ $constraint = PHPUnit_Framework_Assert::stringEndsWith('suffix');
+
+ try {
+ $constraint->evaluate('foo', 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message
+Failed asserting that 'foo' ends with "suffix".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintStringEndsNotWith()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::stringEndsWith('suffix')
+ );
+
+ $this->assertTrue($constraint->evaluate('foo', '', true));
+ $this->assertFalse($constraint->evaluate('foosuffix', '', true));
+ $this->assertEquals('ends not with "suffix"', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate('foosuffix');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that 'foosuffix' ends not with "suffix".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintStringEndsNotWith2()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::stringEndsWith('suffix')
+ );
+
+ try {
+ $constraint->evaluate('foosuffix', 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message
+Failed asserting that 'foosuffix' ends not with "suffix".
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintArrayContainsCheckForObjectIdentity()
+ {
+ // Check for primitive type.
+ $constraint = new PHPUnit_Framework_Constraint_TraversableContains('foo', true, true);
+
+ $this->assertFalse($constraint->evaluate([0], '', true));
+ $this->assertFalse($constraint->evaluate([true], '', true));
+
+ // Default case.
+ $constraint = new PHPUnit_Framework_Constraint_TraversableContains('foo');
+
+ $this->assertTrue($constraint->evaluate([0], '', true));
+ $this->assertTrue($constraint->evaluate([true], '', true));
+ }
+
+ public function testConstraintArrayContains()
+ {
+ $constraint = new PHPUnit_Framework_Constraint_TraversableContains('foo');
+
+ $this->assertFalse($constraint->evaluate(['bar'], '', true));
+ $this->assertTrue($constraint->evaluate(['foo'], '', true));
+ $this->assertEquals("contains 'foo'", $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate(['bar']);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that an array contains 'foo'.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintArrayContains2()
+ {
+ $constraint = new PHPUnit_Framework_Constraint_TraversableContains('foo');
+
+ try {
+ $constraint->evaluate(['bar'], 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message
+Failed asserting that an array contains 'foo'.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintArrayNotContains()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ new PHPUnit_Framework_Constraint_TraversableContains('foo')
+ );
+
+ $this->assertTrue($constraint->evaluate(['bar'], '', true));
+ $this->assertFalse($constraint->evaluate(['foo'], '', true));
+ $this->assertEquals("does not contain 'foo'", $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate(['foo']);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that an array does not contain 'foo'.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintArrayNotContains2()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ new PHPUnit_Framework_Constraint_TraversableContains('foo')
+ );
+
+ try {
+ $constraint->evaluate(['foo'], 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message
+Failed asserting that an array does not contain 'foo'.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintSplObjectStorageContains()
+ {
+ $object = new StdClass;
+ $constraint = new PHPUnit_Framework_Constraint_TraversableContains($object);
+ $this->assertStringMatchesFormat('contains stdClass Object &%s ()', $constraint->toString());
+
+ $storage = new SplObjectStorage;
+ $this->assertFalse($constraint->evaluate($storage, '', true));
+
+ $storage->attach($object);
+ $this->assertTrue($constraint->evaluate($storage, '', true));
+
+ try {
+ $constraint->evaluate(new SplObjectStorage);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertStringMatchesFormat(
+ <<<EOF
+Failed asserting that a traversable contains stdClass Object &%x ().
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintSplObjectStorageContains2()
+ {
+ $object = new StdClass;
+ $constraint = new PHPUnit_Framework_Constraint_TraversableContains($object);
+
+ try {
+ $constraint->evaluate(new SplObjectStorage, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertStringMatchesFormat(
+ <<<EOF
+custom message
+Failed asserting that a traversable contains stdClass Object &%x ().
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAttributeEqualTo()
+ {
+ $object = new ClassWithNonPublicAttributes;
+ $constraint = PHPUnit_Framework_Assert::attributeEqualTo('foo', 1);
+
+ $this->assertTrue($constraint->evaluate($object, '', true));
+ $this->assertEquals('attribute "foo" is equal to 1', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ $constraint = PHPUnit_Framework_Assert::attributeEqualTo('foo', 2);
+
+ $this->assertFalse($constraint->evaluate($object, '', true));
+
+ try {
+ $constraint->evaluate($object);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that attribute "foo" is equal to 2.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAttributeEqualTo2()
+ {
+ $object = new ClassWithNonPublicAttributes;
+ $constraint = PHPUnit_Framework_Assert::attributeEqualTo('foo', 2);
+
+ try {
+ $constraint->evaluate($object, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message\nFailed asserting that attribute "foo" is equal to 2.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAttributeNotEqualTo()
+ {
+ $object = new ClassWithNonPublicAttributes;
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::attributeEqualTo('foo', 2)
+ );
+
+ $this->assertTrue($constraint->evaluate($object, '', true));
+ $this->assertEquals('attribute "foo" is not equal to 2', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::attributeEqualTo('foo', 1)
+ );
+
+ $this->assertFalse($constraint->evaluate($object, '', true));
+
+ try {
+ $constraint->evaluate($object);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that attribute "foo" is not equal to 1.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testAttributeNotEqualTo2()
+ {
+ $object = new ClassWithNonPublicAttributes;
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ PHPUnit_Framework_Assert::attributeEqualTo('foo', 1)
+ );
+
+ try {
+ $constraint->evaluate($object, 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message\nFailed asserting that attribute "foo" is not equal to 1.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsEmpty()
+ {
+ $constraint = new PHPUnit_Framework_Constraint_IsEmpty;
+
+ $this->assertFalse($constraint->evaluate(['foo'], '', true));
+ $this->assertTrue($constraint->evaluate([], '', true));
+ $this->assertFalse($constraint->evaluate(new ArrayObject(['foo']), '', true));
+ $this->assertTrue($constraint->evaluate(new ArrayObject([]), '', true));
+ $this->assertEquals('is empty', $constraint->toString());
+ $this->assertCount(1, $constraint);
+
+ try {
+ $constraint->evaluate(['foo']);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that an array is empty.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintIsEmpty2()
+ {
+ $constraint = new PHPUnit_Framework_Constraint_IsEmpty;
+
+ try {
+ $constraint->evaluate(['foo'], 'custom message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+custom message\nFailed asserting that an array is empty.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintCountWithAnArray()
+ {
+ $constraint = new PHPUnit_Framework_Constraint_Count(5);
+
+ $this->assertTrue($constraint->evaluate([1, 2, 3, 4, 5], '', true));
+ $this->assertFalse($constraint->evaluate([1, 2, 3, 4], '', true));
+ }
+
+ public function testConstraintCountWithAnIteratorWhichDoesNotImplementCountable()
+ {
+ $constraint = new PHPUnit_Framework_Constraint_Count(5);
+
+ $this->assertTrue($constraint->evaluate(new TestIterator([1, 2, 3, 4, 5]), '', true));
+ $this->assertFalse($constraint->evaluate(new TestIterator([1, 2, 3, 4]), '', true));
+ }
+
+ public function testConstraintCountWithAnObjectImplementingCountable()
+ {
+ $constraint = new PHPUnit_Framework_Constraint_Count(5);
+
+ $this->assertTrue($constraint->evaluate(new ArrayObject([1, 2, 3, 4, 5]), '', true));
+ $this->assertFalse($constraint->evaluate(new ArrayObject([1, 2, 3, 4]), '', true));
+ }
+
+ public function testConstraintCountFailing()
+ {
+ $constraint = new PHPUnit_Framework_Constraint_Count(5);
+
+ try {
+ $constraint->evaluate([1, 2]);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that actual size 2 matches expected size 5.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintNotCountFailing()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ new PHPUnit_Framework_Constraint_Count(2)
+ );
+
+ try {
+ $constraint->evaluate([1, 2]);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that actual size 2 does not match expected size 2.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintSameSizeWithAnArray()
+ {
+ $constraint = new PHPUnit_Framework_Constraint_SameSize([1, 2, 3, 4, 5]);
+
+ $this->assertTrue($constraint->evaluate([6, 7, 8, 9, 10], '', true));
+ $this->assertFalse($constraint->evaluate([1, 2, 3, 4], '', true));
+ }
+
+ public function testConstraintSameSizeWithAnIteratorWhichDoesNotImplementCountable()
+ {
+ $constraint = new PHPUnit_Framework_Constraint_SameSize(new TestIterator([1, 2, 3, 4, 5]));
+
+ $this->assertTrue($constraint->evaluate(new TestIterator([6, 7, 8, 9, 10]), '', true));
+ $this->assertFalse($constraint->evaluate(new TestIterator([1, 2, 3, 4]), '', true));
+ }
+
+ public function testConstraintSameSizeWithAnObjectImplementingCountable()
+ {
+ $constraint = new PHPUnit_Framework_Constraint_SameSize(new ArrayObject([1, 2, 3, 4, 5]));
+
+ $this->assertTrue($constraint->evaluate(new ArrayObject([6, 7, 8, 9, 10]), '', true));
+ $this->assertFalse($constraint->evaluate(new ArrayObject([1, 2, 3, 4]), '', true));
+ }
+
+ public function testConstraintSameSizeFailing()
+ {
+ $constraint = new PHPUnit_Framework_Constraint_SameSize([1, 2, 3, 4, 5]);
+
+ try {
+ $constraint->evaluate([1, 2]);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that actual size 2 matches expected size 5.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintNotSameSizeFailing()
+ {
+ $constraint = PHPUnit_Framework_Assert::logicalNot(
+ new PHPUnit_Framework_Constraint_SameSize([1, 2])
+ );
+
+ try {
+ $constraint->evaluate([3, 4]);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that actual size 2 does not match expected size 2.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testConstraintException()
+ {
+ $constraint = new PHPUnit_Framework_Constraint_Exception('FoobarException');
+ $exception = new DummyException('Test');
+ $stackTrace = PHPUnit_Util_Filter::getFilteredStacktrace($exception);
+
+ try {
+ $constraint->evaluate($exception);
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $this->assertEquals(
+ <<<EOF
+Failed asserting that exception of type "DummyException" matches expected exception "FoobarException". Message was: "Test" at
+$stackTrace.
+
+EOF
+ ,
+ PHPUnit_Framework_TestFailure::exceptionToString($e)
+ );
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * Removes spaces in front of newlines
+ *
+ * @param string $string
+ *
+ * @return string
+ */
+ private function trimnl($string)
+ {
+ return preg_replace('/[ ]*\n/', "\n", $string);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Framework/SuiteTest.php b/vendor/phpunit/phpunit/tests/Framework/SuiteTest.php
new file mode 100644
index 0000000..f53af3c
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Framework/SuiteTest.php
@@ -0,0 +1,269 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'BeforeAndAfterTest.php';
+require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'BeforeClassAndAfterClassTest.php';
+require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'TestWithTest.php';
+require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'BeforeClassWithOnlyDataProviderTest.php';
+require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'DataProviderSkippedTest.php';
+require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'DataProviderDependencyTest.php';
+require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'DataProviderIncompleteTest.php';
+require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'InheritedTestCase.php';
+require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'NoTestCaseClass.php';
+require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'NoTestCases.php';
+require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'NotPublicTestCase.php';
+require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'NotVoidTestCase.php';
+require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'OverrideTestCase.php';
+require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'RequirementsClassBeforeClassHookTest.php';
+
+class Framework_SuiteTest extends PHPUnit_Framework_TestCase
+{
+ protected $result;
+
+ protected function setUp()
+ {
+ $this->result = new PHPUnit_Framework_TestResult;
+ }
+
+ public static function suite()
+ {
+ $suite = new PHPUnit_Framework_TestSuite;
+
+ $suite->addTest(new self('testAddTestSuite'));
+ $suite->addTest(new self('testInheritedTests'));
+ $suite->addTest(new self('testNoTestCases'));
+ $suite->addTest(new self('testNoTestCaseClass'));
+ $suite->addTest(new self('testNotExistingTestCase'));
+ $suite->addTest(new self('testNotPublicTestCase'));
+ $suite->addTest(new self('testNotVoidTestCase'));
+ $suite->addTest(new self('testOneTestCase'));
+ $suite->addTest(new self('testShadowedTests'));
+ $suite->addTest(new self('testBeforeClassAndAfterClassAnnotations'));
+ $suite->addTest(new self('testBeforeClassWithDataProviders'));
+ $suite->addTest(new self('testBeforeAnnotation'));
+ $suite->addTest(new self('testTestWithAnnotation'));
+ $suite->addTest(new self('testSkippedTestDataProvider'));
+ $suite->addTest(new self('testTestDataProviderDependency'));
+ $suite->addTest(new self('testIncompleteTestDataProvider'));
+ $suite->addTest(new self('testRequirementsBeforeClassHook'));
+ $suite->addTest(new self('testDontSkipInheritedClass'));
+
+ return $suite;
+ }
+
+ public function testAddTestSuite()
+ {
+ $suite = new PHPUnit_Framework_TestSuite(
+ 'OneTestCase'
+ );
+
+ $suite->run($this->result);
+
+ $this->assertCount(1, $this->result);
+ }
+
+ public function testInheritedTests()
+ {
+ $suite = new PHPUnit_Framework_TestSuite(
+ 'InheritedTestCase'
+ );
+
+ $suite->run($this->result);
+
+ $this->assertTrue($this->result->wasSuccessful());
+ $this->assertCount(2, $this->result);
+ }
+
+ public function testNoTestCases()
+ {
+ $suite = new PHPUnit_Framework_TestSuite(
+ 'NoTestCases'
+ );
+
+ $suite->run($this->result);
+
+ $this->assertTrue(!$this->result->wasSuccessful());
+ $this->assertEquals(0, $this->result->failureCount());
+ $this->assertEquals(1, $this->result->warningCount());
+ $this->assertCount(1, $this->result);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testNoTestCaseClass()
+ {
+ $suite = new PHPUnit_Framework_TestSuite('NoTestCaseClass');
+ }
+
+ public function testNotExistingTestCase()
+ {
+ $suite = new self('notExistingMethod');
+
+ $suite->run($this->result);
+
+ $this->assertEquals(0, $this->result->errorCount());
+ $this->assertEquals(1, $this->result->failureCount());
+ $this->assertCount(1, $this->result);
+ }
+
+ public function testNotPublicTestCase()
+ {
+ $suite = new PHPUnit_Framework_TestSuite(
+ 'NotPublicTestCase'
+ );
+
+ $this->assertCount(2, $suite);
+ }
+
+ public function testNotVoidTestCase()
+ {
+ $suite = new PHPUnit_Framework_TestSuite(
+ 'NotVoidTestCase'
+ );
+
+ $this->assertCount(1, $suite);
+ }
+
+ public function testOneTestCase()
+ {
+ $suite = new PHPUnit_Framework_TestSuite(
+ 'OneTestCase'
+ );
+
+ $suite->run($this->result);
+
+ $this->assertEquals(0, $this->result->errorCount());
+ $this->assertEquals(0, $this->result->failureCount());
+ $this->assertCount(1, $this->result);
+ $this->assertTrue($this->result->wasSuccessful());
+ }
+
+ public function testShadowedTests()
+ {
+ $suite = new PHPUnit_Framework_TestSuite(
+ 'OverrideTestCase'
+ );
+
+ $suite->run($this->result);
+
+ $this->assertCount(1, $this->result);
+ }
+
+ public function testBeforeClassAndAfterClassAnnotations()
+ {
+ $suite = new PHPUnit_Framework_TestSuite(
+ 'BeforeClassAndAfterClassTest'
+ );
+
+ BeforeClassAndAfterClassTest::resetProperties();
+ $suite->run($this->result);
+
+ $this->assertEquals(1, BeforeClassAndAfterClassTest::$beforeClassWasRun, '@beforeClass method was not run once for the whole suite.');
+ $this->assertEquals(1, BeforeClassAndAfterClassTest::$afterClassWasRun, '@afterClass method was not run once for the whole suite.');
+ }
+
+ public function testBeforeClassWithDataProviders()
+ {
+ $suite = new PHPUnit_Framework_TestSuite(
+ 'BeforeClassWithOnlyDataProviderTest'
+ );
+
+ BeforeClassWithOnlyDataProviderTest::resetProperties();
+ $suite->run($this->result);
+
+ $this->assertTrue(BeforeClassWithOnlyDataProviderTest::$setUpBeforeClassWasCalled, 'setUpBeforeClass method was not run.');
+ $this->assertTrue(BeforeClassWithOnlyDataProviderTest::$beforeClassWasCalled, '@beforeClass method was not run.');
+ }
+
+ public function testBeforeAnnotation()
+ {
+ $test = new PHPUnit_Framework_TestSuite(
+ 'BeforeAndAfterTest'
+ );
+
+ BeforeAndAfterTest::resetProperties();
+ $result = $test->run();
+
+ $this->assertEquals(2, BeforeAndAfterTest::$beforeWasRun);
+ $this->assertEquals(2, BeforeAndAfterTest::$afterWasRun);
+ }
+
+ public function testTestWithAnnotation()
+ {
+ $test = new PHPUnit_Framework_TestSuite(
+ 'TestWithTest'
+ );
+
+ BeforeAndAfterTest::resetProperties();
+ $result = $test->run();
+
+ $this->assertCount(4, $result->passed());
+ }
+
+ public function testSkippedTestDataProvider()
+ {
+ $suite = new PHPUnit_Framework_TestSuite('DataProviderSkippedTest');
+
+ $suite->run($this->result);
+
+ $this->assertEquals(3, $this->result->count());
+ $this->assertEquals(1, $this->result->skippedCount());
+ }
+
+ public function testTestDataProviderDependency()
+ {
+ $suite = new PHPUnit_Framework_TestSuite('DataProviderDependencyTest');
+
+ $suite->run($this->result);
+
+ $skipped = $this->result->skipped();
+ $lastSkippedResult = array_pop($skipped);
+ $message = $lastSkippedResult->thrownException()->getMessage();
+
+ $this->assertContains('Test for DataProviderDependencyTest::testDependency skipped by data provider', $message);
+ }
+
+ public function testIncompleteTestDataProvider()
+ {
+ $suite = new PHPUnit_Framework_TestSuite('DataProviderIncompleteTest');
+
+ $suite->run($this->result);
+
+ $this->assertEquals(3, $this->result->count());
+ $this->assertEquals(1, $this->result->notImplementedCount());
+ }
+
+ public function testRequirementsBeforeClassHook()
+ {
+ $suite = new PHPUnit_Framework_TestSuite(
+ 'RequirementsClassBeforeClassHookTest'
+ );
+
+ $suite->run($this->result);
+
+ $this->assertEquals(0, $this->result->errorCount());
+ $this->assertEquals(1, $this->result->skippedCount());
+ }
+
+ public function testDontSkipInheritedClass()
+ {
+ $suite = new PHPUnit_Framework_TestSuite(
+ 'DontSkipInheritedClass'
+ );
+
+ $dir = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'Inheritance' . DIRECTORY_SEPARATOR;
+
+ $suite->addTestFile($dir . 'InheritanceA.php');
+ $suite->addTestFile($dir . 'InheritanceB.php');
+ $result = $suite->run();
+ $this->assertCount(2, $result);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Framework/TestCaseTest.php b/vendor/phpunit/phpunit/tests/Framework/TestCaseTest.php
new file mode 100644
index 0000000..ae2870c
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Framework/TestCaseTest.php
@@ -0,0 +1,690 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'NoArgTestCaseTest.php';
+require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'Singleton.php';
+require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'Mockable.php';
+
+$GLOBALS['a'] = 'a';
+$_ENV['b'] = 'b';
+$_POST['c'] = 'c';
+$_GET['d'] = 'd';
+$_COOKIE['e'] = 'e';
+$_SERVER['f'] = 'f';
+$_FILES['g'] = 'g';
+$_REQUEST['h'] = 'h';
+$GLOBALS['i'] = 'i';
+
+class Framework_TestCaseTest extends PHPUnit_Framework_TestCase
+{
+ protected $backupGlobalsBlacklist = ['i', 'singleton'];
+
+ /**
+ * Used be testStaticAttributesBackupPre
+ */
+ protected static $testStatic = 0;
+
+ public function testCaseToString()
+ {
+ $this->assertEquals(
+ 'Framework_TestCaseTest::testCaseToString',
+ $this->toString()
+ );
+ }
+
+ public function testSuccess()
+ {
+ $test = new Success;
+ $result = $test->run();
+
+ $this->assertEquals(PHPUnit_Runner_BaseTestRunner::STATUS_PASSED, $test->getStatus());
+ $this->assertEquals(0, $result->errorCount());
+ $this->assertEquals(0, $result->failureCount());
+ $this->assertEquals(0, $result->skippedCount());
+ $this->assertCount(1, $result);
+ }
+
+ public function testFailure()
+ {
+ $test = new Failure;
+ $result = $test->run();
+
+ $this->assertEquals(PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE, $test->getStatus());
+ $this->assertEquals(0, $result->errorCount());
+ $this->assertEquals(1, $result->failureCount());
+ $this->assertEquals(0, $result->skippedCount());
+ $this->assertCount(1, $result);
+ }
+
+ public function testError()
+ {
+ $test = new TestError;
+ $result = $test->run();
+
+ $this->assertEquals(PHPUnit_Runner_BaseTestRunner::STATUS_ERROR, $test->getStatus());
+ $this->assertEquals(1, $result->errorCount());
+ $this->assertEquals(0, $result->failureCount());
+ $this->assertEquals(0, $result->skippedCount());
+ $this->assertCount(1, $result);
+ }
+
+ public function testSkipped()
+ {
+ $test = new TestSkipped();
+ $result = $test->run();
+
+ $this->assertEquals(PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED, $test->getStatus());
+ $this->assertEquals('Skipped test', $test->getStatusMessage());
+ $this->assertEquals(0, $result->errorCount());
+ $this->assertEquals(0, $result->failureCount());
+ $this->assertEquals(1, $result->skippedCount());
+ $this->assertCount(1, $result);
+ }
+
+ public function testIncomplete()
+ {
+ $test = new TestIncomplete();
+ $result = $test->run();
+
+ $this->assertEquals(PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE, $test->getStatus());
+ $this->assertEquals('Incomplete test', $test->getStatusMessage());
+ $this->assertEquals(0, $result->errorCount());
+ $this->assertEquals(0, $result->failureCount());
+ $this->assertEquals(0, $result->skippedCount());
+ $this->assertCount(1, $result);
+ }
+
+ public function testExceptionInSetUp()
+ {
+ $test = new ExceptionInSetUpTest('testSomething');
+ $result = $test->run();
+
+ $this->assertTrue($test->setUp);
+ $this->assertFalse($test->assertPreConditions);
+ $this->assertFalse($test->testSomething);
+ $this->assertFalse($test->assertPostConditions);
+ $this->assertTrue($test->tearDown);
+ }
+
+ public function testExceptionInAssertPreConditions()
+ {
+ $test = new ExceptionInAssertPreConditionsTest('testSomething');
+ $result = $test->run();
+
+ $this->assertTrue($test->setUp);
+ $this->assertTrue($test->assertPreConditions);
+ $this->assertFalse($test->testSomething);
+ $this->assertFalse($test->assertPostConditions);
+ $this->assertTrue($test->tearDown);
+ }
+
+ public function testExceptionInTest()
+ {
+ $test = new ExceptionInTest('testSomething');
+ $result = $test->run();
+
+ $this->assertTrue($test->setUp);
+ $this->assertTrue($test->assertPreConditions);
+ $this->assertTrue($test->testSomething);
+ $this->assertFalse($test->assertPostConditions);
+ $this->assertTrue($test->tearDown);
+ }
+
+ public function testExceptionInAssertPostConditions()
+ {
+ $test = new ExceptionInAssertPostConditionsTest('testSomething');
+ $result = $test->run();
+
+ $this->assertTrue($test->setUp);
+ $this->assertTrue($test->assertPreConditions);
+ $this->assertTrue($test->testSomething);
+ $this->assertTrue($test->assertPostConditions);
+ $this->assertTrue($test->tearDown);
+ }
+
+ public function testExceptionInTearDown()
+ {
+ $test = new ExceptionInTearDownTest('testSomething');
+ $result = $test->run();
+
+ $this->assertTrue($test->setUp);
+ $this->assertTrue($test->assertPreConditions);
+ $this->assertTrue($test->testSomething);
+ $this->assertTrue($test->assertPostConditions);
+ $this->assertTrue($test->tearDown);
+ $this->assertEquals(PHPUnit_Runner_BaseTestRunner::STATUS_ERROR, $test->getStatus());
+ }
+
+ public function testNoArgTestCasePasses()
+ {
+ $result = new PHPUnit_Framework_TestResult;
+ $t = new PHPUnit_Framework_TestSuite('NoArgTestCaseTest');
+
+ $t->run($result);
+
+ $this->assertCount(1, $result);
+ $this->assertEquals(0, $result->failureCount());
+ $this->assertEquals(0, $result->errorCount());
+ }
+
+ public function testWasRun()
+ {
+ $test = new WasRun;
+ $test->run();
+
+ $this->assertTrue($test->wasRun);
+ }
+
+ public function testException()
+ {
+ $test = new ThrowExceptionTestCase('test');
+ $test->expectException(RuntimeException::class);
+
+ $result = $test->run();
+
+ $this->assertCount(1, $result);
+ $this->assertTrue($result->wasSuccessful());
+ }
+
+ public function testExceptionWithEmptyMessage()
+ {
+ $test = new ThrowExceptionTestCase('test');
+ $test->expectException(RuntimeException::class, '');
+
+ $result = $test->run();
+
+ $this->assertCount(1, $result);
+ $this->assertTrue($result->wasSuccessful());
+ }
+
+ public function testExceptionWithNullMessage()
+ {
+ $test = new ThrowExceptionTestCase('test');
+ $test->expectException(RuntimeException::class, null);
+
+ $result = $test->run();
+
+ $this->assertCount(1, $result);
+ $this->assertTrue($result->wasSuccessful());
+ }
+
+ public function testExceptionWithMessage()
+ {
+ $test = new ThrowExceptionTestCase('test');
+ $test->expectException(RuntimeException::class);
+ $test->expectExceptionMessage('A runtime error occurred');
+
+ $result = $test->run();
+
+ $this->assertCount(1, $result);
+ $this->assertTrue($result->wasSuccessful());
+ }
+
+ public function testExceptionWithWrongMessage()
+ {
+ $test = new ThrowExceptionTestCase('test');
+ $test->expectException(RuntimeException::class);
+ $test->expectExceptionMessage('A logic error occurred');
+
+ $result = $test->run();
+
+ $this->assertEquals(1, $result->failureCount());
+ $this->assertCount(1, $result);
+ $this->assertEquals(
+ "Failed asserting that exception message 'A runtime error occurred' contains 'A logic error occurred'.",
+ $test->getStatusMessage()
+ );
+ }
+
+ public function testExceptionWithRegexpMessage()
+ {
+ $test = new ThrowExceptionTestCase('test');
+ $test->expectException(RuntimeException::class);
+ $test->expectExceptionMessageRegExp('/runtime .*? occurred/');
+
+ $result = $test->run();
+
+ $this->assertCount(1, $result);
+ $this->assertTrue($result->wasSuccessful());
+ }
+
+ public function testExceptionWithWrongRegexpMessage()
+ {
+ $test = new ThrowExceptionTestCase('test');
+ $test->expectException(RuntimeException::class);
+ $test->expectExceptionMessageRegExp('/logic .*? occurred/');
+
+ $result = $test->run();
+
+ $this->assertEquals(1, $result->failureCount());
+ $this->assertCount(1, $result);
+ $this->assertEquals(
+ "Failed asserting that exception message 'A runtime error occurred' matches '/logic .*? occurred/'.",
+ $test->getStatusMessage()
+ );
+ }
+
+ public function testExceptionWithInvalidRegexpMessage()
+ {
+ $test = new ThrowExceptionTestCase('test');
+ $test->expectException(RuntimeException::class);
+ $test->expectExceptionMessageRegExp('#runtime .*? occurred/');
+
+ $test->run();
+
+ $this->assertEquals(
+ "Invalid expected exception message regex given: '#runtime .*? occurred/'",
+ $test->getStatusMessage()
+ );
+ }
+
+ public function testNoException()
+ {
+ $test = new ThrowNoExceptionTestCase('test');
+ $test->expectException(RuntimeException::class);
+
+ $result = $test->run();
+
+ $this->assertEquals(1, $result->failureCount());
+ $this->assertCount(1, $result);
+ }
+
+ public function testWrongException()
+ {
+ $test = new ThrowExceptionTestCase('test');
+ $test->expectException(InvalidArgumentException::class);
+
+ $result = $test->run();
+
+ $this->assertEquals(1, $result->failureCount());
+ $this->assertCount(1, $result);
+ }
+
+ /**
+ * @backupGlobals enabled
+ */
+ public function testGlobalsBackupPre()
+ {
+ global $a;
+ global $i;
+
+ $this->assertEquals('a', $a);
+ $this->assertEquals('a', $GLOBALS['a']);
+ $this->assertEquals('b', $_ENV['b']);
+ $this->assertEquals('c', $_POST['c']);
+ $this->assertEquals('d', $_GET['d']);
+ $this->assertEquals('e', $_COOKIE['e']);
+ $this->assertEquals('f', $_SERVER['f']);
+ $this->assertEquals('g', $_FILES['g']);
+ $this->assertEquals('h', $_REQUEST['h']);
+ $this->assertEquals('i', $i);
+ $this->assertEquals('i', $GLOBALS['i']);
+
+ $GLOBALS['a'] = 'aa';
+ $GLOBALS['foo'] = 'bar';
+ $_ENV['b'] = 'bb';
+ $_POST['c'] = 'cc';
+ $_GET['d'] = 'dd';
+ $_COOKIE['e'] = 'ee';
+ $_SERVER['f'] = 'ff';
+ $_FILES['g'] = 'gg';
+ $_REQUEST['h'] = 'hh';
+ $GLOBALS['i'] = 'ii';
+
+ $this->assertEquals('aa', $a);
+ $this->assertEquals('aa', $GLOBALS['a']);
+ $this->assertEquals('bar', $GLOBALS['foo']);
+ $this->assertEquals('bb', $_ENV['b']);
+ $this->assertEquals('cc', $_POST['c']);
+ $this->assertEquals('dd', $_GET['d']);
+ $this->assertEquals('ee', $_COOKIE['e']);
+ $this->assertEquals('ff', $_SERVER['f']);
+ $this->assertEquals('gg', $_FILES['g']);
+ $this->assertEquals('hh', $_REQUEST['h']);
+ $this->assertEquals('ii', $i);
+ $this->assertEquals('ii', $GLOBALS['i']);
+ }
+
+ public function testGlobalsBackupPost()
+ {
+ global $a;
+ global $i;
+
+ $this->assertEquals('a', $a);
+ $this->assertEquals('a', $GLOBALS['a']);
+ $this->assertEquals('b', $_ENV['b']);
+ $this->assertEquals('c', $_POST['c']);
+ $this->assertEquals('d', $_GET['d']);
+ $this->assertEquals('e', $_COOKIE['e']);
+ $this->assertEquals('f', $_SERVER['f']);
+ $this->assertEquals('g', $_FILES['g']);
+ $this->assertEquals('h', $_REQUEST['h']);
+ $this->assertEquals('ii', $i);
+ $this->assertEquals('ii', $GLOBALS['i']);
+
+ $this->assertArrayNotHasKey('foo', $GLOBALS);
+ }
+
+ /**
+ * @backupGlobals enabled
+ * @backupStaticAttributes enabled
+ */
+ public function testStaticAttributesBackupPre()
+ {
+ $GLOBALS['singleton'] = Singleton::getInstance();
+ self::$testStatic = 123;
+ }
+
+ /**
+ * @depends testStaticAttributesBackupPre
+ */
+ public function testStaticAttributesBackupPost()
+ {
+ $this->assertNotSame($GLOBALS['singleton'], Singleton::getInstance());
+ $this->assertSame(0, self::$testStatic);
+ }
+
+ public function testIsInIsolationReturnsFalse()
+ {
+ $test = new IsolationTest('testIsInIsolationReturnsFalse');
+ $result = $test->run();
+
+ $this->assertCount(1, $result);
+ $this->assertTrue($result->wasSuccessful());
+ }
+
+ public function testIsInIsolationReturnsTrue()
+ {
+ $test = new IsolationTest('testIsInIsolationReturnsTrue');
+ $test->setRunTestInSeparateProcess(true);
+ $result = $test->run();
+
+ $this->assertCount(1, $result);
+ $this->assertTrue($result->wasSuccessful());
+ }
+
+ public function testExpectOutputStringFooActualFoo()
+ {
+ $test = new OutputTestCase('testExpectOutputStringFooActualFoo');
+ $result = $test->run();
+
+ $this->assertCount(1, $result);
+ $this->assertTrue($result->wasSuccessful());
+ }
+
+ public function testExpectOutputStringFooActualBar()
+ {
+ $test = new OutputTestCase('testExpectOutputStringFooActualBar');
+ $result = $test->run();
+
+ $this->assertCount(1, $result);
+ $this->assertFalse($result->wasSuccessful());
+ }
+
+ public function testExpectOutputRegexFooActualFoo()
+ {
+ $test = new OutputTestCase('testExpectOutputRegexFooActualFoo');
+ $result = $test->run();
+
+ $this->assertCount(1, $result);
+ $this->assertTrue($result->wasSuccessful());
+ }
+
+ public function testExpectOutputRegexFooActualBar()
+ {
+ $test = new OutputTestCase('testExpectOutputRegexFooActualBar');
+ $result = $test->run();
+
+ $this->assertCount(1, $result);
+ $this->assertFalse($result->wasSuccessful());
+ }
+
+ public function testSkipsIfRequiresHigherVersionOfPHPUnit()
+ {
+ $test = new RequirementsTest('testAlwaysSkip');
+ $result = $test->run();
+
+ $this->assertEquals(1, $result->skippedCount());
+ $this->assertEquals(
+ 'PHPUnit >= 1111111 is required.',
+ $test->getStatusMessage()
+ );
+ }
+
+ public function testSkipsIfRequiresHigherVersionOfPHP()
+ {
+ $test = new RequirementsTest('testAlwaysSkip2');
+ $result = $test->run();
+
+ $this->assertEquals(1, $result->skippedCount());
+ $this->assertEquals(
+ 'PHP >= 9999999 is required.',
+ $test->getStatusMessage()
+ );
+ }
+
+ public function testSkipsIfRequiresNonExistingOs()
+ {
+ $test = new RequirementsTest('testAlwaysSkip3');
+ $result = $test->run();
+
+ $this->assertEquals(1, $result->skippedCount());
+ $this->assertEquals(
+ 'Operating system matching /DOESNOTEXIST/i is required.',
+ $test->getStatusMessage()
+ );
+ }
+
+ public function testSkipsIfRequiresNonExistingFunction()
+ {
+ $test = new RequirementsTest('testNine');
+ $result = $test->run();
+
+ $this->assertEquals(1, $result->skippedCount());
+ $this->assertEquals(
+ 'Function testFunc is required.',
+ $test->getStatusMessage()
+ );
+ }
+
+ public function testSkipsIfRequiresNonExistingExtension()
+ {
+ $test = new RequirementsTest('testTen');
+ $result = $test->run();
+
+ $this->assertEquals(
+ 'Extension testExt is required.',
+ $test->getStatusMessage()
+ );
+ }
+
+ public function testSkipsIfRequiresExtensionWithAMinimumVersion()
+ {
+ $test = new RequirementsTest('testSpecificExtensionVersion');
+ $result = $test->run();
+
+ $this->assertEquals(
+ 'Extension testExt >= 1.8.0 is required.',
+ $test->getStatusMessage()
+ );
+ }
+
+ public function testSkipsProvidesMessagesForAllSkippingReasons()
+ {
+ $test = new RequirementsTest('testAllPossibleRequirements');
+ $result = $test->run();
+
+ $this->assertEquals(
+ 'PHP >= 99-dev is required.' . PHP_EOL .
+ 'PHPUnit >= 9-dev is required.' . PHP_EOL .
+ 'Operating system matching /DOESNOTEXIST/i is required.' . PHP_EOL .
+ 'Function testFuncOne is required.' . PHP_EOL .
+ 'Function testFuncTwo is required.' . PHP_EOL .
+ 'Extension testExtOne is required.' . PHP_EOL .
+ 'Extension testExtTwo is required.' . PHP_EOL .
+ 'Extension testExtThree >= 2.0 is required.',
+ $test->getStatusMessage()
+ );
+ }
+
+ public function testRequiringAnExistingMethodDoesNotSkip()
+ {
+ $test = new RequirementsTest('testExistingMethod');
+ $result = $test->run();
+ $this->assertEquals(0, $result->skippedCount());
+ }
+
+ public function testRequiringAnExistingFunctionDoesNotSkip()
+ {
+ $test = new RequirementsTest('testExistingFunction');
+ $result = $test->run();
+ $this->assertEquals(0, $result->skippedCount());
+ }
+
+ public function testRequiringAnExistingExtensionDoesNotSkip()
+ {
+ $test = new RequirementsTest('testExistingExtension');
+ $result = $test->run();
+ $this->assertEquals(0, $result->skippedCount());
+ }
+
+ public function testRequiringAnExistingOsDoesNotSkip()
+ {
+ $test = new RequirementsTest('testExistingOs');
+ $result = $test->run();
+ $this->assertEquals(0, $result->skippedCount());
+ }
+
+ public function testCurrentWorkingDirectoryIsRestored()
+ {
+ $expectedCwd = getcwd();
+
+ $test = new ChangeCurrentWorkingDirectoryTest('testSomethingThatChangesTheCwd');
+ $test->run();
+
+ $this->assertSame($expectedCwd, getcwd());
+ }
+
+ /**
+ * @requires PHP 7
+ * @expectedException TypeError
+ */
+ public function testTypeErrorCanBeExpected()
+ {
+ $o = new ClassWithScalarTypeDeclarations;
+ $o->foo(null, null);
+ }
+
+ public function testCreateMockFromClassName()
+ {
+ $mock = $this->createMock(Mockable::class);
+
+ $this->assertInstanceOf(Mockable::class, $mock);
+ $this->assertInstanceOf(PHPUnit_Framework_MockObject_MockObject::class, $mock);
+ }
+
+ public function testCreateMockMocksAllMethods()
+ {
+ /** @var Mockable $mock */
+ $mock = $this->createMock(Mockable::class);
+
+ $this->assertNull($mock->foo());
+ $this->assertNull($mock->bar());
+ }
+
+ public function testCreatePartialMockDoesNotMockAllMethods()
+ {
+ /** @var Mockable $mock */
+ $mock = $this->createPartialMock(Mockable::class, ['foo']);
+
+ $this->assertNull($mock->foo());
+ $this->assertTrue($mock->bar());
+ }
+
+ public function testCreatePartialMockCanMockNoMethods()
+ {
+ /** @var Mockable $mock */
+ $mock = $this->createPartialMock(Mockable::class, []);
+
+ $this->assertTrue($mock->foo());
+ $this->assertTrue($mock->bar());
+ }
+
+ public function testCreateMockSkipsConstructor()
+ {
+ /** @var Mockable $mock */
+ $mock = $this->createMock(Mockable::class);
+
+ $this->assertFalse($mock->constructorCalled);
+ }
+
+ public function testCreateMockDisablesOriginalClone()
+ {
+ /** @var Mockable $mock */
+ $mock = $this->createMock(Mockable::class);
+
+ $cloned = clone $mock;
+ $this->assertFalse($cloned->cloned);
+ }
+
+ public function testConfiguredMockCanBeCreated()
+ {
+ /** @var Mockable $mock */
+ $mock = $this->createConfiguredMock(
+ Mockable::class,
+ [
+ 'foo' => false
+ ]
+ );
+
+ $this->assertFalse($mock->foo());
+ $this->assertNull($mock->bar());
+ }
+
+ public function testProvidingOfAutoreferencedArray()
+ {
+ $test = new \TestAutoreferenced('testJsonEncodeException', $this->getAutoreferencedArray());
+ $test->runBare();
+
+ $this->assertInternalType('array', $test->myTestData);
+ $this->assertArrayHasKey('data', $test->myTestData);
+ $this->assertEquals($test->myTestData['data'][0], $test->myTestData['data']);
+ }
+
+ /**
+ * @return array
+ */
+ private function getAutoreferencedArray()
+ {
+ $recursionData = [];
+ $recursionData[] = &$recursionData;
+
+ return [
+ 'RECURSION' => [
+ 'data' => $recursionData
+ ]
+ ];
+ }
+
+ public function testProvidingArrayThatMixesObjectsAndScalars()
+ {
+ $data = [
+ [123],
+ ['foo'],
+ [$this->createMock(Mockable::class)],
+ ];
+
+ $test = new \TestAutoreferenced('testJsonEncodeException', [$data]);
+ $test->runBare();
+
+ $this->assertInternalType('array', $test->myTestData);
+ $this->assertSame($data, $test->myTestData);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Framework/TestFailureTest.php b/vendor/phpunit/phpunit/tests/Framework/TestFailureTest.php
new file mode 100644
index 0000000..da536cc
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Framework/TestFailureTest.php
@@ -0,0 +1,21 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Framework_TestFailureTest extends PHPUnit_Framework_TestCase
+{
+ public function testToString()
+ {
+ $test = new self(__FUNCTION__);
+ $exception = new PHPUnit_Framework_Exception('message');
+ $failure = new PHPUnit_Framework_TestFailure($test, $exception);
+
+ $this->assertEquals(__METHOD__ . ': message', $failure->toString());
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Framework/TestImplementorTest.php b/vendor/phpunit/phpunit/tests/Framework/TestImplementorTest.php
new file mode 100644
index 0000000..af04147
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Framework/TestImplementorTest.php
@@ -0,0 +1,24 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Framework_TestImplementorTest extends PHPUnit_Framework_TestCase
+{
+ public function testSuccessfulRun()
+ {
+ $result = new PHPUnit_Framework_TestResult;
+
+ $test = new DoubleTestCase(new Success);
+ $test->run($result);
+
+ $this->assertCount(count($test), $result);
+ $this->assertEquals(0, $result->errorCount());
+ $this->assertEquals(0, $result->failureCount());
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Framework/TestListenerTest.php b/vendor/phpunit/phpunit/tests/Framework/TestListenerTest.php
new file mode 100644
index 0000000..fbab305
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Framework/TestListenerTest.php
@@ -0,0 +1,110 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Framework_TestListenerTest extends PHPUnit_Framework_TestCase implements PHPUnit_Framework_TestListener
+{
+ protected $endCount;
+ protected $errorCount;
+ protected $failureCount;
+ protected $warningCount;
+ protected $notImplementedCount;
+ protected $riskyCount;
+ protected $skippedCount;
+ protected $result;
+ protected $startCount;
+
+ public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->errorCount++;
+ }
+
+ public function addWarning(PHPUnit_Framework_Test $test, PHPUnit_Framework_Warning $e, $time)
+ {
+ $this->warningCount++;
+ }
+
+ public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
+ {
+ $this->failureCount++;
+ }
+
+ public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->notImplementedCount++;
+ }
+
+ public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->riskyCount++;
+ }
+
+ public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
+ {
+ $this->skippedCount++;
+ }
+
+ public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ }
+
+ public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+ {
+ }
+
+ public function startTest(PHPUnit_Framework_Test $test)
+ {
+ $this->startCount++;
+ }
+
+ public function endTest(PHPUnit_Framework_Test $test, $time)
+ {
+ $this->endCount++;
+ }
+
+ protected function setUp()
+ {
+ $this->result = new PHPUnit_Framework_TestResult;
+ $this->result->addListener($this);
+
+ $this->endCount = 0;
+ $this->failureCount = 0;
+ $this->notImplementedCount = 0;
+ $this->riskyCount = 0;
+ $this->skippedCount = 0;
+ $this->startCount = 0;
+ }
+
+ public function testError()
+ {
+ $test = new TestError;
+ $test->run($this->result);
+
+ $this->assertEquals(1, $this->errorCount);
+ $this->assertEquals(1, $this->endCount);
+ }
+
+ public function testFailure()
+ {
+ $test = new Failure;
+ $test->run($this->result);
+
+ $this->assertEquals(1, $this->failureCount);
+ $this->assertEquals(1, $this->endCount);
+ }
+
+ public function testStartStop()
+ {
+ $test = new Success;
+ $test->run($this->result);
+
+ $this->assertEquals(1, $this->startCount);
+ $this->assertEquals(1, $this->endCount);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1149.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1149.phpt
new file mode 100644
index 0000000..fed3ce2
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1149.phpt
@@ -0,0 +1,20 @@
+--TEST--
+GH-1149: Test swallows output buffer when run in a separate process
+--FILE--
+<?php
+
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue1149Test';
+$_SERVER['argv'][3] = __DIR__ . '/1149/Issue1149Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.1. 2 / 2 (100%)2
+
+Time: %s, Memory: %s
+
+OK (2 tests, 2 assertions)
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1149/Issue1149Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1149/Issue1149Test.php
new file mode 100644
index 0000000..01ac870
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1149/Issue1149Test.php
@@ -0,0 +1,18 @@
+<?php
+class Issue1149Test extends PHPUnit_Framework_TestCase
+{
+ public function testOne()
+ {
+ $this->assertTrue(true);
+ print '1';
+ }
+
+ /**
+ * @runInSeparateProcess
+ */
+ public function testTwo()
+ {
+ $this->assertTrue(true);
+ print '2';
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1216.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1216.phpt
new file mode 100644
index 0000000..2f8293a
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1216.phpt
@@ -0,0 +1,25 @@
+--TEST--
+GH-1216: PHPUnit bootstrap must take globals vars even when the file is specified in command line
+--FILE--
+<?php
+
+$_SERVER['argv'][1] = '--configuration';
+$_SERVER['argv'][2] = __DIR__ . '/1216/phpunit1216.xml';
+$_SERVER['argv'][3] = '--debug';
+$_SERVER['argv'][4] = '--bootstrap';
+$_SERVER['argv'][5] = __DIR__ . '/1216/bootstrap1216.php';
+$_SERVER['argv'][6] = __DIR__ . '/1216/Issue1216Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+
+Starting test 'Issue1216Test::testConfigAvailableInBootstrap'.
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1216/Issue1216Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1216/Issue1216Test.php
new file mode 100644
index 0000000..cfceaf5
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1216/Issue1216Test.php
@@ -0,0 +1,8 @@
+<?php
+class Issue1216Test extends PHPUnit_Framework_TestCase
+{
+ public function testConfigAvailableInBootstrap()
+ {
+ $this->assertTrue($_ENV['configAvailableInBootstrap']);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1216/bootstrap1216.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1216/bootstrap1216.php
new file mode 100644
index 0000000..cec2724
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1216/bootstrap1216.php
@@ -0,0 +1,2 @@
+<?php
+$_ENV['configAvailableInBootstrap'] = isset($_ENV['loadedFromConfig']);
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1216/phpunit1216.xml b/vendor/phpunit/phpunit/tests/Regression/GitHub/1216/phpunit1216.xml
new file mode 100644
index 0000000..c1cc9bd
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1216/phpunit1216.xml
@@ -0,0 +1,8 @@
+<phpunit>
+ <testsuite name="Github issue 1216">
+ <file>Issue1216Test.php</file>
+ </testsuite>
+ <php>
+ <env name="loadedFromConfig" value="1"/>
+ </php>
+</phpunit>
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1265.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1265.phpt
new file mode 100644
index 0000000..972b99b
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1265.phpt
@@ -0,0 +1,21 @@
+--TEST--
+GH-1265: Could not use "PHPUnit_Runner_StandardTestSuiteLoader" as loader
+--FILE--
+<?php
+
+$_SERVER['argv'][1] = '--configuration';
+$_SERVER['argv'][2] = __DIR__ . '/1265/phpunit1265.xml';
+$_SERVER['argv'][3] = 'Issue1265Test';
+$_SERVER['argv'][4] = __DIR__ . '/1265/Issue1265Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1265/Issue1265Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1265/Issue1265Test.php
new file mode 100644
index 0000000..68d71b3
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1265/Issue1265Test.php
@@ -0,0 +1,8 @@
+<?php
+class Issue1265Test extends PHPUnit_Framework_TestCase
+{
+ public function testTrue()
+ {
+ $this->assertTrue(true);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1265/phpunit1265.xml b/vendor/phpunit/phpunit/tests/Regression/GitHub/1265/phpunit1265.xml
new file mode 100644
index 0000000..27fdd52
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1265/phpunit1265.xml
@@ -0,0 +1,2 @@
+<phpunit testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader">
+</phpunit>
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1330.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1330.phpt
new file mode 100644
index 0000000..22833a4
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1330.phpt
@@ -0,0 +1,24 @@
+--TEST--
+GH-1330: Allow non-ambiguous shortened longopts
+--FILE--
+<?php
+
+$_SERVER['argv'][1] = '--deb';
+$_SERVER['argv'][2] = '--config';
+$_SERVER['argv'][3] = __DIR__ . '/1330/phpunit1330.xml';
+$_SERVER['argv'][4] = 'Issue1330Test';
+$_SERVER['argv'][5] = __DIR__ . '/1330/Issue1330Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+
+Starting test 'Issue1330Test::testTrue'.
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1330/Issue1330Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1330/Issue1330Test.php
new file mode 100644
index 0000000..0829cb9
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1330/Issue1330Test.php
@@ -0,0 +1,8 @@
+<?php
+class Issue1330Test extends PHPUnit_Framework_TestCase
+{
+ public function testTrue()
+ {
+ $this->assertTrue(PHPUNIT_1330);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1330/phpunit1330.xml b/vendor/phpunit/phpunit/tests/Regression/GitHub/1330/phpunit1330.xml
new file mode 100644
index 0000000..a61e0cc
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1330/phpunit1330.xml
@@ -0,0 +1,5 @@
+<phpunit>
+ <php>
+ <const name="PHPUNIT_1330" value="true"/>
+ </php>
+</phpunit>
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1335.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1335.phpt
new file mode 100644
index 0000000..116e09c
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1335.phpt
@@ -0,0 +1,19 @@
+--TEST--
+https://github.com/sebastianbergmann/phpunit/issues/1335
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--bootstrap';
+$_SERVER['argv'][3] = __DIR__ . '/1335/bootstrap1335.php';
+$_SERVER['argv'][4] = __DIR__ . '/1335/Issue1335Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+............ 12 / 12 (100%)
+
+Time: %s, Memory: %s
+
+OK (12 tests, 12 assertions)
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1335/Issue1335Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1335/Issue1335Test.php
new file mode 100644
index 0000000..56bcf83
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1335/Issue1335Test.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * @runTestsInSeparateProcesses
+ * @preserveGlobalState enabled
+ */
+class Issue1335Test extends PHPUnit_Framework_TestCase
+{
+ public function testGlobalString()
+ {
+ $this->assertEquals('Hello', $GLOBALS['globalString']);
+ }
+
+ public function testGlobalIntTruthy()
+ {
+ $this->assertEquals(1, $GLOBALS['globalIntTruthy']);
+ }
+
+ public function testGlobalIntFalsey()
+ {
+ $this->assertEquals(0, $GLOBALS['globalIntFalsey']);
+ }
+
+ public function testGlobalFloat()
+ {
+ $this->assertEquals(1.123, $GLOBALS['globalFloat']);
+ }
+
+ public function testGlobalBoolTrue()
+ {
+ $this->assertTrue($GLOBALS['globalBoolTrue']);
+ }
+
+ public function testGlobalBoolFalse()
+ {
+ $this->assertFalse($GLOBALS['globalBoolFalse']);
+ }
+
+ public function testGlobalNull()
+ {
+ $this->assertEquals(null, $GLOBALS['globalNull']);
+ }
+
+ public function testGlobalArray()
+ {
+ $this->assertEquals(['foo'], $GLOBALS['globalArray']);
+ }
+
+ public function testGlobalNestedArray()
+ {
+ $this->assertEquals([['foo']], $GLOBALS['globalNestedArray']);
+ }
+
+ public function testGlobalObject()
+ {
+ $this->assertEquals((object) ['foo'=> 'bar'], $GLOBALS['globalObject']);
+ }
+
+ public function testGlobalObjectWithBackSlashString()
+ {
+ $this->assertEquals((object) ['foo'=> 'back\\slash'], $GLOBALS['globalObjectWithBackSlashString']);
+ }
+
+ public function testGlobalObjectWithDoubleBackSlashString()
+ {
+ $this->assertEquals((object) ['foo'=> 'back\\\\slash'], $GLOBALS['globalObjectWithDoubleBackSlashString']);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1335/bootstrap1335.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1335/bootstrap1335.php
new file mode 100644
index 0000000..7165bb2
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1335/bootstrap1335.php
@@ -0,0 +1,13 @@
+<?php
+$globalString = 'Hello';
+$globalIntTruthy = 1;
+$globalIntFalsey = 0;
+$globalFloat = 1.123;
+$globalBoolTrue = true;
+$globalBoolFalse = false;
+$globalNull = null;
+$globalArray = ['foo'];
+$globalNestedArray = [['foo']];
+$globalObject = (object) ['foo'=> 'bar'];
+$globalObjectWithBackSlashString = (object) ['foo'=> 'back\\slash'];
+$globalObjectWithDoubleBackSlashString = (object) ['foo'=> 'back\\\\slash'];
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1337.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1337.phpt
new file mode 100644
index 0000000..a2fc01e
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1337.phpt
@@ -0,0 +1,19 @@
+--TEST--
+https://github.com/sebastianbergmann/phpunit/issues/1337
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = 'Issue1337Test';
+$_SERVER['argv'][4] = __DIR__ . '/1337/Issue1337Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.. 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+OK (2 tests, 2 assertions)
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1337/Issue1337Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1337/Issue1337Test.php
new file mode 100644
index 0000000..922cfe9
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1337/Issue1337Test.php
@@ -0,0 +1,19 @@
+<?php
+class Issue1337Test extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider dataProvider
+ */
+ public function testProvider($a)
+ {
+ $this->assertTrue($a);
+ }
+
+ public function dataProvider()
+ {
+ return [
+ 'c:\\'=> [true],
+ 0.9 => [true]
+ ];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1348.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1348.phpt
new file mode 100644
index 0000000..4da3448
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1348.phpt
@@ -0,0 +1,34 @@
+--TEST--
+https://github.com/sebastianbergmann/phpunit/issues/1348
+--SKIPIF--
+<?php
+if (defined('HHVM_VERSION')) {
+ print 'skip: PHP runtime required';
+}
+?>
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][] = '--report-useless-tests';
+$_SERVER['argv'][] = '--process-isolation';
+$_SERVER['argv'][] = 'Issue1348Test';
+$_SERVER['argv'][] = __DIR__ . '/1348/Issue1348Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.
+STDOUT does not break test result
+E 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 error:
+
+1) Issue1348Test::testSTDERR
+PHPUnit_Framework_Exception: STDERR works as usual.
+
+ERRORS!
+Tests: 2, Assertions: 1, Errors: 1.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1348/Issue1348Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1348/Issue1348Test.php
new file mode 100644
index 0000000..d3c82f0
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1348/Issue1348Test.php
@@ -0,0 +1,14 @@
+<?php
+class Issue1348Test extends PHPUnit_Framework_TestCase
+{
+ public function testSTDOUT()
+ {
+ fwrite(STDOUT, "\nSTDOUT does not break test result\n");
+ $this->assertTrue(true);
+ }
+
+ public function testSTDERR()
+ {
+ fwrite(STDERR, 'STDERR works as usual.');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1351.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1351.phpt
new file mode 100644
index 0000000..ef3246d
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1351.phpt
@@ -0,0 +1,46 @@
+--TEST--
+https://github.com/sebastianbergmann/phpunit/issues/1351
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo') || !in_array('sqlite', PDO::getAvailableDrivers())) {
+ print 'skip: PDO_SQLITE is required';
+}
+?>
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = 'Issue1351Test';
+$_SERVER['argv'][4] = __DIR__ . '/1351/Issue1351Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+F.E.E 5 / 5 (100%)
+
+Time: %s, Memory: %s
+
+There were 2 errors:
+
+1) Issue1351Test::testExceptionPre
+RuntimeException: Expected rethrown exception.
+%A
+Caused by
+LogicException: Expected exception.
+%A
+
+2) Issue1351Test::testPhpCoreLanguageException
+PDOException: SQLSTATE[HY000]: General error: 1 no such table: php_wtf
+%A
+
+--
+
+There was 1 failure:
+
+1) Issue1351Test::testFailurePre
+Expected failure.
+%A
+ERRORS!
+Tests: 5, Assertions: 5, Errors: 2, Failures: 1.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1351/ChildProcessClass1351.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1351/ChildProcessClass1351.php
new file mode 100644
index 0000000..24c0537
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1351/ChildProcessClass1351.php
@@ -0,0 +1,4 @@
+<?php
+class ChildProcessClass1351
+{
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1351/Issue1351Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1351/Issue1351Test.php
new file mode 100644
index 0000000..f688c55
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1351/Issue1351Test.php
@@ -0,0 +1,48 @@
+<?php
+class Issue1351Test extends PHPUnit_Framework_TestCase
+{
+ protected $instance;
+
+ /**
+ * @runInSeparateProcess
+ */
+ public function testFailurePre()
+ {
+ $this->instance = new ChildProcessClass1351();
+ $this->assertFalse(true, 'Expected failure.');
+ }
+
+ public function testFailurePost()
+ {
+ $this->assertNull($this->instance);
+ $this->assertFalse(class_exists('ChildProcessClass1351', false), 'ChildProcessClass1351 is not loaded.');
+ }
+
+ /**
+ * @runInSeparateProcess
+ */
+ public function testExceptionPre()
+ {
+ $this->instance = new ChildProcessClass1351();
+ try {
+ throw new LogicException('Expected exception.');
+ } catch (LogicException $e) {
+ throw new RuntimeException('Expected rethrown exception.', 0, $e);
+ }
+ }
+
+ public function testExceptionPost()
+ {
+ $this->assertNull($this->instance);
+ $this->assertFalse(class_exists('ChildProcessClass1351', false), 'ChildProcessClass1351 is not loaded.');
+ }
+
+ public function testPhpCoreLanguageException()
+ {
+ // User-space code cannot instantiate a PDOException with a string code,
+ // so trigger a real one.
+ $connection = new PDO('sqlite::memory:');
+ $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+ $connection->query("DELETE FROM php_wtf WHERE exception_code = 'STRING'");
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1374.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1374.phpt
new file mode 100644
index 0000000..a5998f0
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1374.phpt
@@ -0,0 +1,19 @@
+--TEST--
+https://github.com/sebastianbergmann/phpunit/issues/1374
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue1374Test';
+$_SERVER['argv'][3] = __DIR__ . '/1374/Issue1374Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+S 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK, but incomplete, skipped, or risky tests!
+Tests: 1, Assertions: 0, Skipped: 1.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1374/Issue1374Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1374/Issue1374Test.php
new file mode 100644
index 0000000..ad6a3bf
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1374/Issue1374Test.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * @requires extension I_DO_NOT_EXIST
+ */
+class Issue1374Test extends PHPUnit_Framework_TestCase
+{
+ protected function setUp()
+ {
+ print __FUNCTION__;
+ }
+
+ public function testSomething()
+ {
+ $this->fail('This should not be reached');
+ }
+
+ protected function tearDown()
+ {
+ print __FUNCTION__;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1437.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1437.phpt
new file mode 100644
index 0000000..a49c338
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1437.phpt
@@ -0,0 +1,26 @@
+--TEST--
+https://github.com/sebastianbergmann/phpunit/issues/1437
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue1437Test';
+$_SERVER['argv'][3] = __DIR__ . '/1437/Issue1437Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+F 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 failure:
+
+1) Issue1437Test::testFailure
+Failed asserting that false is true.
+
+%sIssue1437Test.php:%i
+
+FAILURES!
+Tests: 1, Assertions: 1, Failures: 1.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1437/Issue1437Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1437/Issue1437Test.php
new file mode 100644
index 0000000..bff4b20
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1437/Issue1437Test.php
@@ -0,0 +1,9 @@
+<?php
+class Issue1437Test extends PHPUnit_Framework_TestCase
+{
+ public function testFailure()
+ {
+ ob_start();
+ $this->assertTrue(false);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1468.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1468.phpt
new file mode 100644
index 0000000..85ce1d1
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1468.phpt
@@ -0,0 +1,20 @@
+--TEST--
+https://github.com/sebastianbergmann/phpunit/issues/1468
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--disallow-todo-tests';
+$_SERVER['argv'][3] = 'Issue1468Test';
+$_SERVER['argv'][4] = __DIR__ . '/1468/Issue1468Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+I 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK, but incomplete, skipped, or risky tests!
+Tests: 1, Assertions: 0, Incomplete: 1.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1468/Issue1468Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1468/Issue1468Test.php
new file mode 100644
index 0000000..535b25b
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1468/Issue1468Test.php
@@ -0,0 +1,11 @@
+<?php
+class Issue1468Test extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @todo Implement this test
+ */
+ public function testFailure()
+ {
+ $this->markTestIncomplete();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1471.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1471.phpt
new file mode 100644
index 0000000..9944fae
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1471.phpt
@@ -0,0 +1,26 @@
+--TEST--
+https://github.com/sebastianbergmann/phpunit/issues/1471
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue1471Test';
+$_SERVER['argv'][3] = __DIR__ . '/1471/Issue1471Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+F 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 failure:
+
+1) Issue1471Test::testFailure
+Failed asserting that false is true.
+
+%s/Issue1471Test.php:10
+
+FAILURES!
+Tests: 1, Assertions: 1, Failures: 1.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1471/Issue1471Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1471/Issue1471Test.php
new file mode 100644
index 0000000..28f1274
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1471/Issue1471Test.php
@@ -0,0 +1,12 @@
+<?php
+class Issue1471Test extends PHPUnit_Framework_TestCase
+{
+ public function testFailure()
+ {
+ $this->expectOutputString('*');
+
+ print '*';
+
+ $this->assertTrue(false);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1472.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1472.phpt
new file mode 100644
index 0000000..10656cb
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1472.phpt
@@ -0,0 +1,25 @@
+--TEST--
+https://github.com/sebastianbergmann/phpunit/issues/1472
+--SKIPIF--
+<?php
+// See: https://github.com/facebook/hhvm/issues/4669
+if (defined('HHVM_VERSION')) {
+ print 'skip: HHVM does not support cloning DOM nodes';
+}
+?>
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue1472Test';
+$_SERVER['argv'][3] = __DIR__ . '/1472/Issue1472Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 4 assertions)
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1472/Issue1472Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1472/Issue1472Test.php
new file mode 100644
index 0000000..a392773
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1472/Issue1472Test.php
@@ -0,0 +1,21 @@
+<?php
+class Issue1472Test extends PHPUnit_Framework_TestCase
+{
+ public function testAssertEqualXMLStructure()
+ {
+ $doc = new DOMDocument;
+ $doc->loadXML('<root><label>text content</label></root>');
+
+ $xpath = new DOMXPath($doc);
+
+ $labelElement = $doc->getElementsByTagName('label')->item(0);
+
+ $this->assertEquals(1, $xpath->evaluate('count(//label[text() = "text content"])'));
+
+ $expectedElmt = $doc->createElement('label', 'text content');
+ $this->assertEqualXMLStructure($expectedElmt, $labelElement);
+
+ // the following assertion fails, even though it passed before - which is due to the assertEqualXMLStructure() has modified the $labelElement
+ $this->assertEquals(1, $xpath->evaluate('count(//label[text() = "text content"])'));
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1570.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/1570.phpt
new file mode 100644
index 0000000..a34dfa2
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1570.phpt
@@ -0,0 +1,20 @@
+--TEST--
+https://github.com/sebastianbergmann/phpunit/issues/1570
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--disallow-test-output';
+$_SERVER['argv'][3] = 'Issue1570Test';
+$_SERVER['argv'][4] = __DIR__ . '/1570/Issue1570Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+R 1 / 1 (100%)*
+
+Time: %s, Memory: %s
+
+OK, but incomplete, skipped, or risky tests!
+Tests: 1, Assertions: 0, Risky: 1.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/1570/Issue1570Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/1570/Issue1570Test.php
new file mode 100644
index 0000000..0148506
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/1570/Issue1570Test.php
@@ -0,0 +1,8 @@
+<?php
+class Issue1570Test extends PHPUnit_Framework_TestCase
+{
+ public function testOne()
+ {
+ print '*';
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2137-filter.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/2137-filter.phpt
new file mode 100644
index 0000000..a02829a
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2137-filter.phpt
@@ -0,0 +1,28 @@
+--TEST--
+#2137: Error message for invalid dataprovider
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue2137Test';
+$_SERVER['argv'][3] = __DIR__ . '/2137/Issue2137Test.php';
+$_SERVER['argv'][4] = '--filter';
+$_SERVER['argv'][5] = 'BrandService';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+W 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 warning:
+
+1) Warning
+The data provider specified for Issue2137Test::testBrandService is invalid.
+Data set #0 is invalid.
+
+WARNINGS!
+Tests: 1, Assertions: 0, Warnings: 1.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2137-no_filter.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/2137-no_filter.phpt
new file mode 100644
index 0000000..3668557
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2137-no_filter.phpt
@@ -0,0 +1,30 @@
+--TEST--
+#2137: Error message for invalid dataprovider
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue2137Test';
+$_SERVER['argv'][3] = __DIR__ . '/2137/Issue2137Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+WW 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+There were 2 warnings:
+
+1) Warning
+The data provider specified for Issue2137Test::testBrandService is invalid.
+Data set #0 is invalid.
+
+2) Warning
+The data provider specified for Issue2137Test::testSomethingElseInvalid is invalid.
+Data set #0 is invalid.
+
+WARNINGS!
+Tests: 2, Assertions: 0, Warnings: 2.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2137/Issue2137Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/2137/Issue2137Test.php
new file mode 100644
index 0000000..e9121be
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2137/Issue2137Test.php
@@ -0,0 +1,33 @@
+<?php
+class Issue2137Test extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider provideBrandService
+ * @param $provided
+ * @param $expected
+ */
+ public function testBrandService($provided, $expected)
+ {
+ $this->assertSame($provided, $expected);
+ }
+
+
+ public function provideBrandService()
+ {
+ return [
+ //[true, true]
+ new stdClass() // not valid
+ ];
+ }
+
+
+ /**
+ * @dataProvider provideBrandService
+ * @param $provided
+ * @param $expected
+ */
+ public function testSomethingElseInvalid($provided, $expected)
+ {
+ $this->assertSame($provided, $expected);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2145.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/2145.phpt
new file mode 100644
index 0000000..9edc97d
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2145.phpt
@@ -0,0 +1,26 @@
+--TEST--
+--stop-on-failure fails to stop on PHP 7
+--FILE--
+<?php
+
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue2145Test';
+$_SERVER['argv'][3] = '--stop-on-error';
+$_SERVER['argv'][4] = __DIR__ . '/2145/Issue2145Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+E
+
+Time: %s, Memory: %s
+
+There was 1 error:
+
+1) Issue2145Test
+%A
+ERRORS!
+Tests: 2, Assertions: 0, Errors: 1.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2145/Issue2145Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/2145/Issue2145Test.php
new file mode 100644
index 0000000..c290765
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2145/Issue2145Test.php
@@ -0,0 +1,16 @@
+<?php
+class Issue2145Test extends PHPUnit_Framework_TestCase
+{
+ public static function setUpBeforeClass()
+ {
+ throw new Exception;
+ }
+
+ public function testOne()
+ {
+ }
+
+ public function testTwo()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2158.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/2158.phpt
new file mode 100644
index 0000000..963849d
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2158.phpt
@@ -0,0 +1,19 @@
+--TEST--
+#2158: Failure to run tests in separate processes if a file included into main process contains constant definition
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue2158Test';
+$_SERVER['argv'][3] = __DIR__ . '/2158/Issue2158Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.. 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+OK (2 tests, 2 assertions)
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2158/Issue2158Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/2158/Issue2158Test.php
new file mode 100644
index 0000000..014aa4f
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2158/Issue2158Test.php
@@ -0,0 +1,23 @@
+<?php
+class Issue2158Test extends PHPUnit_Framework_TestCase
+{
+ /**
+ * Set constant in main process
+ */
+ public function testSomething()
+ {
+ include(__DIR__ . '/constant.inc');
+ $this->assertTrue(true);
+ }
+
+ /**
+ * Constant defined previously in main process constant should be available and
+ * no errors should be yielded by reload of included files
+ *
+ * @runInSeparateProcess
+ */
+ public function testSomethingElse()
+ {
+ $this->assertTrue(defined('TEST_CONSTANT'));
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2158/constant.inc b/vendor/phpunit/phpunit/tests/Regression/GitHub/2158/constant.inc
new file mode 100644
index 0000000..4137114
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2158/constant.inc
@@ -0,0 +1,5 @@
+<?php
+
+define('TEST_CONSTANT', true);
+
+?>
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2299/Issue2299Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/2299/Issue2299Test.php
new file mode 100644
index 0000000..1139be3
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2299/Issue2299Test.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * @author Jean Carlo Machado <contato@jeancarlomachado.com.br>
+ */
+class Test extends PHPUnit_Framework_TestCase
+{
+ public function testOne()
+ {
+ $this->expectExceptionMessage('message');
+
+ throw new Exception('message');
+ }
+
+ public function testTwo()
+ {
+ $this->expectExceptionCode(123);
+
+ throw new Exception('message', 123);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2366.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/2366.phpt
new file mode 100644
index 0000000..6c6ce72
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2366.phpt
@@ -0,0 +1,19 @@
+--TEST--
+#2366: Using a test double from a data provider only works once
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue2366Test';
+$_SERVER['argv'][3] = __DIR__ . '/2366/Issue2366Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.. 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+OK (2 tests, 2 assertions)
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2366/Issue2366Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/2366/Issue2366Test.php
new file mode 100644
index 0000000..b8ea9f5
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2366/Issue2366Test.php
@@ -0,0 +1,30 @@
+<?php
+class Issue2366
+{
+ public function foo()
+ {
+ }
+}
+
+class Issue2366Test extends PHPUnit\Framework\TestCase
+{
+ /**
+ * @dataProvider provider
+ */
+ public function testOne($o)
+ {
+ $this->assertEquals(1, $o->foo());
+ }
+
+ public function provider()
+ {
+ $o = $this->createMock(Issue2366::class);
+
+ $o->method('foo')->willReturn(1);
+
+ return [
+ [$o],
+ [$o]
+ ];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2380.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/2380.phpt
new file mode 100644
index 0000000..fb76058
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2380.phpt
@@ -0,0 +1,19 @@
+--TEST--
+#2380: Data Providers cannot be generators anymore
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue2380Test';
+$_SERVER['argv'][3] = __DIR__ . '/2380/Issue2380Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2380/Issue2380Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/2380/Issue2380Test.php
new file mode 100644
index 0000000..55c2b80
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2380/Issue2380Test.php
@@ -0,0 +1,21 @@
+<?php
+use PHPUnit\Framework\TestCase;
+
+class Issue2380Test extends TestCase
+{
+ /**
+ * @dataProvider generatorData
+ */
+ public function testGeneratorProvider($data)
+ {
+ $this->assertNotEmpty($data);
+ }
+
+ /**
+ * @return Generator
+ */
+ public function generatorData()
+ {
+ yield ['testing'];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2382.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/2382.phpt
new file mode 100644
index 0000000..c6adc13
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2382.phpt
@@ -0,0 +1,19 @@
+--TEST--
+#2382: Data Providers throw error with uncloneable object
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue2382Test';
+$_SERVER['argv'][3] = __DIR__ . '/2382/Issue2382Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2382/Issue2382Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/2382/Issue2382Test.php
new file mode 100644
index 0000000..9fd49cb
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2382/Issue2382Test.php
@@ -0,0 +1,22 @@
+<?php
+use PHPUnit\Framework\TestCase;
+
+class Issue2382Test extends TestCase
+{
+ /**
+ * @dataProvider dataProvider
+ */
+ public function testOne($test)
+ {
+ $this->assertInstanceOf(\Exception::class, $test);
+ }
+
+ public function dataProvider()
+ {
+ return [
+ [
+ $this->getMockBuilder(\Exception::class)->getMock()
+ ]
+ ];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2435.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/2435.phpt
new file mode 100644
index 0000000..85f8c24
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2435.phpt
@@ -0,0 +1,20 @@
+--TEST--
+GH-2435: Test empty @group annotation
+--FILE--
+<?php
+
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue2435Test';
+$_SERVER['argv'][3] = __DIR__ . '/2435/Issue2435Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2435/Issue2435Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/2435/Issue2435Test.php
new file mode 100644
index 0000000..447418e
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2435/Issue2435Test.php
@@ -0,0 +1,12 @@
+<?php
+
+/**
+ * @group
+ */
+class Issue2435Test extends PHPUnit_Framework_TestCase
+{
+ public function testOne()
+ {
+ $this->assertTrue(true);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/244.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/244.phpt
new file mode 100644
index 0000000..eb5d7db
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/244.phpt
@@ -0,0 +1,32 @@
+--TEST--
+GH-244: Expected Exception should support string codes
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = 'Issue244Test';
+$_SERVER['argv'][4] = __DIR__ . '/244/Issue244Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.FFF 4 / 4 (100%)
+
+Time: %s, Memory: %s
+
+There were 3 failures:
+
+1) Issue244Test::testFails
+Failed asserting that '123StringCode' is equal to expected exception code 'OtherString'.
+
+2) Issue244Test::testFailsTooIfExpectationIsANumber
+Failed asserting that '123StringCode' is equal to expected exception code 123.
+
+3) Issue244Test::testFailsTooIfExceptionCodeIsANumber
+Failed asserting that 123 is equal to expected exception code '123String'.
+
+FAILURES!
+Tests: 4, Assertions: 8, Failures: 3.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/244/Issue244Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/244/Issue244Test.php
new file mode 100644
index 0000000..621c4cf
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/244/Issue244Test.php
@@ -0,0 +1,55 @@
+<?php
+class Issue244Test extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @expectedException Issue244Exception
+ * @expectedExceptionCode 123StringCode
+ */
+ public function testWorks()
+ {
+ throw new Issue244Exception;
+ }
+
+ /**
+ * @expectedException Issue244Exception
+ * @expectedExceptionCode OtherString
+ */
+ public function testFails()
+ {
+ throw new Issue244Exception;
+ }
+
+ /**
+ * @expectedException Issue244Exception
+ * @expectedExceptionCode 123
+ */
+ public function testFailsTooIfExpectationIsANumber()
+ {
+ throw new Issue244Exception;
+ }
+
+ /**
+ * @expectedException Issue244ExceptionIntCode
+ * @expectedExceptionCode 123String
+ */
+ public function testFailsTooIfExceptionCodeIsANumber()
+ {
+ throw new Issue244ExceptionIntCode;
+ }
+}
+
+class Issue244Exception extends Exception
+{
+ public function __construct()
+ {
+ $this->code = '123StringCode';
+ }
+}
+
+class Issue244ExceptionIntCode extends Exception
+{
+ public function __construct()
+ {
+ $this->code = 123;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2731.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/2731.phpt
new file mode 100644
index 0000000..7e2d324
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2731.phpt
@@ -0,0 +1,26 @@
+--TEST--
+GH-2731: Empty exception message cannot be expected
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue2731Test';
+$_SERVER['argv'][3] = __DIR__ . '/2731/Issue2731Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+F 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 failure:
+
+1) Issue2731Test::testOne
+Failed asserting that exception message is empty but is 'message'.
+
+FAILURES!
+Tests: 1, Assertions: 2, Failures: 1.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2731/Issue2731Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/2731/Issue2731Test.php
new file mode 100644
index 0000000..0d1e6d3
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2731/Issue2731Test.php
@@ -0,0 +1,11 @@
+<?php
+class Issue2731Test extends PHPUnit\Framework\TestCase
+{
+ public function testOne()
+ {
+ $this->expectException(Exception::class);
+ $this->expectExceptionMessage('');
+
+ throw new Exception('message');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2758.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/2758.phpt
new file mode 100644
index 0000000..8828dff
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2758.phpt
@@ -0,0 +1,22 @@
+--TEST--
+GH-2758: TestCase::addToAssertionCount() no longer has effect when called from TestListener::endTest()
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--configuration';
+$_SERVER['argv'][2] = __DIR__ . '/2758/phpunit.xml';
+$_SERVER['argv'][3] = 'Issue2758Test';
+$_SERVER['argv'][4] = __DIR__ . '/2758/Issue2758Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+require __DIR__ . '/2758/Issue2758TestListener.php';
+
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2758/Issue2758Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/2758/Issue2758Test.php
new file mode 100644
index 0000000..d2e0428
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2758/Issue2758Test.php
@@ -0,0 +1,7 @@
+<?php
+class Issue2758Test extends PHPUnit_Framework_TestCase
+{
+ public function testOne()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2758/Issue2758TestListener.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/2758/Issue2758TestListener.php
new file mode 100644
index 0000000..b3e2405
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2758/Issue2758TestListener.php
@@ -0,0 +1,12 @@
+<?php
+class Issue2758TestListener extends PHPUnit_Framework_BaseTestListener
+{
+ public function endTest(PHPUnit_Framework_Test $test, $time)
+ {
+ if (!$test instanceof PHPUnit_Framework_TestCase) {
+ return;
+ }
+
+ $test->addToAssertionCount(1);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2758/phpunit.xml b/vendor/phpunit/phpunit/tests/Regression/GitHub/2758/phpunit.xml
new file mode 100644
index 0000000..c12f3e2
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2758/phpunit.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.3/phpunit.xsd">
+ <listeners>
+ <listener class="Issue2758TestListener" />
+ </listeners>
+</phpunit>
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2811.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/2811.phpt
new file mode 100644
index 0000000..c179b12
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2811.phpt
@@ -0,0 +1,20 @@
+--TEST--
+GH-2811: expectExceptionMessage() does not work without expectException()
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue2811Test';
+$_SERVER['argv'][3] = __DIR__ . '/2811/Issue2811Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 2 assertions)
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2811/Issue2811Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/2811/Issue2811Test.php
new file mode 100644
index 0000000..20bb570
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2811/Issue2811Test.php
@@ -0,0 +1,10 @@
+<?php
+class Issue2811Test extends PHPUnit\Framework\TestCase
+{
+ public function testOne()
+ {
+ $this->expectExceptionMessage('hello');
+
+ throw new \Exception('hello');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2972.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/2972.phpt
new file mode 100644
index 0000000..a46ced1
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2972.phpt
@@ -0,0 +1,18 @@
+--TEST--
+GH-2972: Test suite shouldn't fail when it contains both *.phpt files and unconventionally named tests
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = __DIR__ . '/2972/';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.. 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+OK (2 tests, 2 assertions)
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2972/issue-2972-test.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/2972/issue-2972-test.phpt
new file mode 100644
index 0000000..4d09cf5
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2972/issue-2972-test.phpt
@@ -0,0 +1,10 @@
+--TEST--
+Just a sample test for issue 2972, does not actually test anything
+--FILE--
+<?php
+echo "Hello world\n";
+?>
+===DONE===
+--EXPECT--
+Hello world
+===DONE===
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/2972/unconventiallyNamedIssue2972Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/2972/unconventiallyNamedIssue2972Test.php
new file mode 100644
index 0000000..3fd57f0
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/2972/unconventiallyNamedIssue2972Test.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Issue2972;
+
+use PHPUnit\Framework\TestCase;
+
+class Issue2972Test extends TestCase
+{
+ public function testHello()
+ {
+ $this->assertNotEmpty('Hello world!');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/322.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/322.phpt
new file mode 100644
index 0000000..c69e215
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/322.phpt
@@ -0,0 +1,26 @@
+--TEST--
+GH-322: group commandline option should override group/exclude setting in phpunit.xml
+--FILE--
+<?php
+
+$_SERVER['argv'][1] = '--configuration';
+$_SERVER['argv'][2] = __DIR__ . '/322/phpunit322.xml';
+$_SERVER['argv'][3] = '--debug';
+$_SERVER['argv'][4] = '--group';
+$_SERVER['argv'][5] = 'one';
+$_SERVER['argv'][6] = 'Issue322Test';
+$_SERVER['argv'][7] = __DIR__ . '/322/Issue322Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+
+Starting test 'Issue322Test::testOne'.
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 0 assertions)
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/322/Issue322Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/322/Issue322Test.php
new file mode 100644
index 0000000..618bcaa
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/322/Issue322Test.php
@@ -0,0 +1,17 @@
+<?php
+class Issue322Test extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @group one
+ */
+ public function testOne()
+ {
+ }
+
+ /**
+ * @group two
+ */
+ public function testTwo()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/322/phpunit322.xml b/vendor/phpunit/phpunit/tests/Regression/GitHub/322/phpunit322.xml
new file mode 100644
index 0000000..e3b2948
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/322/phpunit322.xml
@@ -0,0 +1,11 @@
+<phpunit>
+ <testsuite name="My Test Suite">
+ <file>Test.php</file>
+ </testsuite>
+
+ <groups>
+ <exclude>
+ <group>one</group>
+ </exclude>
+ </groups>
+</phpunit>
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/433.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/433.phpt
new file mode 100644
index 0000000..0f1adf1
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/433.phpt
@@ -0,0 +1,31 @@
+--TEST--
+GH-433: expectOutputString not completely working as expected
+--FILE--
+<?php
+
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue433Test';
+$_SERVER['argv'][3] = __DIR__ . '/433/Issue433Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+..F 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 failure:
+
+1) Issue433Test::testNotMatchingOutput
+Failed asserting that two strings are equal.
+--- Expected
++++ Actual
+@@ @@
+-'foo'
++'bar'
+
+FAILURES!
+Tests: 3, Assertions: 3, Failures: 1.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/433/Issue433Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/433/Issue433Test.php
new file mode 100644
index 0000000..e0a91b3
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/433/Issue433Test.php
@@ -0,0 +1,21 @@
+<?php
+class Issue433Test extends PHPUnit_Framework_TestCase
+{
+ public function testOutputWithExpectationBefore()
+ {
+ $this->expectOutputString('test');
+ print 'test';
+ }
+
+ public function testOutputWithExpectationAfter()
+ {
+ print 'test';
+ $this->expectOutputString('test');
+ }
+
+ public function testNotMatchingOutput()
+ {
+ print 'bar';
+ $this->expectOutputString('foo');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/445.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/445.phpt
new file mode 100644
index 0000000..f15b129
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/445.phpt
@@ -0,0 +1,32 @@
+--TEST--
+GH-455: expectOutputString not working in strict mode
+--FILE--
+<?php
+
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--disallow-test-output';
+$_SERVER['argv'][3] = 'Issue445Test';
+$_SERVER['argv'][4] = __DIR__ . '/445/Issue445Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+..F 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 failure:
+
+1) Issue445Test::testNotMatchingOutput
+Failed asserting that two strings are equal.
+--- Expected
++++ Actual
+@@ @@
+-'foo'
++'bar'
+
+FAILURES!
+Tests: 3, Assertions: 3, Failures: 1.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/445/Issue445Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/445/Issue445Test.php
new file mode 100644
index 0000000..c309025
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/445/Issue445Test.php
@@ -0,0 +1,21 @@
+<?php
+class Issue445Test extends PHPUnit_Framework_TestCase
+{
+ public function testOutputWithExpectationBefore()
+ {
+ $this->expectOutputString('test');
+ print 'test';
+ }
+
+ public function testOutputWithExpectationAfter()
+ {
+ print 'test';
+ $this->expectOutputString('test');
+ }
+
+ public function testNotMatchingOutput()
+ {
+ print 'bar';
+ $this->expectOutputString('foo');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/498.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/498.phpt
new file mode 100644
index 0000000..db6e00b
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/498.phpt
@@ -0,0 +1,29 @@
+--TEST--
+GH-498: The test methods won't be run if a dataProvider throws Exception and --group is added in command line
+--FILE--
+<?php
+
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--group';
+$_SERVER['argv'][3] = 'trueOnly';
+$_SERVER['argv'][4] = 'Issue498Test';
+$_SERVER['argv'][5] = __DIR__ . '/498/Issue498Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+W 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 warning:
+
+1) Warning
+The data provider specified for Issue498Test::shouldBeFalse is invalid.
+Can't create the data
+
+WARNINGS!
+Tests: 1, Assertions: 0, Warnings: 1.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/498/Issue498Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/498/Issue498Test.php
new file mode 100644
index 0000000..5d22aac
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/498/Issue498Test.php
@@ -0,0 +1,44 @@
+<?php
+
+class Issue498Test extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @test
+ * @dataProvider shouldBeTrueDataProvider
+ * @group falseOnly
+ */
+ public function shouldBeTrue($testData)
+ {
+ $this->assertTrue(true);
+ }
+
+ /**
+ * @test
+ * @dataProvider shouldBeFalseDataProvider
+ * @group trueOnly
+ */
+ public function shouldBeFalse($testData)
+ {
+ $this->assertFalse(false);
+ }
+
+ public function shouldBeTrueDataProvider()
+ {
+
+ //throw new Exception("Can't create the data");
+ return [
+ [true],
+ [false]
+ ];
+ }
+
+ public function shouldBeFalseDataProvider()
+ {
+ throw new Exception("Can't create the data");
+
+ return [
+ [true],
+ [false]
+ ];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/503.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/503.phpt
new file mode 100644
index 0000000..07aecb7
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/503.phpt
@@ -0,0 +1,33 @@
+--TEST--
+GH-503: assertEquals() Line Ending Differences Are Obscure
+--FILE--
+<?php
+
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue503Test';
+$_SERVER['argv'][3] = __DIR__ . '/503/Issue503Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+F 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 failure:
+
+1) Issue503Test::testCompareDifferentLineEndings
+Failed asserting that two strings are identical.
+--- Expected
++++ Actual
+@@ @@
+ #Warning: Strings contain different line endings!
+ foo
+
+%s:%i
+
+FAILURES!
+Tests: 1, Assertions: 1, Failures: 1.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/503/Issue503Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/503/Issue503Test.php
new file mode 100644
index 0000000..75ca8d4
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/503/Issue503Test.php
@@ -0,0 +1,11 @@
+<?php
+class Issue503Test extends PHPUnit_Framework_TestCase
+{
+ public function testCompareDifferentLineEndings()
+ {
+ $this->assertSame(
+ "foo\n",
+ "foo\r\n"
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/581.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/581.phpt
new file mode 100644
index 0000000..c4327b4
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/581.phpt
@@ -0,0 +1,42 @@
+--TEST--
+GH-581: PHPUnit_Util_Type::export adds extra newlines in Windows
+--FILE--
+<?php
+
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue581Test';
+$_SERVER['argv'][3] = __DIR__ . '/581/Issue581Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+F 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 failure:
+
+1) Issue581Test::testExportingObjectsDoesNotBreakWindowsLineFeeds
+Failed asserting that two objects are equal.
+--- Expected
++++ Actual
+@@ @@
+ stdClass Object (
+ 0 => 1
+ 1 => 2
+ 2 => 'Test\n'
+ 3 => 4
+- 4 => 5
++ 4 => 1
+ 5 => 6
+ 6 => 7
+ 7 => 8
+ )
+
+%s:%i
+
+FAILURES!
+Tests: 1, Assertions: 1, Failures: 1.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/581/Issue581Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/581/Issue581Test.php
new file mode 100644
index 0000000..88d637c
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/581/Issue581Test.php
@@ -0,0 +1,11 @@
+<?php
+class Issue581Test extends PHPUnit_Framework_TestCase
+{
+ public function testExportingObjectsDoesNotBreakWindowsLineFeeds()
+ {
+ $this->assertEquals(
+ (object) [1, 2, "Test\r\n", 4, 5, 6, 7, 8],
+ (object) [1, 2, "Test\r\n", 4, 1, 6, 7, 8]
+ );
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/74.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/74.phpt
new file mode 100644
index 0000000..6ace583
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/74.phpt
@@ -0,0 +1,28 @@
+--TEST--
+GH-74: catchable fatal error in 3.5
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = 'Issue74Test';
+$_SERVER['argv'][4] = __DIR__ . '/74/Issue74Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+E 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 error:
+
+1) Issue74Test::testCreateAndThrowNewExceptionInProcessIsolation
+NewException: Testing GH-74
+
+%sIssue74Test.php:7
+
+ERRORS!
+Tests: 1, Assertions: 0, Errors: 1.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/74/Issue74Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/74/Issue74Test.php
new file mode 100644
index 0000000..72f3592
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/74/Issue74Test.php
@@ -0,0 +1,9 @@
+<?php
+class Issue74Test extends PHPUnit_Framework_TestCase
+{
+ public function testCreateAndThrowNewExceptionInProcessIsolation()
+ {
+ require_once __DIR__ . '/NewException.php';
+ throw new NewException('Testing GH-74');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/74/NewException.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/74/NewException.php
new file mode 100644
index 0000000..abe2f71
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/74/NewException.php
@@ -0,0 +1,4 @@
+<?php
+class NewException extends Exception
+{
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/765.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/765.phpt
new file mode 100644
index 0000000..266968a
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/765.phpt
@@ -0,0 +1,26 @@
+--TEST--
+GH-765: Fatal error triggered in PHPUnit when exception is thrown in data provider of a test with a dependency
+--FILE--
+<?php
+
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue765Test';
+$_SERVER['argv'][3] = __DIR__ . '/765/Issue765Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.W 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 warning:
+
+1) Warning
+The data provider specified for Issue765Test::testDependent is invalid.
+
+WARNINGS!
+Tests: 2, Assertions: 1, Warnings: 1.
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/765/Issue765Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/765/Issue765Test.php
new file mode 100644
index 0000000..a47474b
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/765/Issue765Test.php
@@ -0,0 +1,22 @@
+<?php
+class Issue765Test extends PHPUnit_Framework_TestCase
+{
+ public function testDependee()
+ {
+ $this->assertTrue(true);
+ }
+
+ /**
+ * @depends testDependee
+ * @dataProvider dependentProvider
+ */
+ public function testDependent($a)
+ {
+ $this->assertTrue(true);
+ }
+
+ public function dependentProvider()
+ {
+ throw new Exception;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/797.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/797.phpt
new file mode 100644
index 0000000..ea73fd1
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/797.phpt
@@ -0,0 +1,22 @@
+--TEST--
+GH-797: Disabled $preserveGlobalState does not load bootstrap.php.
+--FILE--
+<?php
+
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][] = '--process-isolation';
+$_SERVER['argv'][] = '--bootstrap';
+$_SERVER['argv'][] = __DIR__ . '/797/bootstrap797.php';
+$_SERVER['argv'][] = __DIR__ . '/797/Issue797Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/797/Issue797Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/797/Issue797Test.php
new file mode 100644
index 0000000..b1c1b8f
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/797/Issue797Test.php
@@ -0,0 +1,10 @@
+<?php
+class Issue797Test extends PHPUnit_Framework_TestCase
+{
+ protected $preserveGlobalState = false;
+
+ public function testBootstrapPhpIsExecutedInIsolation()
+ {
+ $this->assertEquals(GITHUB_ISSUE, 797);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/797/bootstrap797.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/797/bootstrap797.php
new file mode 100644
index 0000000..03890a3
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/797/bootstrap797.php
@@ -0,0 +1,6 @@
+<?php
+// If process isolation fails to include this file, then
+// PHPUnit_Framework_TestCase itself does not exist. :-)
+require __DIR__ . '/../../../bootstrap.php';
+
+const GITHUB_ISSUE = 797;
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/863.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/863.phpt
new file mode 100644
index 0000000..2f13e9b
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/863.phpt
@@ -0,0 +1,24 @@
+--TEST--
+GH-863: Number of tests to run calculated incorrectly when --repeat is used
+--FILE--
+<?php
+
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--repeat';
+$_SERVER['argv'][3] = '50';
+$_SERVER['argv'][4] = 'BankAccountTest';
+$_SERVER['argv'][5] = dirname(dirname(__DIR__)) . '/_files/BankAccountTest.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+............................................................... 63 / 150 ( 42%)
+............................................................... 126 / 150 ( 84%)
+........................ 150 / 150 (100%)
+
+Time: %s, Memory: %s
+
+OK (150 tests, 150 assertions)
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/873-php5.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/873-php5.phpt
new file mode 100644
index 0000000..3bf1e9a
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/873-php5.phpt
@@ -0,0 +1,22 @@
+--TEST--
+GH-873: PHPUnit suppresses exceptions thrown outside of test case function
+--SKIPIF--
+<?php
+if (PHP_MAJOR_VERSION > 5) {
+ print 'skip: PHP 5 is required';
+}
+?>
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue873Test';
+$_SERVER['argv'][3] = __DIR__ . '/873/Issue873Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+
+Fatal error: Uncaught exception 'Exception' with message 'PHPUnit suppresses exceptions thrown outside of test case function' in %s:%i
+Stack trace:
+%a
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/873-php7.phpt b/vendor/phpunit/phpunit/tests/Regression/GitHub/873-php7.phpt
new file mode 100644
index 0000000..24974ac
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/873-php7.phpt
@@ -0,0 +1,22 @@
+--TEST--
+GH-873: PHPUnit suppresses exceptions thrown outside of test case function
+--SKIPIF--
+<?php
+if (PHP_MAJOR_VERSION < 7) {
+ print 'skip: PHP 7 is required';
+}
+?>
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue873Test';
+$_SERVER['argv'][3] = __DIR__ . '/873/Issue873Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+
+Fatal error: Uncaught Exception: PHPUnit suppresses exceptions thrown outside of test case function in %s:%i
+Stack trace:
+%a
diff --git a/vendor/phpunit/phpunit/tests/Regression/GitHub/873/Issue873Test.php b/vendor/phpunit/phpunit/tests/Regression/GitHub/873/Issue873Test.php
new file mode 100644
index 0000000..70fd904
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/GitHub/873/Issue873Test.php
@@ -0,0 +1,9 @@
+<?php
+
+if (extension_loaded('xdebug')) {
+ xdebug_disable();
+}
+
+ throw new Exception(
+ 'PHPUnit suppresses exceptions thrown outside of test case function'
+ );
diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/1021.phpt b/vendor/phpunit/phpunit/tests/Regression/Trac/1021.phpt
new file mode 100644
index 0000000..9f65239
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/Trac/1021.phpt
@@ -0,0 +1,19 @@
+--TEST--
+#1021: Depending on a test that uses a data provider does not work
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue1021Test';
+$_SERVER['argv'][3] = __DIR__ . '/1021/Issue1021Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.. 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+OK (2 tests, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/1021/Issue1021Test.php b/vendor/phpunit/phpunit/tests/Regression/Trac/1021/Issue1021Test.php
new file mode 100644
index 0000000..c8fa4c7
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/Trac/1021/Issue1021Test.php
@@ -0,0 +1,23 @@
+<?php
+class Issue1021Test extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider provider
+ */
+ public function testSomething($data)
+ {
+ $this->assertTrue($data);
+ }
+
+ /**
+ * @depends testSomething
+ */
+ public function testSomethingElse()
+ {
+ }
+
+ public function provider()
+ {
+ return [[true]];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/523.phpt b/vendor/phpunit/phpunit/tests/Regression/Trac/523.phpt
new file mode 100644
index 0000000..55f7059
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/Trac/523.phpt
@@ -0,0 +1,19 @@
+--TEST--
+#523: assertAttributeEquals does not work with classes extending ArrayIterator
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue523Test';
+$_SERVER['argv'][3] = __DIR__ . '/523/Issue523Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/523/Issue523Test.php b/vendor/phpunit/phpunit/tests/Regression/Trac/523/Issue523Test.php
new file mode 100644
index 0000000..80124f1
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/Trac/523/Issue523Test.php
@@ -0,0 +1,13 @@
+<?php
+class Issue523Test extends PHPUnit_Framework_TestCase
+{
+ public function testAttributeEquals()
+ {
+ $this->assertAttributeEquals('foo', 'field', new Issue523());
+ }
+};
+
+class Issue523 extends ArrayIterator
+{
+ protected $field = 'foo';
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/578.phpt b/vendor/phpunit/phpunit/tests/Regression/Trac/578.phpt
new file mode 100644
index 0000000..9f3c00c
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/Trac/578.phpt
@@ -0,0 +1,37 @@
+--TEST--
+#578: Double printing of trace line for exceptions from notices and warnings
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue578Test';
+$_SERVER['argv'][3] = __DIR__ . '/578/Issue578Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+EEE 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+There were 3 errors:
+
+1) Issue578Test::testNoticesDoublePrintStackTrace
+Invalid error type specified
+
+%sIssue578Test.php:%i
+
+2) Issue578Test::testWarningsDoublePrintStackTrace
+Invalid error type specified
+
+%sIssue578Test.php:%i
+
+3) Issue578Test::testUnexpectedExceptionsPrintsCorrectly
+Exception: Double printed exception
+
+%sIssue578Test.php:%i
+
+ERRORS!
+Tests: 3, Assertions: 0, Errors: 3.
diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/578/Issue578Test.php b/vendor/phpunit/phpunit/tests/Regression/Trac/578/Issue578Test.php
new file mode 100644
index 0000000..262d97f
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/Trac/578/Issue578Test.php
@@ -0,0 +1,20 @@
+<?php
+class Issue578Test extends PHPUnit_Framework_TestCase
+{
+ public function testNoticesDoublePrintStackTrace()
+ {
+ $this->iniSet('error_reporting', E_ALL | E_NOTICE);
+ trigger_error('Stack Trace Test Notice', E_NOTICE);
+ }
+
+ public function testWarningsDoublePrintStackTrace()
+ {
+ $this->iniSet('error_reporting', E_ALL | E_NOTICE);
+ trigger_error('Stack Trace Test Notice', E_WARNING);
+ }
+
+ public function testUnexpectedExceptionsPrintsCorrectly()
+ {
+ throw new Exception('Double printed exception');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/684.phpt b/vendor/phpunit/phpunit/tests/Regression/Trac/684.phpt
new file mode 100644
index 0000000..b7ab70e
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/Trac/684.phpt
@@ -0,0 +1,25 @@
+--TEST--
+#684: Unable to find test class when no test methods exists
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'Issue684Test';
+$_SERVER['argv'][3] = __DIR__ . '/684/Issue684Test.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+W 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 warning:
+
+1) Warning
+No tests found in class "Foo_Bar_Issue684Test".
+
+WARNINGS!
+Tests: 1, Assertions: 0, Warnings: 1.
diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/684/Issue684Test.php b/vendor/phpunit/phpunit/tests/Regression/Trac/684/Issue684Test.php
new file mode 100644
index 0000000..e8e5d87
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/Trac/684/Issue684Test.php
@@ -0,0 +1,4 @@
+<?php
+class Foo_Bar_Issue684Test extends PHPUnit_Framework_TestCase
+{
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/783.phpt b/vendor/phpunit/phpunit/tests/Regression/Trac/783.phpt
new file mode 100644
index 0000000..260ca06
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/Trac/783.phpt
@@ -0,0 +1,21 @@
+--TEST--
+#783: Tests getting executed twice when using multiple groups
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--group';
+$_SERVER['argv'][3] = 'foo,bar';
+$_SERVER['argv'][4] = 'ParentSuite';
+$_SERVER['argv'][5] = __DIR__ . '/783/ParentSuite.php';
+
+require __DIR__ . '/../../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.. 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+OK (2 tests, 0 assertions)
diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/783/ChildSuite.php b/vendor/phpunit/phpunit/tests/Regression/Trac/783/ChildSuite.php
new file mode 100644
index 0000000..8bac514
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/Trac/783/ChildSuite.php
@@ -0,0 +1,15 @@
+<?php
+require_once 'OneTest.php';
+require_once 'TwoTest.php';
+
+class ChildSuite
+{
+ public static function suite()
+ {
+ $suite = new PHPUnit_Framework_TestSuite('Child');
+ $suite->addTestSuite('OneTest');
+ $suite->addTestSuite('TwoTest');
+
+ return $suite;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/783/OneTest.php b/vendor/phpunit/phpunit/tests/Regression/Trac/783/OneTest.php
new file mode 100644
index 0000000..7195158
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/Trac/783/OneTest.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * @group foo
+ */
+class OneTest extends PHPUnit_Framework_TestCase
+{
+ public function testSomething()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/783/ParentSuite.php b/vendor/phpunit/phpunit/tests/Regression/Trac/783/ParentSuite.php
new file mode 100644
index 0000000..6dd63e2
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/Trac/783/ParentSuite.php
@@ -0,0 +1,13 @@
+<?php
+require_once 'ChildSuite.php';
+
+class ParentSuite
+{
+ public static function suite()
+ {
+ $suite = new PHPUnit_Framework_TestSuite('Parent');
+ $suite->addTest(ChildSuite::suite());
+
+ return $suite;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Regression/Trac/783/TwoTest.php b/vendor/phpunit/phpunit/tests/Regression/Trac/783/TwoTest.php
new file mode 100644
index 0000000..580246c
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Regression/Trac/783/TwoTest.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * @group bar
+ */
+class TwoTest extends PHPUnit_Framework_TestCase
+{
+ public function testSomething()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Runner/BaseTestRunnerTest.php b/vendor/phpunit/phpunit/tests/Runner/BaseTestRunnerTest.php
new file mode 100644
index 0000000..be8679e
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Runner/BaseTestRunnerTest.php
@@ -0,0 +1,18 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Runner_BaseTestRunnerTest extends PHPUnit_Framework_TestCase
+{
+ public function testInvokeNonStaticSuite()
+ {
+ $runner = new MockRunner;
+ $runner->getTest('NonStatic');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/TextUI/_files/expect_external.txt b/vendor/phpunit/phpunit/tests/TextUI/_files/expect_external.txt
new file mode 100644
index 0000000..5e1c309
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/_files/expect_external.txt
@@ -0,0 +1 @@
+Hello World \ No newline at end of file
diff --git a/vendor/phpunit/phpunit/tests/TextUI/_files/phpt-env.expected.txt b/vendor/phpunit/phpunit/tests/TextUI/_files/phpt-env.expected.txt
new file mode 100644
index 0000000..ef75baf
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/_files/phpt-env.expected.txt
@@ -0,0 +1 @@
+string(%d) "%s"
diff --git a/vendor/phpunit/phpunit/tests/TextUI/_files/phpt_external.php b/vendor/phpunit/phpunit/tests/TextUI/_files/phpt_external.php
new file mode 100644
index 0000000..e0705ac
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/_files/phpt_external.php
@@ -0,0 +1,2 @@
+<?php
+echo 'Hello World';
diff --git a/vendor/phpunit/phpunit/tests/TextUI/abstract-test-class.phpt b/vendor/phpunit/phpunit/tests/TextUI/abstract-test-class.phpt
new file mode 100644
index 0000000..34e3a5e
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/abstract-test-class.phpt
@@ -0,0 +1,24 @@
+--TEST--
+phpunit AbstractTest ../_files/AbstractTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'AbstractTest';
+$_SERVER['argv'][3] = __DIR__ . '/../_files/AbstractTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+W 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 warning:
+
+1) Warning
+Cannot instantiate class "AbstractTest".
+
+WARNINGS!
+Tests: 1, Assertions: 0, Warnings: 1.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/assertion.phpt b/vendor/phpunit/phpunit/tests/TextUI/assertion.phpt
new file mode 100644
index 0000000..71de0fb
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/assertion.phpt
@@ -0,0 +1,38 @@
+--TEST--
+phpunit AssertionExampleTest ../_files/AssertionExampleTest.php
+--SKIPIF--
+<?php
+if (PHP_MAJOR_VERSION < 7) {
+ print 'skip: PHP 7 is required' . PHP_EOL;
+}
+
+if (ini_get('zend.assertions') != 1) {
+ print 'skip: zend.assertions=1 is required' . PHP_EOL;
+}
+
+if (ini_get('assert.exception') != 1) {
+ print 'skip: assert.exception=1 is required' . PHP_EOL;
+}
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'AssertionExampleTest';
+$_SERVER['argv'][3] = __DIR__ . '/../_files/AssertionExampleTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+F 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 failure:
+
+1) AssertionExampleTest::testOne
+assert(false) in %sAssertionExample.php:%d
+
+FAILURES!
+Tests: 1, Assertions: 1, Failures: 1.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/code-coverage-ignore.phpt b/vendor/phpunit/phpunit/tests/TextUI/code-coverage-ignore.phpt
new file mode 100644
index 0000000..79a0a18
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/code-coverage-ignore.phpt
@@ -0,0 +1,36 @@
+--TEST--
+phpunit --colors=never --coverage-text=php://stdout IgnoreCodeCoverageClassTest ../_files/IgnoreCodeCoverageClassTest.php --whitelist ../../tests/_files/IgnoreCodeCoverageClass.php
+--SKIPIF--
+<?php
+if (!extension_loaded('xdebug')) {
+ print 'skip: Extension xdebug is required.';
+}
+?>
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--colors=never';
+$_SERVER['argv'][3] = '--coverage-text=php://stdout';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/IgnoreCodeCoverageClassTest.php';
+$_SERVER['argv'][5] = '--whitelist';
+$_SERVER['argv'][6] = __DIR__ . '/../_files/IgnoreCodeCoverageClass.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.. 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+OK (2 tests, 2 assertions)
+
+
+Code Coverage Report:%w
+%s
+%w
+ Summary:%w
+ Classes:%w(0/0)%w
+ Methods:%w(0/0)%w
+ Lines:%w(0/0)%w \ No newline at end of file
diff --git a/vendor/phpunit/phpunit/tests/TextUI/colors-always.phpt b/vendor/phpunit/phpunit/tests/TextUI/colors-always.phpt
new file mode 100644
index 0000000..996b334
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/colors-always.phpt
@@ -0,0 +1,18 @@
+--TEST--
+phpunit --colors=always BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--colors=always';
+$_SERVER['argv'][3] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+... 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+%s[30;42mOK (3 tests, 3 assertions)%s[0m
diff --git a/vendor/phpunit/phpunit/tests/TextUI/concrete-test-class.phpt b/vendor/phpunit/phpunit/tests/TextUI/concrete-test-class.phpt
new file mode 100644
index 0000000..85e9243
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/concrete-test-class.phpt
@@ -0,0 +1,18 @@
+--TEST--
+phpunit ConcreteTest ../_files/ConcreteTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'ConcreteTest';
+$_SERVER['argv'][3] = __DIR__ . '/../_files/ConcreteTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.. 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+OK (2 tests, 0 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/custom-printer-debug.phpt b/vendor/phpunit/phpunit/tests/TextUI/custom-printer-debug.phpt
new file mode 100644
index 0000000..183ad3a
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/custom-printer-debug.phpt
@@ -0,0 +1,26 @@
+--TEST--
+phpunit -c ../_files/configuration.custom-printer.xml --debug BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '-c';
+$_SERVER['argv'][2] = __DIR__ . '/../_files/configuration.custom-printer.xml';
+$_SERVER['argv'][3] = '--debug';
+$_SERVER['argv'][4] = 'BankAccountTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+
+Starting test 'BankAccountTest::testBalanceIsInitiallyZero'.
+.
+Starting test 'BankAccountTest::testBalanceCannotBecomeNegative'.
+.
+Starting test 'BankAccountTest::testBalanceCannotBecomeNegative2'.
+. 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/custom-printer-verbose.phpt b/vendor/phpunit/phpunit/tests/TextUI/custom-printer-verbose.phpt
new file mode 100644
index 0000000..c90cd52
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/custom-printer-verbose.phpt
@@ -0,0 +1,31 @@
+--TEST--
+phpunit -c ../_files/configuration.custom-printer.xml --verbose IncompleteTest ../_files/IncompleteTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '-c';
+$_SERVER['argv'][2] = __DIR__ . '/../_files/configuration.custom-printer.xml';
+$_SERVER['argv'][3] = '--verbose';
+$_SERVER['argv'][4] = 'IncompleteTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/IncompleteTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+Runtime: %s
+Configuration: %sconfiguration.custom-printer.xml
+
+I 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 incomplete test:
+
+1) IncompleteTest::testIncomplete
+Test incomplete
+
+%s
+
+OK, but incomplete, skipped, or risky tests!
+Tests: 1, Assertions: 0, Incomplete: 1.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/dataprovider-debug.phpt b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-debug.phpt
new file mode 100644
index 0000000..b4f1e51
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-debug.phpt
@@ -0,0 +1,33 @@
+--TEST--
+phpunit --debug DataProviderDebugTest ../_files/DataProviderDebugTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--debug';
+$_SERVER['argv'][3] = 'DataProviderDebugTest';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/DataProviderDebugTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+
+Starting test 'DataProviderDebugTest::testProvider with data set #0 (null, true, 1, 1.0)'.
+.
+Starting test 'DataProviderDebugTest::testProvider with data set #1 (1.2, resource(%d) of type (stream), '1')'.
+.
+Starting test 'DataProviderDebugTest::testProvider with data set #2 (array(array(1, 2, 3), array(3, 4, 5)))'.
+.
+Starting test 'DataProviderDebugTest::testProvider with data set #3 ('this\nis\na\nvery\nvery\nvery\nvery...g\ntext')'.
+.
+Starting test 'DataProviderDebugTest::testProvider with data set #4 (stdClass Object (), stdClass Object (...), array(), SplObjectStorage Object (...), stdClass Object (...))'.
+.
+Starting test 'DataProviderDebugTest::testProvider with data set #5 (Binary String: 0x000102030405, Binary String: 0x0e0f101112131...c1d1e1f)'.
+.
+Starting test 'DataProviderDebugTest::testProvider with data set #6 (Binary String: 0x0009)'.
+. 7 / 7 (100%)
+
+Time: %s, Memory: %s
+
+OK (7 tests, 7 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/dataprovider-issue-2833.phpt b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-issue-2833.phpt
new file mode 100644
index 0000000..6381898
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-issue-2833.phpt
@@ -0,0 +1,17 @@
+--TEST--
+phpunit ../_files/DataProviderIssue2833
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = __DIR__ . '/../_files/DataProviderIssue2833';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.. 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+OK (2 tests, 2 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/dataprovider-issue-2859.phpt b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-issue-2859.phpt
new file mode 100644
index 0000000..3458820
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-issue-2859.phpt
@@ -0,0 +1,17 @@
+--TEST--
+phpunit -c ../_files/DataProviderIssue2859/phpunit.xml
+--FILE--
+<?php
+$_SERVER['argv'][1] = '-c';
+$_SERVER['argv'][2] = __DIR__ . '/../_files/DataProviderIssue2859/phpunit.xml';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/dataprovider-issue-2922.phpt b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-issue-2922.phpt
new file mode 100644
index 0000000..3de85a9
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-issue-2922.phpt
@@ -0,0 +1,18 @@
+--TEST--
+phpunit --exclude-group=foo ../_files/DataProviderIssue2922
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--exclude-group=foo';
+$_SERVER['argv'][3] = __DIR__ . '/../_files/DataProviderIssue2922';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/dataprovider-log-xml-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-log-xml-isolation.phpt
new file mode 100644
index 0000000..c8c1b83
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-log-xml-isolation.phpt
@@ -0,0 +1,46 @@
+--TEST--
+phpunit --process-isolation --log-junit php://stdout DataProviderTest ../_files/DataProviderTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = '--log-junit';
+$_SERVER['argv'][4] = 'php://stdout';
+$_SERVER['argv'][5] = 'DataProviderTest';
+$_SERVER['argv'][6] = __DIR__ . '/../_files/DataProviderTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+..F. 4 / 4 (100%)<?xml version="1.0" encoding="UTF-8"?>
+<testsuites>
+ <testsuite name="DataProviderTest" file="%sDataProviderTest.php" tests="4" assertions="4" failures="1" errors="0" time="%f">
+ <testsuite name="DataProviderTest::testAdd" tests="4" assertions="4" failures="1" errors="0" time="%f">
+ <testcase name="testAdd with data set #0" assertions="1" time="%f"/>
+ <testcase name="testAdd with data set #1" assertions="1" time="%f"/>
+ <testcase name="testAdd with data set #2" assertions="1" time="%f">
+ <failure type="PHPUnit_Framework_ExpectationFailedException">DataProviderTest::testAdd with data set #2 (1, 1, 3)
+Failed asserting that 2 matches expected 3.
+
+%s:%i
+</failure>
+ </testcase>
+ <testcase name="testAdd with data set #3" assertions="1" time="%f"/>
+ </testsuite>
+ </testsuite>
+</testsuites>
+
+
+Time: %s, Memory: %s
+
+There was 1 failure:
+
+1) DataProviderTest::testAdd with data set #2 (1, 1, 3)
+Failed asserting that 2 matches expected 3.
+
+%s:%i
+
+FAILURES!
+Tests: 4, Assertions: 4, Failures: 1.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/dataprovider-log-xml.phpt b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-log-xml.phpt
new file mode 100644
index 0000000..4832d12
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-log-xml.phpt
@@ -0,0 +1,45 @@
+--TEST--
+phpunit --log-junit php://stdout DataProviderTest ../_files/DataProviderTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--log-junit';
+$_SERVER['argv'][3] = 'php://stdout';
+$_SERVER['argv'][4] = 'DataProviderTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/DataProviderTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+..F. 4 / 4 (100%)<?xml version="1.0" encoding="UTF-8"?>
+<testsuites>
+ <testsuite name="DataProviderTest" file="%sDataProviderTest.php" tests="4" assertions="4" failures="1" errors="0" time="%f">
+ <testsuite name="DataProviderTest::testAdd" tests="4" assertions="4" failures="1" errors="0" time="%f">
+ <testcase name="testAdd with data set #0" assertions="1" time="%f"/>
+ <testcase name="testAdd with data set #1" assertions="1" time="%f"/>
+ <testcase name="testAdd with data set #2" assertions="1" time="%f">
+ <failure type="PHPUnit_Framework_ExpectationFailedException">DataProviderTest::testAdd with data set #2 (1, 1, 3)
+Failed asserting that 2 matches expected 3.
+
+%s:%i
+</failure>
+ </testcase>
+ <testcase name="testAdd with data set #3" assertions="1" time="%f"/>
+ </testsuite>
+ </testsuite>
+</testsuites>
+
+
+Time: %s, Memory: %s
+
+There was 1 failure:
+
+1) DataProviderTest::testAdd with data set #2 (1, 1, 3)
+Failed asserting that 2 matches expected 3.
+
+%s:%i
+
+FAILURES!
+Tests: 4, Assertions: 4, Failures: 1.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/dataprovider-testdox.phpt b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-testdox.phpt
new file mode 100644
index 0000000..6d04a3c
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/dataprovider-testdox.phpt
@@ -0,0 +1,19 @@
+--TEST--
+phpunit DataProviderTestDoxTest ../_files/DataProviderTestDoxTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--testdox';
+$_SERVER['argv'][3] = 'DataProviderTestDoxTest';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/DataProviderTestDoxTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+DataProviderTestDox
+ [x] Does something with one
+ [x] Does something with two
+ [x] Does something else with one
+ [x] Does something else with two
diff --git a/vendor/phpunit/phpunit/tests/TextUI/debug.phpt b/vendor/phpunit/phpunit/tests/TextUI/debug.phpt
new file mode 100644
index 0000000..8da0eea
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/debug.phpt
@@ -0,0 +1,25 @@
+--TEST--
+phpunit --debug BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--debug';
+$_SERVER['argv'][3] = 'BankAccountTest';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+
+Starting test 'BankAccountTest::testBalanceIsInitiallyZero'.
+.
+Starting test 'BankAccountTest::testBalanceCannotBecomeNegative'.
+.
+Starting test 'BankAccountTest::testBalanceCannotBecomeNegative2'.
+. 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/default-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/default-isolation.phpt
new file mode 100644
index 0000000..cd316a1
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/default-isolation.phpt
@@ -0,0 +1,19 @@
+--TEST--
+phpunit --process-isolation BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = 'BankAccountTest';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+... 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/default.phpt b/vendor/phpunit/phpunit/tests/TextUI/default.phpt
new file mode 100644
index 0000000..24ae89a
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/default.phpt
@@ -0,0 +1,18 @@
+--TEST--
+phpunit BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'BankAccountTest';
+$_SERVER['argv'][3] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+... 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/dependencies-clone.phpt b/vendor/phpunit/phpunit/tests/TextUI/dependencies-clone.phpt
new file mode 100644
index 0000000..a7ca51d
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/dependencies-clone.phpt
@@ -0,0 +1,22 @@
+--TEST--
+phpunit --verbose ClonedDependencyTest ../_files/ClonedDependencyTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--verbose';
+$_SERVER['argv'][3] = 'ClonedDependencyTest';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/ClonedDependencyTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+Runtime: %s
+
+.... 4 / 4 (100%)
+
+Time: %s, Memory: %s
+
+OK (4 tests, 3 assertions)
+
diff --git a/vendor/phpunit/phpunit/tests/TextUI/dependencies-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/dependencies-isolation.phpt
new file mode 100644
index 0000000..b044eaa
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/dependencies-isolation.phpt
@@ -0,0 +1,42 @@
+--TEST--
+phpunit --process-isolation --verbose DependencyTestSuite ../_files/DependencyTestSuite.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = '--verbose';
+$_SERVER['argv'][4] = 'DependencyTestSuite';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/DependencyTestSuite.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+Runtime: %s
+
+...FSSS 7 / 7 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 failure:
+
+1) DependencyFailureTest::testOne
+
+%s:%i
+
+--
+
+There were 3 skipped tests:
+
+1) DependencyFailureTest::testTwo
+This test depends on "DependencyFailureTest::testOne" to pass.
+
+2) DependencyFailureTest::testThree
+This test depends on "DependencyFailureTest::testTwo" to pass.
+
+3) DependencyFailureTest::testFour
+This test depends on "DependencyFailureTest::testOne" to pass.
+
+FAILURES!
+Tests: 7, Assertions: 0, Failures: 1, Skipped: 3.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/dependencies.phpt b/vendor/phpunit/phpunit/tests/TextUI/dependencies.phpt
new file mode 100644
index 0000000..56e2dae
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/dependencies.phpt
@@ -0,0 +1,41 @@
+--TEST--
+phpunit --verbose DependencyTestSuite ../_files/DependencyTestSuite.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--verbose';
+$_SERVER['argv'][3] = 'DependencyTestSuite';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/DependencyTestSuite.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+Runtime: %s
+
+...FSSS 7 / 7 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 failure:
+
+1) DependencyFailureTest::testOne
+
+%s:%i
+
+--
+
+There were 3 skipped tests:
+
+1) DependencyFailureTest::testTwo
+This test depends on "DependencyFailureTest::testOne" to pass.
+
+2) DependencyFailureTest::testThree
+This test depends on "DependencyFailureTest::testTwo" to pass.
+
+3) DependencyFailureTest::testFour
+This test depends on "DependencyFailureTest::testOne" to pass.
+
+FAILURES!
+Tests: 7, Assertions: 0, Failures: 1, Skipped: 3.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/dependencies2-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/dependencies2-isolation.phpt
new file mode 100644
index 0000000..de5a46e
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/dependencies2-isolation.phpt
@@ -0,0 +1,19 @@
+--TEST--
+phpunit --process-isolation StackTest ../_files/StackTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = 'StackTest';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/StackTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.. 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+OK (2 tests, 5 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/dependencies2.phpt b/vendor/phpunit/phpunit/tests/TextUI/dependencies2.phpt
new file mode 100644
index 0000000..aba4e7a
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/dependencies2.phpt
@@ -0,0 +1,18 @@
+--TEST--
+phpunit StackTest ../_files/StackTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'StackTest';
+$_SERVER['argv'][3] = __DIR__ . '/../_files/StackTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.. 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+OK (2 tests, 5 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/dependencies3-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/dependencies3-isolation.phpt
new file mode 100644
index 0000000..30fee4d
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/dependencies3-isolation.phpt
@@ -0,0 +1,19 @@
+--TEST--
+phpunit --process-isolation MultiDependencyTest ../_files/MultiDependencyTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = 'MultiDependencyTest';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/MultiDependencyTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+... 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+OK (3 tests, 2 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/dependencies3.phpt b/vendor/phpunit/phpunit/tests/TextUI/dependencies3.phpt
new file mode 100644
index 0000000..c2b0fe8
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/dependencies3.phpt
@@ -0,0 +1,19 @@
+--TEST--
+phpunit MultiDependencyTest ../_files/MultiDependencyTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'MultiDependencyTest';
+$_SERVER['argv'][3] = __DIR__ . '/../_files/MultiDependencyTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+... 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+OK (3 tests, 2 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/disable-code-coverage-ignore.phpt b/vendor/phpunit/phpunit/tests/TextUI/disable-code-coverage-ignore.phpt
new file mode 100644
index 0000000..badeb16
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/disable-code-coverage-ignore.phpt
@@ -0,0 +1,40 @@
+--TEST--
+phpunit --colors=never --coverage-text=php://stdout --disable-coverage-ignore IgnoreCodeCoverageClassTest tests/_files/IgnoreCodeCoverageClassTest.php --whitelist ../../tests/_files/IgnoreCodeCoverageClass.php
+--SKIPIF--
+<?php
+if (!extension_loaded('xdebug')) {
+ print 'skip: Extension xdebug is required.';
+}
+?>
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--colors=never';
+$_SERVER['argv'][3] = '--coverage-text=php://stdout';
+$_SERVER['argv'][4] = '--disable-coverage-ignore';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/IgnoreCodeCoverageClassTest.php';
+$_SERVER['argv'][6] = '--whitelist';
+$_SERVER['argv'][7] = __DIR__ . '/../_files/IgnoreCodeCoverageClass.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.. 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+OK (2 tests, 2 assertions)
+
+
+Code Coverage Report:%w
+%s
+%w
+ Summary:%w
+ Classes: 100.00% (1/1)%w
+ Methods: 100.00% (2/2)%w
+ Lines:%s
+
+IgnoreCodeCoverageClass
+ Methods: 100.00% ( 2/ 2) Lines: 100.00% ( 2/ 2) \ No newline at end of file
diff --git a/vendor/phpunit/phpunit/tests/TextUI/empty-testcase.phpt b/vendor/phpunit/phpunit/tests/TextUI/empty-testcase.phpt
new file mode 100644
index 0000000..d3fbf9c
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/empty-testcase.phpt
@@ -0,0 +1,25 @@
+--TEST--
+phpunit EmptyTestCaseTest ../_files/EmptyTestCaseTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'EmptyTestCaseTest';
+$_SERVER['argv'][3] = __DIR__ . '/../_files/EmptyTestCaseTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+W 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 warning:
+
+1) Warning
+No tests found in class "EmptyTestCaseTest".
+
+WARNINGS!
+Tests: 1, Assertions: 0, Warnings: 1.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/exception-stack.phpt b/vendor/phpunit/phpunit/tests/TextUI/exception-stack.phpt
new file mode 100644
index 0000000..e8b5377
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/exception-stack.phpt
@@ -0,0 +1,64 @@
+--TEST--
+phpunit ExceptionStackTest ../_files/ExceptionStackTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'ExceptionStackTest';
+$_SERVER['argv'][3] = __DIR__ . '/../_files/ExceptionStackTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+EE 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+There were 2 errors:
+
+1) ExceptionStackTest::testPrintingChildException
+PHPUnit_Framework_Exception: Child exception
+message
+Failed asserting that two arrays are equal.
+--- Expected
++++ Actual
+@@ @@
+ Array (
+- 0 => 1
++ 0 => 2
+ )
+
+
+%s:%i
+
+Caused by
+message
+Failed asserting that two arrays are equal.
+--- Expected
++++ Actual
+@@ @@
+ Array (
+- 0 => 1
++ 0 => 2
+ )
+
+%s:%i
+
+2) ExceptionStackTest::testNestedExceptions
+Exception: One
+
+%s:%i
+
+Caused by
+InvalidArgumentException: Two
+
+%s:%i
+
+Caused by
+Exception: Three
+
+%s:%i
+
+ERRORS!
+Tests: 2, Assertions: 1, Errors: 2.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/exclude-group-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/exclude-group-isolation.phpt
new file mode 100644
index 0000000..1686912
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/exclude-group-isolation.phpt
@@ -0,0 +1,21 @@
+--TEST--
+phpunit --process-isolation --exclude-group balanceIsInitiallyZero BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = '--exclude-group';
+$_SERVER['argv'][4] = 'balanceIsInitiallyZero';
+$_SERVER['argv'][5] = 'BankAccountTest';
+$_SERVER['argv'][6] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.. 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+OK (2 tests, 2 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/exclude-group.phpt b/vendor/phpunit/phpunit/tests/TextUI/exclude-group.phpt
new file mode 100644
index 0000000..fde260b
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/exclude-group.phpt
@@ -0,0 +1,20 @@
+--TEST--
+phpunit --exclude-group balanceIsInitiallyZero BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--exclude-group';
+$_SERVER['argv'][3] = 'balanceIsInitiallyZero';
+$_SERVER['argv'][4] = 'BankAccountTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.. 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+OK (2 tests, 2 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/failure-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/failure-isolation.phpt
new file mode 100644
index 0000000..29b3ed6
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/failure-isolation.phpt
@@ -0,0 +1,141 @@
+--TEST--
+phpunit --process-isolation FailureTest ../_files/FailureTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = 'FailureTest';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/FailureTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+FFFFFFFFFFFFF 13 / 13 (100%)
+
+Time: %s, Memory: %s
+
+There were 13 failures:
+
+1) FailureTest::testAssertArrayEqualsArray
+message
+Failed asserting that two arrays are equal.
+--- Expected
++++ Actual
+@@ @@
+ Array (
+- 0 => 1
++ 0 => 2
+ )
+
+%s:%i
+
+2) FailureTest::testAssertIntegerEqualsInteger
+message
+Failed asserting that 2 matches expected 1.
+
+%s:%i
+
+3) FailureTest::testAssertObjectEqualsObject
+message
+Failed asserting that two objects are equal.
+--- Expected
++++ Actual
+@@ @@
+ stdClass Object (
+- 'foo' => 'bar'
++ 'bar' => 'foo'
+ )
+
+%s:%i
+
+4) FailureTest::testAssertNullEqualsString
+message
+Failed asserting that 'bar' matches expected null.
+
+%s:%i
+
+5) FailureTest::testAssertStringEqualsString
+message
+Failed asserting that two strings are equal.
+--- Expected
++++ Actual
+@@ @@
+-'foo'
++'bar'
+
+%s:%i
+
+6) FailureTest::testAssertTextEqualsText
+message
+Failed asserting that two strings are equal.
+--- Expected
++++ Actual
+@@ @@
+ 'foo
+-bar
++baz
+ '
+
+%s:%i
+
+7) FailureTest::testAssertStringMatchesFormat
+message
+Failed asserting that format description matches text.
+--- Expected
++++ Actual
+@@ @@
+-*%s*
++**
+
+%s:%i
+
+8) FailureTest::testAssertNumericEqualsNumeric
+message
+Failed asserting that 2 matches expected 1.
+
+%s:%i
+
+9) FailureTest::testAssertTextSameText
+message
+Failed asserting that two strings are identical.
+--- Expected
++++ Actual
+@@ @@
+-foo
++bar
+
+%s:%i
+
+10) FailureTest::testAssertObjectSameObject
+message
+Failed asserting that two variables reference the same object.
+
+%s:%i
+
+11) FailureTest::testAssertObjectSameNull
+message
+Failed asserting that null is identical to an object of class "stdClass".
+
+%s:%i
+
+12) FailureTest::testAssertFloatSameFloat
+message
+Failed asserting that 1.5 is identical to 1.0.
+
+%s:%i
+
+13) FailureTest::testAssertStringMatchesFormatFile
+Failed asserting that format description matches text.
+--- Expected
++++ Actual
+@@ @@
+-FOO
+-
++...BAR...
+
+%s:%i
+
+FAILURES!
+Tests: 13, Assertions: 14, Failures: 13.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/failure-reverse-list.phpt b/vendor/phpunit/phpunit/tests/TextUI/failure-reverse-list.phpt
new file mode 100644
index 0000000..eb2769f
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/failure-reverse-list.phpt
@@ -0,0 +1,141 @@
+--TEST--
+phpunit --reverse-list FailureTest ../_files/FailureTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--reverse-list';
+$_SERVER['argv'][3] = 'FailureTest';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/FailureTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+FFFFFFFFFFFFF 13 / 13 (100%)
+
+Time: %s, Memory: %s
+
+There were 13 failures:
+
+1) FailureTest::testAssertStringMatchesFormatFile
+Failed asserting that format description matches text.
+--- Expected
++++ Actual
+@@ @@
+-FOO
+-
++...BAR...
+
+%s:%d
+
+2) FailureTest::testAssertFloatSameFloat
+message
+Failed asserting that 1.5 is identical to 1.0.
+
+%s:%d
+
+3) FailureTest::testAssertObjectSameNull
+message
+Failed asserting that null is identical to an object of class "stdClass".
+
+%s:%d
+
+4) FailureTest::testAssertObjectSameObject
+message
+Failed asserting that two variables reference the same object.
+
+%s:%d
+
+5) FailureTest::testAssertTextSameText
+message
+Failed asserting that two strings are identical.
+--- Expected
++++ Actual
+@@ @@
+-foo
++bar
+
+%s:%d
+
+6) FailureTest::testAssertNumericEqualsNumeric
+message
+Failed asserting that 2 matches expected 1.
+
+%s:%d
+
+7) FailureTest::testAssertStringMatchesFormat
+message
+Failed asserting that format description matches text.
+--- Expected
++++ Actual
+@@ @@
+-*%s*
++**
+
+%s:%d
+
+8) FailureTest::testAssertTextEqualsText
+message
+Failed asserting that two strings are equal.
+--- Expected
++++ Actual
+@@ @@
+ 'foo
+-bar
++baz
+ '
+
+%s:%d
+
+9) FailureTest::testAssertStringEqualsString
+message
+Failed asserting that two strings are equal.
+--- Expected
++++ Actual
+@@ @@
+-'foo'
++'bar'
+
+%s:%d
+
+10) FailureTest::testAssertNullEqualsString
+message
+Failed asserting that 'bar' matches expected null.
+
+%s:%d
+
+11) FailureTest::testAssertObjectEqualsObject
+message
+Failed asserting that two objects are equal.
+--- Expected
++++ Actual
+@@ @@
+ stdClass Object (
+- 'foo' => 'bar'
++ 'bar' => 'foo'
+ )
+
+%s:22
+
+12) FailureTest::testAssertIntegerEqualsInteger
+message
+Failed asserting that 2 matches expected 1.
+
+%s:%d
+
+13) FailureTest::testAssertArrayEqualsArray
+message
+Failed asserting that two arrays are equal.
+--- Expected
++++ Actual
+@@ @@
+ Array (
+- 0 => 1
++ 0 => 2
+ )
+
+%s:%d
+
+FAILURES!
+Tests: 13, Assertions: 14, Failures: 13.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/failure.phpt b/vendor/phpunit/phpunit/tests/TextUI/failure.phpt
new file mode 100644
index 0000000..eb86a05
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/failure.phpt
@@ -0,0 +1,140 @@
+--TEST--
+phpunit FailureTest ../_files/FailureTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'FailureTest';
+$_SERVER['argv'][3] = __DIR__ . '/../_files/FailureTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+FFFFFFFFFFFFF 13 / 13 (100%)
+
+Time: %s, Memory: %s
+
+There were 13 failures:
+
+1) FailureTest::testAssertArrayEqualsArray
+message
+Failed asserting that two arrays are equal.
+--- Expected
++++ Actual
+@@ @@
+ Array (
+- 0 => 1
++ 0 => 2
+ )
+
+%s:%i
+
+2) FailureTest::testAssertIntegerEqualsInteger
+message
+Failed asserting that 2 matches expected 1.
+
+%s:%i
+
+3) FailureTest::testAssertObjectEqualsObject
+message
+Failed asserting that two objects are equal.
+--- Expected
++++ Actual
+@@ @@
+ stdClass Object (
+- 'foo' => 'bar'
++ 'bar' => 'foo'
+ )
+
+%s:%i
+
+4) FailureTest::testAssertNullEqualsString
+message
+Failed asserting that 'bar' matches expected null.
+
+%s:%i
+
+5) FailureTest::testAssertStringEqualsString
+message
+Failed asserting that two strings are equal.
+--- Expected
++++ Actual
+@@ @@
+-'foo'
++'bar'
+
+%s:%i
+
+6) FailureTest::testAssertTextEqualsText
+message
+Failed asserting that two strings are equal.
+--- Expected
++++ Actual
+@@ @@
+ 'foo
+-bar
++baz
+ '
+
+%s:%i
+
+7) FailureTest::testAssertStringMatchesFormat
+message
+Failed asserting that format description matches text.
+--- Expected
++++ Actual
+@@ @@
+-*%s*
++**
+
+%s:%i
+
+8) FailureTest::testAssertNumericEqualsNumeric
+message
+Failed asserting that 2 matches expected 1.
+
+%s:%i
+
+9) FailureTest::testAssertTextSameText
+message
+Failed asserting that two strings are identical.
+--- Expected
++++ Actual
+@@ @@
+-foo
++bar
+
+%s:%i
+
+10) FailureTest::testAssertObjectSameObject
+message
+Failed asserting that two variables reference the same object.
+
+%s:%i
+
+11) FailureTest::testAssertObjectSameNull
+message
+Failed asserting that null is identical to an object of class "stdClass".
+
+%s:%i
+
+12) FailureTest::testAssertFloatSameFloat
+message
+Failed asserting that 1.5 is identical to 1.0.
+
+%s:%i
+
+13) FailureTest::testAssertStringMatchesFormatFile
+Failed asserting that format description matches text.
+--- Expected
++++ Actual
+@@ @@
+-FOO
+-
++...BAR...
+
+%s:%i
+
+FAILURES!
+Tests: 13, Assertions: 14, Failures: 13.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/fatal-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/fatal-isolation.phpt
new file mode 100644
index 0000000..2d9347d
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/fatal-isolation.phpt
@@ -0,0 +1,25 @@
+--TEST--
+phpunit FatalTest --process-isolation ../_files/FatalTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = 'FatalTest';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/FatalTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+E 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 error:
+
+1) FatalTest::testFatalError
+%s
+
+ERRORS!
+Tests: 1, Assertions: 0, Errors: 1.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-class-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-class-isolation.phpt
new file mode 100644
index 0000000..56ae79b
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-class-isolation.phpt
@@ -0,0 +1,21 @@
+--TEST--
+phpunit --process-isolation --filter BankAccountTest BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = '--filter';
+$_SERVER['argv'][4] = 'BankAccountTest';
+$_SERVER['argv'][5] = 'BankAccountTest';
+$_SERVER['argv'][6] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+... 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-class.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-class.phpt
new file mode 100644
index 0000000..21f7898
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-class.phpt
@@ -0,0 +1,20 @@
+--TEST--
+phpunit --filter BankAccountTest BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--filter';
+$_SERVER['argv'][3] = 'BankAccountTest';
+$_SERVER['argv'][4] = 'BankAccountTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+... 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-classname-and-range-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-classname-and-range-isolation.phpt
new file mode 100644
index 0000000..208832a
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-classname-and-range-isolation.phpt
@@ -0,0 +1,21 @@
+--TEST--
+phpunit --process-isolation --filter DataProviderFilterTest#1-3 DataProviderFilterTest ../_files/DataProviderFilterTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = '--filter';
+$_SERVER['argv'][4] = 'DataProviderFilterTest#1-3';
+$_SERVER['argv'][5] = 'DataProviderFilterTest';
+$_SERVER['argv'][6] = __DIR__ . '/../_files/DataProviderFilterTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+... 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-classname-and-range.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-classname-and-range.phpt
new file mode 100644
index 0000000..f4b81e5
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-classname-and-range.phpt
@@ -0,0 +1,20 @@
+--TEST--
+phpunit --filter DataProviderFilterTest#1-3 DataProviderFilterTest ../_files/DataProviderFilterTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--filter';
+$_SERVER['argv'][3] = 'DataProviderFilterTest#1-3';
+$_SERVER['argv'][4] = 'DataProviderFilterTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/DataProviderFilterTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+... 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-number-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-number-isolation.phpt
new file mode 100644
index 0000000..2f33f1e
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-number-isolation.phpt
@@ -0,0 +1,21 @@
+--TEST--
+phpunit --process-isolation --filter testTrue#3 DataProviderFilterTest ../_files/DataProviderFilterTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = '--filter';
+$_SERVER['argv'][4] = 'testTrue#3';
+$_SERVER['argv'][5] = 'DataProviderFilterTest';
+$_SERVER['argv'][6] = __DIR__ . '/../_files/DataProviderFilterTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-number.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-number.phpt
new file mode 100644
index 0000000..1824806
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-number.phpt
@@ -0,0 +1,20 @@
+--TEST--
+phpunit --filter testTrue#3 DataProviderFilterTest ../_files/DataProviderFilterTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--filter';
+$_SERVER['argv'][3] = 'testTrue#3';
+$_SERVER['argv'][4] = 'DataProviderFilterTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/DataProviderFilterTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-range-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-range-isolation.phpt
new file mode 100644
index 0000000..e5ec16c
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-range-isolation.phpt
@@ -0,0 +1,21 @@
+--TEST--
+phpunit --process-isolation --filter \#1-3 DataProviderFilterTest ../_files/DataProviderFilterTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = '--filter';
+$_SERVER['argv'][4] = '#1-3';
+$_SERVER['argv'][5] = 'DataProviderFilterTest';
+$_SERVER['argv'][6] = __DIR__ . '/../_files/DataProviderFilterTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+... 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-range.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-range.phpt
new file mode 100644
index 0000000..cdfac8c
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-range.phpt
@@ -0,0 +1,20 @@
+--TEST--
+phpunit --filter \#1-3 DataProviderFilterTest ../_files/DataProviderFilterTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--filter';
+$_SERVER['argv'][3] = '#1-3';
+$_SERVER['argv'][4] = 'DataProviderFilterTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/DataProviderFilterTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+... 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-regexp-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-regexp-isolation.phpt
new file mode 100644
index 0000000..1ac3730
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-regexp-isolation.phpt
@@ -0,0 +1,21 @@
+--TEST--
+phpunit --process-isolation --filter @false.* DataProviderFilterTest ../_files/DataProviderFilterTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = '--filter';
+$_SERVER['argv'][4] = '@false.*';
+$_SERVER['argv'][5] = 'DataProviderFilterTest';
+$_SERVER['argv'][6] = __DIR__ . '/../_files/DataProviderFilterTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.. 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+OK (2 tests, 2 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-regexp.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-regexp.phpt
new file mode 100644
index 0000000..63c8f31
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-regexp.phpt
@@ -0,0 +1,20 @@
+--TEST--
+phpunit --filter @false.* DataProviderFilterTest ../_files/DataProviderFilterTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--filter';
+$_SERVER['argv'][3] = '@false.*';
+$_SERVER['argv'][4] = 'DataProviderFilterTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/DataProviderFilterTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.. 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+OK (2 tests, 2 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-string-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-string-isolation.phpt
new file mode 100644
index 0000000..b47c428
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-string-isolation.phpt
@@ -0,0 +1,21 @@
+--TEST--
+phpunit --process-isolation --filter @false\ test DataProviderFilterTest ../_files/DataProviderFilterTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = '--filter';
+$_SERVER['argv'][4] = '@false test';
+$_SERVER['argv'][5] = 'DataProviderFilterTest';
+$_SERVER['argv'][6] = __DIR__ . '/../_files/DataProviderFilterTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-string.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-string.phpt
new file mode 100644
index 0000000..82a91ca
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-only-string.phpt
@@ -0,0 +1,20 @@
+--TEST--
+phpunit --filter @false\ test DataProviderFilterTest ../_files/DataProviderFilterTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--filter';
+$_SERVER['argv'][3] = '@false test';
+$_SERVER['argv'][4] = 'DataProviderFilterTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/DataProviderFilterTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-range-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-range-isolation.phpt
new file mode 100644
index 0000000..dab3e74
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-range-isolation.phpt
@@ -0,0 +1,21 @@
+--TEST--
+phpunit --process-isolation --filter testTrue#1-3 DataProviderFilterTest ../_files/DataProviderFilterTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = '--filter';
+$_SERVER['argv'][4] = 'testTrue#1-3';
+$_SERVER['argv'][5] = 'DataProviderFilterTest';
+$_SERVER['argv'][6] = __DIR__ . '/../_files/DataProviderFilterTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+... 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-range.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-range.phpt
new file mode 100644
index 0000000..ec3bc74
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-range.phpt
@@ -0,0 +1,20 @@
+--TEST--
+phpunit --filter testTrue#1-3 DataProviderFilterTest ../_files/DataProviderFilterTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--filter';
+$_SERVER['argv'][3] = 'testTrue#1-3';
+$_SERVER['argv'][4] = 'DataProviderFilterTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/DataProviderFilterTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+... 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-regexp-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-regexp-isolation.phpt
new file mode 100644
index 0000000..70684b6
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-regexp-isolation.phpt
@@ -0,0 +1,21 @@
+--TEST--
+phpunit --process-isolation --filter testFalse@false.* DataProviderFilterTest ../_files/DataProviderFilterTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = '--filter';
+$_SERVER['argv'][4] = 'testFalse@false.*';
+$_SERVER['argv'][5] = 'DataProviderFilterTest';
+$_SERVER['argv'][6] = __DIR__ . '/../_files/DataProviderFilterTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.. 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+OK (2 tests, 2 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-regexp.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-regexp.phpt
new file mode 100644
index 0000000..dc98bc9
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-regexp.phpt
@@ -0,0 +1,20 @@
+--TEST--
+phpunit --filter testFalse@false.* DataProviderFilterTest ../_files/DataProviderFilterTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--filter';
+$_SERVER['argv'][3] = 'testFalse@false.*';
+$_SERVER['argv'][4] = 'DataProviderFilterTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/DataProviderFilterTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.. 2 / 2 (100%)
+
+Time: %s, Memory: %s
+
+OK (2 tests, 2 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-string-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-string-isolation.phpt
new file mode 100644
index 0000000..571ecfd
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-string-isolation.phpt
@@ -0,0 +1,21 @@
+--TEST--
+phpunit --process-isolation --filter testFalse@false\ test DataProviderFilterTest ../_files/DataProviderFilterTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = '--filter';
+$_SERVER['argv'][4] = 'testFalse@false test';
+$_SERVER['argv'][5] = 'DataProviderFilterTest';
+$_SERVER['argv'][6] = __DIR__ . '/../_files/DataProviderFilterTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-string.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-string.phpt
new file mode 100644
index 0000000..0c334af
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-dataprovider-by-string.phpt
@@ -0,0 +1,20 @@
+--TEST--
+phpunit --filter testFalse@false\ test DataProviderFilterTest ../_files/DataProviderFilterTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--filter';
+$_SERVER['argv'][3] = 'testFalse@false test';
+$_SERVER['argv'][4] = 'DataProviderFilterTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/DataProviderFilterTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-method-case-insensitive.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-method-case-insensitive.phpt
new file mode 100644
index 0000000..1d41489
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-method-case-insensitive.phpt
@@ -0,0 +1,20 @@
+--TEST--
+phpunit --filter /balanceIsInitiallyZero/i BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--filter';
+$_SERVER['argv'][3] = '/balanceIsInitiallyZero/i';
+$_SERVER['argv'][4] = 'BankAccountTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-method-case-sensitive-no-result.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-method-case-sensitive-no-result.phpt
new file mode 100644
index 0000000..0428e8e
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-method-case-sensitive-no-result.phpt
@@ -0,0 +1,20 @@
+--TEST--
+phpunit --filter balanceIsInitiallyZero BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--filter';
+$_SERVER['argv'][3] = '/balanceIsInitiallyZero/';
+$_SERVER['argv'][4] = 'BankAccountTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+
+
+Time: %s, Memory: %s
+
+No tests executed!
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-method-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-method-isolation.phpt
new file mode 100644
index 0000000..aba25e5
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-method-isolation.phpt
@@ -0,0 +1,21 @@
+--TEST--
+phpunit --process-isolation --filter testBalanceIsInitiallyZero BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = '--filter';
+$_SERVER['argv'][4] = 'testBalanceIsInitiallyZero';
+$_SERVER['argv'][5] = 'BankAccountTest';
+$_SERVER['argv'][6] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-method.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-method.phpt
new file mode 100644
index 0000000..e6b7492
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-method.phpt
@@ -0,0 +1,20 @@
+--TEST--
+phpunit --filter testBalanceIsInitiallyZero BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--filter';
+$_SERVER['argv'][3] = 'testBalanceIsInitiallyZero';
+$_SERVER['argv'][4] = 'BankAccountTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/filter-no-results.phpt b/vendor/phpunit/phpunit/tests/TextUI/filter-no-results.phpt
new file mode 100644
index 0000000..3685e11
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/filter-no-results.phpt
@@ -0,0 +1,20 @@
+--TEST--
+phpunit --filter doesNotExist BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--filter';
+$_SERVER['argv'][3] = 'doesNotExist';
+$_SERVER['argv'][4] = 'BankAccountTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+
+
+Time: %s, Memory: %s
+
+No tests executed!
diff --git a/vendor/phpunit/phpunit/tests/TextUI/forward-compatibility.phpt b/vendor/phpunit/phpunit/tests/TextUI/forward-compatibility.phpt
new file mode 100644
index 0000000..24ae89a
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/forward-compatibility.phpt
@@ -0,0 +1,18 @@
+--TEST--
+phpunit BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = 'BankAccountTest';
+$_SERVER['argv'][3] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+... 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/group-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/group-isolation.phpt
new file mode 100644
index 0000000..a533cd7
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/group-isolation.phpt
@@ -0,0 +1,21 @@
+--TEST--
+phpunit --process-isolation --group balanceIsInitiallyZero BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = '--group';
+$_SERVER['argv'][4] = 'balanceIsInitiallyZero';
+$_SERVER['argv'][5] = 'BankAccountTest';
+$_SERVER['argv'][6] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/group.phpt b/vendor/phpunit/phpunit/tests/TextUI/group.phpt
new file mode 100644
index 0000000..e45ff58
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/group.phpt
@@ -0,0 +1,20 @@
+--TEST--
+phpunit --group balanceIsInitiallyZero BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--group';
+$_SERVER['argv'][3] = 'balanceIsInitiallyZero';
+$_SERVER['argv'][4] = 'BankAccountTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/help.phpt b/vendor/phpunit/phpunit/tests/TextUI/help.phpt
new file mode 100644
index 0000000..997d08c
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/help.phpt
@@ -0,0 +1,99 @@
+--TEST--
+phpunit
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+Usage: phpunit [options] UnitTest [UnitTest.php]
+ phpunit [options] <directory>
+
+Code Coverage Options:
+
+ --coverage-clover <file> Generate code coverage report in Clover XML format.
+ --coverage-crap4j <file> Generate code coverage report in Crap4J XML format.
+ --coverage-html <dir> Generate code coverage report in HTML format.
+ --coverage-php <file> Export PHP_CodeCoverage object to file.
+ --coverage-text=<file> Generate code coverage report in text format.
+ Default: Standard output.
+ --coverage-xml <dir> Generate code coverage report in PHPUnit XML format.
+ --whitelist <dir> Whitelist <dir> for code coverage analysis.
+ --disable-coverage-ignore Disable annotations for ignoring code coverage.
+
+Logging Options:
+
+ --log-junit <file> Log test execution in JUnit XML format to file.
+ --log-teamcity <file> Log test execution in TeamCity format to file.
+ --testdox-html <file> Write agile documentation in HTML format to file.
+ --testdox-text <file> Write agile documentation in Text format to file.
+ --testdox-xml <file> Write agile documentation in XML format to file.
+ --reverse-list Print defects in reverse order
+
+Test Selection Options:
+
+ --filter <pattern> Filter which tests to run.
+ --testsuite <name> Filter which testsuite to run.
+ --group ... Only runs tests from the specified group(s).
+ --exclude-group ... Exclude tests from the specified group(s).
+ --list-groups List available test groups.
+ --list-suites List available test suites.
+ --test-suffix ... Only search for test in files with specified
+ suffix(es). Default: Test.php,.phpt
+
+Test Execution Options:
+
+ --report-useless-tests Be strict about tests that do not test anything.
+ --strict-coverage Be strict about @covers annotation usage.
+ --strict-global-state Be strict about changes to global state
+ --disallow-test-output Be strict about output during tests.
+ --disallow-resource-usage Be strict about resource usage during small tests.
+ --enforce-time-limit Enforce time limit based on test size.
+ --disallow-todo-tests Disallow @todo-annotated tests.
+
+ --process-isolation Run each test in a separate PHP process.
+ --no-globals-backup Do not backup and restore $GLOBALS for each test.
+ --static-backup Backup and restore static attributes for each test.
+
+ --colors=<flag> Use colors in output ("never", "auto" or "always").
+ --columns <n> Number of columns to use for progress output.
+ --columns max Use maximum number of columns for progress output.
+ --stderr Write to STDERR instead of STDOUT.
+ --stop-on-error Stop execution upon first error.
+ --stop-on-failure Stop execution upon first error or failure.
+ --stop-on-warning Stop execution upon first warning.
+ --stop-on-risky Stop execution upon first risky test.
+ --stop-on-skipped Stop execution upon first skipped test.
+ --stop-on-incomplete Stop execution upon first incomplete test.
+ --fail-on-warning Treat tests with warnings as failures.
+ --fail-on-risky Treat risky tests as failures.
+ -v|--verbose Output more verbose information.
+ --debug Display debugging information during test execution.
+
+ --loader <loader> TestSuiteLoader implementation to use.
+ --repeat <times> Runs the test(s) repeatedly.
+ --teamcity Report test execution progress in TeamCity format.
+ --testdox Report test execution progress in TestDox format.
+ --testdox-group Only include tests from the specified group(s).
+ --testdox-exclude-group Exclude tests from the specified group(s).
+ --printer <printer> TestListener implementation to use.
+
+Configuration Options:
+
+ --bootstrap <file> A "bootstrap" PHP file that is run before the tests.
+ -c|--configuration <file> Read configuration from XML file.
+ --no-configuration Ignore default configuration file (phpunit.xml).
+ --no-coverage Ignore code coverage configuration.
+ --no-extensions Do not load PHPUnit extensions.
+ --include-path <path(s)> Prepend PHP's include_path with given path(s).
+ -d key[=value] Sets a php.ini value.
+ --generate-configuration Generate configuration file with suggested settings.
+
+Miscellaneous Options:
+
+ -h|--help Prints this usage information.
+ --version Prints the version and exits.
+ --atleast-version <min> Checks that version is greater than min and exits.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/help2.phpt b/vendor/phpunit/phpunit/tests/TextUI/help2.phpt
new file mode 100644
index 0000000..aee3f9b
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/help2.phpt
@@ -0,0 +1,100 @@
+--TEST--
+phpunit --help
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--help';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+Usage: phpunit [options] UnitTest [UnitTest.php]
+ phpunit [options] <directory>
+
+Code Coverage Options:
+
+ --coverage-clover <file> Generate code coverage report in Clover XML format.
+ --coverage-crap4j <file> Generate code coverage report in Crap4J XML format.
+ --coverage-html <dir> Generate code coverage report in HTML format.
+ --coverage-php <file> Export PHP_CodeCoverage object to file.
+ --coverage-text=<file> Generate code coverage report in text format.
+ Default: Standard output.
+ --coverage-xml <dir> Generate code coverage report in PHPUnit XML format.
+ --whitelist <dir> Whitelist <dir> for code coverage analysis.
+ --disable-coverage-ignore Disable annotations for ignoring code coverage.
+
+Logging Options:
+
+ --log-junit <file> Log test execution in JUnit XML format to file.
+ --log-teamcity <file> Log test execution in TeamCity format to file.
+ --testdox-html <file> Write agile documentation in HTML format to file.
+ --testdox-text <file> Write agile documentation in Text format to file.
+ --testdox-xml <file> Write agile documentation in XML format to file.
+ --reverse-list Print defects in reverse order
+
+Test Selection Options:
+
+ --filter <pattern> Filter which tests to run.
+ --testsuite <name> Filter which testsuite to run.
+ --group ... Only runs tests from the specified group(s).
+ --exclude-group ... Exclude tests from the specified group(s).
+ --list-groups List available test groups.
+ --list-suites List available test suites.
+ --test-suffix ... Only search for test in files with specified
+ suffix(es). Default: Test.php,.phpt
+
+Test Execution Options:
+
+ --report-useless-tests Be strict about tests that do not test anything.
+ --strict-coverage Be strict about @covers annotation usage.
+ --strict-global-state Be strict about changes to global state
+ --disallow-test-output Be strict about output during tests.
+ --disallow-resource-usage Be strict about resource usage during small tests.
+ --enforce-time-limit Enforce time limit based on test size.
+ --disallow-todo-tests Disallow @todo-annotated tests.
+
+ --process-isolation Run each test in a separate PHP process.
+ --no-globals-backup Do not backup and restore $GLOBALS for each test.
+ --static-backup Backup and restore static attributes for each test.
+
+ --colors=<flag> Use colors in output ("never", "auto" or "always").
+ --columns <n> Number of columns to use for progress output.
+ --columns max Use maximum number of columns for progress output.
+ --stderr Write to STDERR instead of STDOUT.
+ --stop-on-error Stop execution upon first error.
+ --stop-on-failure Stop execution upon first error or failure.
+ --stop-on-warning Stop execution upon first warning.
+ --stop-on-risky Stop execution upon first risky test.
+ --stop-on-skipped Stop execution upon first skipped test.
+ --stop-on-incomplete Stop execution upon first incomplete test.
+ --fail-on-warning Treat tests with warnings as failures.
+ --fail-on-risky Treat risky tests as failures.
+ -v|--verbose Output more verbose information.
+ --debug Display debugging information during test execution.
+
+ --loader <loader> TestSuiteLoader implementation to use.
+ --repeat <times> Runs the test(s) repeatedly.
+ --teamcity Report test execution progress in TeamCity format.
+ --testdox Report test execution progress in TestDox format.
+ --testdox-group Only include tests from the specified group(s).
+ --testdox-exclude-group Exclude tests from the specified group(s).
+ --printer <printer> TestListener implementation to use.
+
+Configuration Options:
+
+ --bootstrap <file> A "bootstrap" PHP file that is run before the tests.
+ -c|--configuration <file> Read configuration from XML file.
+ --no-configuration Ignore default configuration file (phpunit.xml).
+ --no-coverage Ignore code coverage configuration.
+ --no-extensions Do not load PHPUnit extensions.
+ --include-path <path(s)> Prepend PHP's include_path with given path(s).
+ -d key[=value] Sets a php.ini value.
+ --generate-configuration Generate configuration file with suggested settings.
+
+Miscellaneous Options:
+
+ -h|--help Prints this usage information.
+ --version Prints the version and exits.
+ --atleast-version <min> Checks that version is greater than min and exits.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/ini-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/ini-isolation.phpt
new file mode 100644
index 0000000..5e85ce9
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/ini-isolation.phpt
@@ -0,0 +1,21 @@
+--TEST--
+phpunit --process-isolation -d default_mimetype=application/x-test IniTest ../_files/IniTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = '-d';
+$_SERVER['argv'][4] = 'default_mimetype=application/x-test';
+$_SERVER['argv'][5] = 'IniTest';
+$_SERVER['argv'][6] = __DIR__ . '/../_files/IniTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/list-groups.phpt b/vendor/phpunit/phpunit/tests/TextUI/list-groups.phpt
new file mode 100644
index 0000000..0e92fac
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/list-groups.phpt
@@ -0,0 +1,18 @@
+--TEST--
+phpunit --list-groups BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--list-groups';
+$_SERVER['argv'][3] = 'BankAccountTest';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+Available test group(s):
+ - balanceCannotBecomeNegative
+ - balanceIsInitiallyZero
+ - specification
diff --git a/vendor/phpunit/phpunit/tests/TextUI/list-suites.phpt b/vendor/phpunit/phpunit/tests/TextUI/list-suites.phpt
new file mode 100644
index 0000000..fbf9cac
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/list-suites.phpt
@@ -0,0 +1,16 @@
+--TEST--
+phpunit --list-suites --configuration=__DIR__.'/../_files/configuration.suites.xml'
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--list-suites';
+$_SERVER['argv'][2] = '--configuration';
+$_SERVER['argv'][3] = __DIR__.'/../_files/configuration.suites.xml';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+Available test suite(s):
+ - Suite One
+ - Suite Two
diff --git a/vendor/phpunit/phpunit/tests/TextUI/log-json-post-66021.phpt b/vendor/phpunit/phpunit/tests/TextUI/log-json-post-66021.phpt
new file mode 100644
index 0000000..3fee397
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/log-json-post-66021.phpt
@@ -0,0 +1,73 @@
+--TEST--
+phpunit --log-json php://stdout BankAccountTest ../_files/BankAccountTest.php
+--SKIPIF--
+<?php
+if (!defined('JSON_PRETTY_PRINT')) {
+ print 'skip: JSON_PRETTY_PRINT is required';
+} elseif (json_encode([], JSON_PRETTY_PRINT) != '[]') {
+ print 'skip: Does not have PHP #66021 (Blank line inside empty JSON array/object)';
+}
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--log-json';
+$_SERVER['argv'][3] = 'php://stdout';
+$_SERVER['argv'][4] = 'BankAccountTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+Warning: Deprecated JSON test listener used
+
+{
+ "event": "suiteStart",
+ "suite": "BankAccountTest",
+ "tests": 3
+}{
+ "event": "testStart",
+ "suite": "BankAccountTest",
+ "test": "BankAccountTest::testBalanceIsInitiallyZero"
+}.{
+ "event": "test",
+ "suite": "BankAccountTest",
+ "test": "BankAccountTest::testBalanceIsInitiallyZero",
+ "status": "pass",
+ "time": %f,
+ "trace": [],
+ "message": "",
+ "output": ""
+}{
+ "event": "testStart",
+ "suite": "BankAccountTest",
+ "test": "BankAccountTest::testBalanceCannotBecomeNegative"
+}.{
+ "event": "test",
+ "suite": "BankAccountTest",
+ "test": "BankAccountTest::testBalanceCannotBecomeNegative",
+ "status": "pass",
+ "time": %f,
+ "trace": [],
+ "message": "",
+ "output": ""
+}{
+ "event": "testStart",
+ "suite": "BankAccountTest",
+ "test": "BankAccountTest::testBalanceCannotBecomeNegative2"
+}. 3 / 3 (100%){
+ "event": "test",
+ "suite": "BankAccountTest",
+ "test": "BankAccountTest::testBalanceCannotBecomeNegative2",
+ "status": "pass",
+ "time": %f,
+ "trace": [],
+ "message": "",
+ "output": ""
+}
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/log-junit.phpt b/vendor/phpunit/phpunit/tests/TextUI/log-junit.phpt
new file mode 100644
index 0000000..eda5725
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/log-junit.phpt
@@ -0,0 +1,68 @@
+--TEST--
+phpunit --log-junit php://stdout --report-useless-tests StatusTest ../_files/StatusTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--log-junit';
+$_SERVER['argv'][3] = 'php://stdout';
+$_SERVER['argv'][4] = '--report-useless-tests';
+$_SERVER['argv'][5] = 'StatusTest';
+$_SERVER['argv'][6] = __DIR__ . '/../_files/StatusTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+?>
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.FEISRW 7 / 7 (100%)<?xml version="1.0" encoding="UTF-8"?>
+<testsuites>
+ <testsuite name="StatusTest" file="%s/StatusTest.php" tests="4" assertions="2" failures="1" errors="1" time="%s">
+ <testcase name="testSuccess" class="StatusTest" file="%s/StatusTest.php" line="%d" assertions="1" time="%s"/>
+ <testcase name="testFailure" class="StatusTest" file="%s/StatusTest.php" line="%d" assertions="1" time="%s">
+ <failure type="PHPUnit_Framework_ExpectationFailedException">StatusTest::testFailure
+Failed asserting that false is true.
+
+%s/StatusTest.php:%s
+</failure>
+ </testcase>
+ <testcase name="testError" class="StatusTest" file="%s/StatusTest.php" line="%d" assertions="0" time="%s">
+ <error type="Exception">StatusTest::testError
+Exception:%w
+
+%s/StatusTest.php:%d
+</error>
+ </testcase>
+ <testcase name="testWarning" class="StatusTest" file="%s/StatusTest.php" line="%d" assertions="0" time="%s"/>
+ </testsuite>
+</testsuites>
+
+
+Time: %s, Memory: %s
+
+There was 1 error:
+
+1) StatusTest::testError
+Exception:%w
+
+%s:%d
+
+--
+
+There was 1 warning:
+
+1) StatusTest::testWarning
+
+%s/StatusTest.php:%d
+
+--
+
+There was 1 failure:
+
+1) StatusTest::testFailure
+Failed asserting that false is true.
+
+%s/StatusTest.php:%d
+
+ERRORS!
+Tests: 7, Assertions: 2, Errors: 1, Failures: 1, Warnings: 1, Skipped: 1, Incomplete: 1, Risky: 1. \ No newline at end of file
diff --git a/vendor/phpunit/phpunit/tests/TextUI/log-tap.phpt b/vendor/phpunit/phpunit/tests/TextUI/log-tap.phpt
new file mode 100644
index 0000000..19773a8
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/log-tap.phpt
@@ -0,0 +1,27 @@
+--TEST--
+phpunit --log-tap php://stdout BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--log-tap';
+$_SERVER['argv'][3] = 'php://stdout';
+$_SERVER['argv'][4] = 'BankAccountTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+Warning: Deprecated TAP test listener used
+
+TAP version 13
+.ok 1 - BankAccountTest::testBalanceIsInitiallyZero
+.ok 2 - BankAccountTest::testBalanceCannotBecomeNegative
+. 3 / 3 (100%)ok 3 - BankAccountTest::testBalanceCannotBecomeNegative2
+1..3
+
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/log-teamcity.phpt b/vendor/phpunit/phpunit/tests/TextUI/log-teamcity.phpt
new file mode 100644
index 0000000..9bf9dca
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/log-teamcity.phpt
@@ -0,0 +1,38 @@
+--TEST--
+phpunit --log-teamcity php://stdout BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--log-teamcity';
+$_SERVER['argv'][3] = 'php://stdout';
+$_SERVER['argv'][4] = 'BankAccountTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+
+##teamcity[testCount count='3' flowId='%d']
+
+##teamcity[testSuiteStarted name='BankAccountTest' locationHint='php_qn://%s/tests/_files/BankAccountTest.php::\BankAccountTest' flowId='%d']
+
+##teamcity[testStarted name='testBalanceIsInitiallyZero' locationHint='php_qn://%s/tests/_files/BankAccountTest.php::\BankAccountTest::testBalanceIsInitiallyZero' flowId='%d']
+.
+##teamcity[testFinished name='testBalanceIsInitiallyZero' duration='%s' flowId='%d']
+
+##teamcity[testStarted name='testBalanceCannotBecomeNegative' locationHint='php_qn://%s/tests/_files/BankAccountTest.php::\BankAccountTest::testBalanceCannotBecomeNegative' flowId='%d']
+.
+##teamcity[testFinished name='testBalanceCannotBecomeNegative' duration='%s' flowId='%d']
+
+##teamcity[testStarted name='testBalanceCannotBecomeNegative2' locationHint='php_qn://%s/tests/_files/BankAccountTest.php::\BankAccountTest::testBalanceCannotBecomeNegative2' flowId='%d']
+. 3 / 3 (100%)
+##teamcity[testFinished name='testBalanceCannotBecomeNegative2' duration='%s' flowId='%d']
+
+##teamcity[testSuiteFinished name='BankAccountTest' flowId='%d']
+
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/mycommand.phpt b/vendor/phpunit/phpunit/tests/TextUI/mycommand.phpt
new file mode 100644
index 0000000..ca8c8c7
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/mycommand.phpt
@@ -0,0 +1,23 @@
+--TEST--
+phpunit BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--my-option=123';
+$_SERVER['argv'][3] = '--my-other-option';
+$_SERVER['argv'][4] = 'BankAccountTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+require __DIR__ . '/../_files/MyCommand.php';
+MyCommand::main();
+?>
+--EXPECTF--
+MyCommand::myHandler 123
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+... 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/options-after-arguments.phpt b/vendor/phpunit/phpunit/tests/TextUI/options-after-arguments.phpt
new file mode 100644
index 0000000..17711d1
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/options-after-arguments.phpt
@@ -0,0 +1,18 @@
+--TEST--
+phpunit BankAccountTest ../_files/BankAccountTest.php --colors
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = __DIR__ . '/../_files/BankAccountTest.php';
+$_SERVER['argv'][3] = '--colors=always';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+... 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+%s[30;42mOK (3 tests, 3 assertions)%s[0m
diff --git a/vendor/phpunit/phpunit/tests/TextUI/output-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/output-isolation.phpt
new file mode 100644
index 0000000..828fdfe
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/output-isolation.phpt
@@ -0,0 +1,20 @@
+--TEST--
+phpunit --process-isolation --filter testExpectOutputStringFooActualFoo ../_files/OutputTestCase.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--process-isolation';
+$_SERVER['argv'][3] = '--filter';
+$_SERVER['argv'][4] = 'testExpectOutputStringFooActualFoo';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/OutputTestCase.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/phar-extension-suppressed.phpt b/vendor/phpunit/phpunit/tests/TextUI/phar-extension-suppressed.phpt
new file mode 100644
index 0000000..70ee2f8
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/phar-extension-suppressed.phpt
@@ -0,0 +1,12 @@
+--TEST--
+phpunit --configuration tests/_files/phpunit-example-extension
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--configuration';
+$_SERVER['argv'][2] = __DIR__ . '/../_files/phpunit-example-extension';
+$_SERVER['argv'][3] = '--no-extensions';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+Fatal error: Trait 'PHPUnit\ExampleExtension\TestCaseTrait' not found in %s
diff --git a/vendor/phpunit/phpunit/tests/TextUI/phar-extension.phpt b/vendor/phpunit/phpunit/tests/TextUI/phar-extension.phpt
new file mode 100644
index 0000000..06de392
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/phar-extension.phpt
@@ -0,0 +1,21 @@
+--TEST--
+phpunit --configuration tests/_files/phpunit-example-extension
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--configuration';
+$_SERVER['argv'][2] = __DIR__ . '/../_files/phpunit-example-extension';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+Runtime: %s
+Configuration: %s/phpunit-example-extension/phpunit.xml
+Extension: %s/phpunit-example-extension/tools/phpunit.d/phpunit-example-extension-1.0.0.phar
+
+. 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK (1 test, 1 assertion)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/phpt-args.phpt b/vendor/phpunit/phpunit/tests/TextUI/phpt-args.phpt
new file mode 100644
index 0000000..4314f19
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/phpt-args.phpt
@@ -0,0 +1,12 @@
+--TEST--
+PHPT runner supports ARGS section
+--ARGS--
+help
+--FILE--
+<?php
+if ($argc > 0 && $argv[1] == 'help') {
+ echo 'Help';
+}
+?>
+--EXPECT--
+Help
diff --git a/vendor/phpunit/phpunit/tests/TextUI/phpt-env.phpt b/vendor/phpunit/phpunit/tests/TextUI/phpt-env.phpt
new file mode 100644
index 0000000..689cfe1
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/phpt-env.phpt
@@ -0,0 +1,12 @@
+--TEST--
+PHPT runner should support ENV section
+--ENV--
+FOO=bar
+--FILE--
+<?php
+if (isset($_SERVER['FOO'])) {
+ var_dump($_SERVER['FOO']);
+}
+?>
+--EXPECTF_EXTERNAL--
+_files/phpt-env.expected.txt
diff --git a/vendor/phpunit/phpunit/tests/TextUI/phpt-external.phpt b/vendor/phpunit/phpunit/tests/TextUI/phpt-external.phpt
new file mode 100644
index 0000000..c6ff50e
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/phpt-external.phpt
@@ -0,0 +1,6 @@
+--TEST--
+GH-1436: PHPT runner doesn't handle external files.
+--FILE_EXTERNAL--
+_files/phpt_external.php
+--EXPECT_EXTERNAL--
+_files/expect_external.txt
diff --git a/vendor/phpunit/phpunit/tests/TextUI/phpt-stderr.phpt b/vendor/phpunit/phpunit/tests/TextUI/phpt-stderr.phpt
new file mode 100644
index 0000000..d6b33f0
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/phpt-stderr.phpt
@@ -0,0 +1,8 @@
+--TEST--
+GH-1169: PHPT runner doesn't look at STDERR.
+--FILE--
+<?php
+$stderr = fopen('php://stderr', 'w');
+fwrite($stderr, 'PHPUnit must look at STDERR when running PHPT tests.');
+--EXPECTF--
+PHPUnit must look at STDERR when running PHPT tests.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/phpt-stdin.phpt b/vendor/phpunit/phpunit/tests/TextUI/phpt-stdin.phpt
new file mode 100644
index 0000000..51430f1
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/phpt-stdin.phpt
@@ -0,0 +1,11 @@
+--TEST--
+PHPT runner supports STDIN section
+--STDIN--
+Hello World
+--FILE--
+<?php
+$input = file_get_contents('php://stdin');
+echo $input;
+?>
+--EXPECT--
+Hello World
diff --git a/vendor/phpunit/phpunit/tests/TextUI/phpt-xfail.phpt b/vendor/phpunit/phpunit/tests/TextUI/phpt-xfail.phpt
new file mode 100644
index 0000000..89927d4
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/phpt-xfail.phpt
@@ -0,0 +1,18 @@
+--TEST--
+PHPT runner supports XFAIL section
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = __DIR__ . '/../_files/phpt-xfail.phpt';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+I 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK, but incomplete, skipped, or risky tests!
+Tests: 1, Assertions: 1, Incomplete: 1. \ No newline at end of file
diff --git a/vendor/phpunit/phpunit/tests/TextUI/repeat.phpt b/vendor/phpunit/phpunit/tests/TextUI/repeat.phpt
new file mode 100644
index 0000000..59bcbcb
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/repeat.phpt
@@ -0,0 +1,20 @@
+--TEST--
+phpunit --repeat 3 BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--repeat';
+$_SERVER['argv'][3] = '3';
+$_SERVER['argv'][4] = 'BankAccountTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+......... 9 / 9 (100%)
+
+Time: %s, Memory: %s
+
+OK (9 tests, 9 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests-incomplete.phpt b/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests-incomplete.phpt
new file mode 100644
index 0000000..3d12cfd
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests-incomplete.phpt
@@ -0,0 +1,20 @@
+--TEST--
+phpunit --report-useless-tests IncompleteTest ../_files/IncompleteTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--report-useless-tests';
+$_SERVER['argv'][3] = 'IncompleteTest';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/IncompleteTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+I 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK, but incomplete, skipped, or risky tests!
+Tests: 1, Assertions: 0, Incomplete: 1.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests-isolation.phpt b/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests-isolation.phpt
new file mode 100644
index 0000000..5d4f1ea
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests-isolation.phpt
@@ -0,0 +1,21 @@
+--TEST--
+phpunit --report-useless-tests --process-isolation IncompleteTest ../_files/IncompleteTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--report-useless-tests';
+$_SERVER['argv'][3] = '--process-isolation';
+$_SERVER['argv'][4] = 'NothingTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/NothingTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+R 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+OK, but incomplete, skipped, or risky tests!
+Tests: 1, Assertions: 0, Risky: 1.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests.phpt b/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests.phpt
new file mode 100644
index 0000000..135d1ef
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/report-useless-tests.phpt
@@ -0,0 +1,28 @@
+--TEST--
+phpunit --report-useless-tests NothingTest ../_files/NothingTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--report-useless-tests';
+$_SERVER['argv'][3] = '--verbose';
+$_SERVER['argv'][4] = 'NothingTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/NothingTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+Runtime: %s
+
+R 1 / 1 (100%)
+
+Time: %s, Memory: %s
+
+There was 1 risky test:
+
+1) NothingTest::testNothing
+This test did not perform any assertions
+
+OK, but incomplete, skipped, or risky tests!
+Tests: 1, Assertions: 0, Risky: 1.
diff --git a/vendor/phpunit/phpunit/tests/TextUI/stop-on-warning-via-cli.phpt b/vendor/phpunit/phpunit/tests/TextUI/stop-on-warning-via-cli.phpt
new file mode 100644
index 0000000..c60c556
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/stop-on-warning-via-cli.phpt
@@ -0,0 +1,25 @@
+--TEST--
+phpunit --stop-on-warning StopOnWarningTestSuite ./tests/_files/StopOnWarningTestSuite.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--stop-on-warning';
+$_SERVER['argv'][3] = 'StopOnWarningTestSuite';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/StopOnWarningTestSuite.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+W
+
+Time: %s, Memory: %s
+
+There was 1 warning:
+
+1) Warning
+No tests found in class "NoTestCases".
+
+WARNINGS!
+Tests: 1, Assertions: 0, Warnings: 1. \ No newline at end of file
diff --git a/vendor/phpunit/phpunit/tests/TextUI/stop-on-warning-via-config.phpt b/vendor/phpunit/phpunit/tests/TextUI/stop-on-warning-via-config.phpt
new file mode 100644
index 0000000..47db7a6
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/stop-on-warning-via-config.phpt
@@ -0,0 +1,26 @@
+--TEST--
+phpunit -c ../_files/configuration_stop_on_warning.xml --stop-on-warning StopOnWarningTestSuite ./tests/_files/StopOnWarningTestSuite.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '-c';
+$_SERVER['argv'][2] = __DIR__ . '/../_files/configuration_stop_on_warning.xml';
+$_SERVER['argv'][3] = '--stop-on-warning';
+$_SERVER['argv'][4] = 'StopOnWarningTestSuite';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/StopOnWarningTestSuite.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+W
+
+Time: %s, Memory: %s
+
+There was 1 warning:
+
+1) Warning
+No tests found in class "NoTestCases".
+
+WARNINGS!
+Tests: 1, Assertions: 0, Warnings: 1. \ No newline at end of file
diff --git a/vendor/phpunit/phpunit/tests/TextUI/tap.phpt b/vendor/phpunit/phpunit/tests/TextUI/tap.phpt
new file mode 100644
index 0000000..e87c010
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/tap.phpt
@@ -0,0 +1,17 @@
+--TEST--
+phpunit --tap BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--tap';
+$_SERVER['argv'][3] = 'BankAccountTest';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+TAP version 13
+ok 1 - BankAccountTest::testBalanceIsInitiallyZero
+ok 2 - BankAccountTest::testBalanceCannotBecomeNegative
+ok 3 - BankAccountTest::testBalanceCannotBecomeNegative2
+1..3
diff --git a/vendor/phpunit/phpunit/tests/TextUI/teamcity-inner-exceptions.phpt b/vendor/phpunit/phpunit/tests/TextUI/teamcity-inner-exceptions.phpt
new file mode 100644
index 0000000..17d769a
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/teamcity-inner-exceptions.phpt
@@ -0,0 +1,39 @@
+--TEST--
+phpunit --teamcity ExceptionStackTest ../_files/ExceptionStackTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--teamcity';
+$_SERVER['argv'][3] = 'ExceptionStackTest';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/ExceptionStackTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+
+##teamcity[testCount count='2' flowId='%d']
+
+##teamcity[testSuiteStarted name='ExceptionStackTest' locationHint='php_qn://%s/tests/_files/ExceptionStackTest.php::\ExceptionStackTest' flowId='%d']
+
+##teamcity[testStarted name='testPrintingChildException' locationHint='php_qn://%s/tests/_files/ExceptionStackTest.php::\ExceptionStackTest::testPrintingChildException' flowId='%d']
+
+##teamcity[testFailed name='testPrintingChildException' message='Child exception|nmessage|nFailed asserting that two arrays are equal.|n--- Expected|n+++ Actual|n@@ @@|n Array (|n- 0 => 1|n+ 0 => 2|n )|n' details=' %s/tests/_files/ExceptionStackTest.php:10|n |n Caused by|n message|n Failed asserting that two arrays are equal.|n --- Expected|n +++ Actual|n @@ @@|n Array (|n - 0 => 1|n + 0 => 2|n )|n |n %s/tests/_files/ExceptionStackTest.php:7|n ' flowId='%d']
+
+##teamcity[testFinished name='testPrintingChildException' duration='%d' flowId='%d']
+
+##teamcity[testStarted name='testNestedExceptions' locationHint='php_qn://%s/tests/_files/ExceptionStackTest.php::\ExceptionStackTest::testNestedExceptions' flowId='%d']
+
+##teamcity[testFailed name='testNestedExceptions' message='Exception : One' details=' %s/tests/_files/ExceptionStackTest.php:18|n ' flowId='%d']
+
+##teamcity[testFinished name='testNestedExceptions' duration='%d' flowId='%d']
+
+##teamcity[testSuiteFinished name='ExceptionStackTest' flowId='%d']
+
+
+Time: %s, Memory: %s
+
+
+ERRORS!
+Tests: 2, Assertions: 1, Errors: 2. \ No newline at end of file
diff --git a/vendor/phpunit/phpunit/tests/TextUI/teamcity.phpt b/vendor/phpunit/phpunit/tests/TextUI/teamcity.phpt
new file mode 100644
index 0000000..30ba277
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/teamcity.phpt
@@ -0,0 +1,37 @@
+--TEST--
+phpunit --teamcity BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--teamcity';
+$_SERVER['argv'][3] = 'BankAccountTest';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+
+##teamcity[testCount count='3' flowId='%d']
+
+##teamcity[testSuiteStarted name='BankAccountTest' locationHint='php_qn://%s/tests/_files/BankAccountTest.php::\BankAccountTest' flowId='%d']
+
+##teamcity[testStarted name='testBalanceIsInitiallyZero' locationHint='php_qn://%s/tests/_files/BankAccountTest.php::\BankAccountTest::testBalanceIsInitiallyZero' flowId='%d']
+
+##teamcity[testFinished name='testBalanceIsInitiallyZero' duration='%s' flowId='%d']
+
+##teamcity[testStarted name='testBalanceCannotBecomeNegative' locationHint='php_qn://%s/tests/_files/BankAccountTest.php::\BankAccountTest::testBalanceCannotBecomeNegative' flowId='%d']
+
+##teamcity[testFinished name='testBalanceCannotBecomeNegative' duration='%s' flowId='%d']
+
+##teamcity[testStarted name='testBalanceCannotBecomeNegative2' locationHint='php_qn://%s/tests/_files/BankAccountTest.php::\BankAccountTest::testBalanceCannotBecomeNegative2' flowId='%d']
+
+##teamcity[testFinished name='testBalanceCannotBecomeNegative2' duration='%s' flowId='%d']
+
+##teamcity[testSuiteFinished name='BankAccountTest' flowId='%d']
+
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/test-suffix-multiple.phpt b/vendor/phpunit/phpunit/tests/TextUI/test-suffix-multiple.phpt
new file mode 100644
index 0000000..ae7da52
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/test-suffix-multiple.phpt
@@ -0,0 +1,19 @@
+--TEST--
+phpunit --test-suffix .test.php,.my.php ../_files/
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--test-suffix';
+$_SERVER['argv'][3] = '.test.php,.my.php';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+..... 5 / 5 (100%)
+
+Time: %s, Memory: %s
+
+OK (5 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/test-suffix-single.phpt b/vendor/phpunit/phpunit/tests/TextUI/test-suffix-single.phpt
new file mode 100644
index 0000000..031223a
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/test-suffix-single.phpt
@@ -0,0 +1,19 @@
+--TEST--
+phpunit --test-suffix .test.php ../_files/
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--test-suffix';
+$_SERVER['argv'][3] = '.test.php';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+... 3 / 3 (100%)
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/testdox-exclude-group.phpt b/vendor/phpunit/phpunit/tests/TextUI/testdox-exclude-group.phpt
new file mode 100644
index 0000000..8724c8a
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/testdox-exclude-group.phpt
@@ -0,0 +1,25 @@
+--TEST--
+phpunit --testdox-text php://stdout --testdox-exclude-group one TestDoxGroupTest ../_files/TestDoxGroupTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--testdox-text';
+$_SERVER['argv'][3] = 'php://stdout';
+$_SERVER['argv'][4] = '--testdox-exclude-group';
+$_SERVER['argv'][5] = 'one';
+$_SERVER['argv'][6] = 'TestDoxGroupTest';
+$_SERVER['argv'][7] = __DIR__ . '/../_files/TestDoxGroupTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.DoxGroup
+. 2 / 2 (100%) [x] Two
+
+
+
+Time: %s, Memory: %s
+
+OK (2 tests, 0 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/testdox-group.phpt b/vendor/phpunit/phpunit/tests/TextUI/testdox-group.phpt
new file mode 100644
index 0000000..407559f
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/testdox-group.phpt
@@ -0,0 +1,25 @@
+--TEST--
+phpunit --testdox-text php://stdout --testdox-group one TestDoxGroupTest ../_files/TestDoxGroupTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--testdox-text';
+$_SERVER['argv'][3] = 'php://stdout';
+$_SERVER['argv'][4] = '--testdox-group';
+$_SERVER['argv'][5] = 'one';
+$_SERVER['argv'][6] = 'TestDoxGroupTest';
+$_SERVER['argv'][7] = __DIR__ . '/../_files/TestDoxGroupTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+DoxGroup
+.. 2 / 2 (100%) [x] One
+
+
+
+Time: %s, Memory: %s
+
+OK (2 tests, 0 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/testdox-html.phpt b/vendor/phpunit/phpunit/tests/TextUI/testdox-html.phpt
new file mode 100644
index 0000000..7e23e59
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/testdox-html.phpt
@@ -0,0 +1,56 @@
+--TEST--
+phpunit --testdox-html php://stdout BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--testdox-html';
+$_SERVER['argv'][3] = 'php://stdout';
+$_SERVER['argv'][4] = 'BankAccountTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8"/>
+ <title>Test Documentation</title>
+ <style>
+ body {
+ text-rendering: optimizeLegibility;
+ font-variant-ligatures: common-ligatures;
+ font-kerning: normal;
+ margin-left: 2em;
+ }
+
+ body > ul > li {
+ font-family: Source Serif Pro, PT Sans, Trebuchet MS, Helvetica, Arial;
+ font-size: 2em;
+ }
+
+ h2 {
+ font-family: Tahoma, Helvetica, Arial;
+ font-size: 3em;
+ }
+
+ ul {
+ list-style: none;
+ margin-bottom: 1em;
+ }
+ </style>
+ </head>
+ <body>
+
+ <h2 id="BankAccountTest">BankAccount</h2>
+ <ul>
+... 3 / 3 (100%) <li style="color: #555753;">✓ Balance is initially zero</li>
+ <li style="color: #555753;">✓ Balance cannot become negative</li>
+ </ul>
+ </body>
+</html>
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/testdox-text.phpt b/vendor/phpunit/phpunit/tests/TextUI/testdox-text.phpt
new file mode 100644
index 0000000..a70fb2b
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/testdox-text.phpt
@@ -0,0 +1,24 @@
+--TEST--
+phpunit --testdox-text php://stdout BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--testdox-text';
+$_SERVER['argv'][3] = 'php://stdout';
+$_SERVER['argv'][4] = 'BankAccountTest';
+$_SERVER['argv'][5] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+BankAccount
+... 3 / 3 (100%) [x] Balance is initially zero
+ [x] Balance cannot become negative
+
+
+
+Time: %s, Memory: %s
+
+OK (3 tests, 3 assertions)
diff --git a/vendor/phpunit/phpunit/tests/TextUI/testdox-xml.phpt b/vendor/phpunit/phpunit/tests/TextUI/testdox-xml.phpt
new file mode 100644
index 0000000..384f7c7
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/testdox-xml.phpt
@@ -0,0 +1,56 @@
+--TEST--
+phpunit --testdox-xml php://stdout StatusTest ../_files/StatusTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--report-useless-tests';
+$_SERVER['argv'][3] = '--testdox-xml';
+$_SERVER['argv'][4] = 'php://stdout';
+$_SERVER['argv'][5] = 'StatusTest';
+$_SERVER['argv'][6] = __DIR__ . '/../_files/StatusTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+.FEISRW 7 / 7 (100%)<?xml version="1.0" encoding="UTF-8"?>
+<tests>
+ <test className="StatusTest" methodName="testSuccess" prettifiedClassName="Status" prettifiedMethodName="Success" status="0" time="%s" size="-1" groups="default"/>
+ <test className="StatusTest" methodName="testFailure" prettifiedClassName="Status" prettifiedMethodName="Failure" status="3" time="%s" size="-1" groups="default" exceptionLine="11" exceptionMessage="Failed asserting that false is true."/>
+ <test className="StatusTest" methodName="testError" prettifiedClassName="Status" prettifiedMethodName="Error" status="4" time="%s" size="-1" groups="default" exceptionMessage=""/>
+ <test className="StatusTest" methodName="testIncomplete" prettifiedClassName="Status" prettifiedMethodName="Incomplete" status="2" time="%s" size="-1" groups="default"/>
+ <test className="StatusTest" methodName="testSkipped" prettifiedClassName="Status" prettifiedMethodName="Skipped" status="1" time="%s" size="-1" groups="default"/>
+ <test className="StatusTest" methodName="testRisky" prettifiedClassName="Status" prettifiedMethodName="Risky" status="5" time="%s" size="-1" groups="default"/>
+ <test className="StatusTest" methodName="testWarning" prettifiedClassName="Status" prettifiedMethodName="Warning" status="6" time="%s" size="-1" groups="default"/>
+</tests>
+
+
+Time: %s, Memory: %s
+
+There was 1 error:
+
+1) StatusTest::testError
+Exception:%s
+
+%s/StatusTest.php:%d
+
+--
+
+There was 1 warning:
+
+1) StatusTest::testWarning
+
+%s/StatusTest.php:%d
+
+--
+
+There was 1 failure:
+
+1) StatusTest::testFailure
+Failed asserting that false is true.
+
+%s/StatusTest.php:%d
+
+ERRORS!
+Tests: 7, Assertions: 2, Errors: 1, Failures: 1, Warnings: 1, Skipped: 1, Incomplete: 1, Risky: 1. \ No newline at end of file
diff --git a/vendor/phpunit/phpunit/tests/TextUI/testdox.phpt b/vendor/phpunit/phpunit/tests/TextUI/testdox.phpt
new file mode 100644
index 0000000..d24f625
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/TextUI/testdox.phpt
@@ -0,0 +1,18 @@
+--TEST--
+phpunit --testdox php://stdout BankAccountTest ../_files/BankAccountTest.php
+--FILE--
+<?php
+$_SERVER['argv'][1] = '--no-configuration';
+$_SERVER['argv'][2] = '--testdox';
+$_SERVER['argv'][3] = 'BankAccountTest';
+$_SERVER['argv'][4] = __DIR__ . '/../_files/BankAccountTest.php';
+
+require __DIR__ . '/../bootstrap.php';
+PHPUnit_TextUI_Command::main();
+--EXPECTF--
+PHPUnit %s by Sebastian Bergmann and contributors.
+
+BankAccount
+ [x] Balance is initially zero
+ [x] Balance cannot become negative
+
diff --git a/vendor/phpunit/phpunit/tests/Util/ConfigurationTest.php b/vendor/phpunit/phpunit/tests/Util/ConfigurationTest.php
new file mode 100644
index 0000000..e21994b
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Util/ConfigurationTest.php
@@ -0,0 +1,431 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Util_ConfigurationTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @var PHPUnit_Util_Configuration
+ */
+ protected $configuration;
+
+ protected function setUp()
+ {
+ $this->configuration = PHPUnit_Util_Configuration::getInstance(
+ dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'configuration.xml'
+ );
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ */
+ public function testExceptionIsThrownForNotExistingConfigurationFile()
+ {
+ PHPUnit_Util_Configuration::getInstance('not_existing_file.xml');
+ }
+
+ public function testShouldReadColorsWhenTrueInConfigurationfile()
+ {
+ $configurationFilename = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'configuration.colors.true.xml';
+ $configurationInstance = PHPUnit_Util_Configuration::getInstance($configurationFilename);
+ $configurationValues = $configurationInstance->getPHPUnitConfiguration();
+
+ $this->assertEquals(PHPUnit_TextUI_ResultPrinter::COLOR_AUTO, $configurationValues['colors']);
+ }
+
+ public function testShouldReadColorsWhenFalseInConfigurationfile()
+ {
+ $configurationFilename = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'configuration.colors.false.xml';
+ $configurationInstance = PHPUnit_Util_Configuration::getInstance($configurationFilename);
+ $configurationValues = $configurationInstance->getPHPUnitConfiguration();
+
+ $this->assertEquals(PHPUnit_TextUI_ResultPrinter::COLOR_NEVER, $configurationValues['colors']);
+ }
+
+ public function testShouldReadColorsWhenEmptyInConfigurationfile()
+ {
+ $configurationFilename = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'configuration.colors.empty.xml';
+ $configurationInstance = PHPUnit_Util_Configuration::getInstance($configurationFilename);
+ $configurationValues = $configurationInstance->getPHPUnitConfiguration();
+
+ $this->assertEquals(PHPUnit_TextUI_ResultPrinter::COLOR_NEVER, $configurationValues['colors']);
+ }
+
+ public function testShouldReadColorsWhenInvalidInConfigurationfile()
+ {
+ $configurationFilename = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'configuration.colors.invalid.xml';
+ $configurationInstance = PHPUnit_Util_Configuration::getInstance($configurationFilename);
+ $configurationValues = $configurationInstance->getPHPUnitConfiguration();
+
+ $this->assertEquals(PHPUnit_TextUI_ResultPrinter::COLOR_NEVER, $configurationValues['colors']);
+ }
+
+ public function testFilterConfigurationIsReadCorrectly()
+ {
+ $this->assertEquals(
+ [
+ 'whitelist' =>
+ [
+ 'addUncoveredFilesFromWhitelist' => true,
+ 'processUncoveredFilesFromWhitelist' => false,
+ 'include' =>
+ [
+ 'directory' =>
+ [
+ 0 =>
+ [
+ 'path' => '/path/to/files',
+ 'prefix' => '',
+ 'suffix' => '.php',
+ 'group' => 'DEFAULT'
+ ],
+ ],
+ 'file' =>
+ [
+ 0 => '/path/to/file',
+ 1 => '/path/to/file',
+ ],
+ ],
+ 'exclude' =>
+ [
+ 'directory' =>
+ [
+ 0 =>
+ [
+ 'path' => '/path/to/files',
+ 'prefix' => '',
+ 'suffix' => '.php',
+ 'group' => 'DEFAULT'
+ ],
+ ],
+ 'file' =>
+ [
+ 0 => '/path/to/file',
+ ],
+ ],
+ ],
+ ],
+ $this->configuration->getFilterConfiguration()
+ );
+ }
+
+ public function testGroupConfigurationIsReadCorrectly()
+ {
+ $this->assertEquals(
+ [
+ 'include' =>
+ [
+ 0 => 'name',
+ ],
+ 'exclude' =>
+ [
+ 0 => 'name',
+ ],
+ ],
+ $this->configuration->getGroupConfiguration()
+ );
+ }
+
+ public function testTestdoxGroupConfigurationIsReadCorrectly()
+ {
+ $this->assertEquals(
+ [
+ 'include' =>
+ [
+ 0 => 'name',
+ ],
+ 'exclude' =>
+ [
+ 0 => 'name',
+ ],
+ ],
+ $this->configuration->getTestdoxGroupConfiguration()
+ );
+ }
+
+ public function testListenerConfigurationIsReadCorrectly()
+ {
+ $dir = __DIR__;
+ $includePath = ini_get('include_path');
+
+ ini_set('include_path', $dir . PATH_SEPARATOR . $includePath);
+
+ $this->assertEquals(
+ [
+ 0 =>
+ [
+ 'class' => 'MyListener',
+ 'file' => '/optional/path/to/MyListener.php',
+ 'arguments' =>
+ [
+ 0 =>
+ [
+ 0 => 'Sebastian',
+ ],
+ 1 => 22,
+ 2 => 'April',
+ 3 => 19.78,
+ 4 => null,
+ 5 => new stdClass,
+ 6 => dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'MyTestFile.php',
+ 7 => dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'MyRelativePath',
+ ],
+ ],
+ [
+ 'class' => 'IncludePathListener',
+ 'file' => __FILE__,
+ 'arguments' => []
+ ],
+ [
+ 'class' => 'CompactArgumentsListener',
+ 'file' => '/CompactArgumentsListener.php',
+ 'arguments' =>
+ [
+ 0 => 42
+ ],
+ ],
+ ],
+ $this->configuration->getListenerConfiguration()
+ );
+
+ ini_set('include_path', $includePath);
+ }
+
+ public function testLoggingConfigurationIsReadCorrectly()
+ {
+ $this->assertEquals(
+ [
+ 'lowUpperBound' => '50',
+ 'highLowerBound' => '90',
+ 'coverage-html' => '/tmp/report',
+ 'coverage-clover' => '/tmp/clover.xml',
+ 'json' => '/tmp/logfile.json',
+ 'plain' => '/tmp/logfile.txt',
+ 'tap' => '/tmp/logfile.tap',
+ 'logIncompleteSkipped' => false,
+ 'junit' => '/tmp/logfile.xml',
+ 'testdox-html' => '/tmp/testdox.html',
+ 'testdox-text' => '/tmp/testdox.txt',
+ 'testdox-xml' => '/tmp/testdox.xml'
+ ],
+ $this->configuration->getLoggingConfiguration()
+ );
+ }
+
+ public function testPHPConfigurationIsReadCorrectly()
+ {
+ $this->assertEquals(
+ [
+ 'include_path' =>
+ [
+ dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . '.',
+ '/path/to/lib'
+ ],
+ 'ini' => ['foo' => 'bar'],
+ 'const' => ['FOO' => false, 'BAR' => true],
+ 'var' => ['foo' => false],
+ 'env' => ['foo' => true],
+ 'post' => ['foo' => 'bar'],
+ 'get' => ['foo' => 'bar'],
+ 'cookie' => ['foo' => 'bar'],
+ 'server' => ['foo' => 'bar'],
+ 'files' => ['foo' => 'bar'],
+ 'request'=> ['foo' => 'bar'],
+ ],
+ $this->configuration->getPHPConfiguration()
+ );
+ }
+
+ /**
+ * @backupGlobals enabled
+ */
+ public function testPHPConfigurationIsHandledCorrectly()
+ {
+ $this->configuration->handlePHPConfiguration();
+
+ $path = dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . '.' . PATH_SEPARATOR . '/path/to/lib';
+ $this->assertStringStartsWith($path, ini_get('include_path'));
+ $this->assertEquals(false, FOO);
+ $this->assertEquals(true, BAR);
+ $this->assertEquals(false, $GLOBALS['foo']);
+ $this->assertEquals(true, $_ENV['foo']);
+ $this->assertEquals(true, getenv('foo'));
+ $this->assertEquals('bar', $_POST['foo']);
+ $this->assertEquals('bar', $_GET['foo']);
+ $this->assertEquals('bar', $_COOKIE['foo']);
+ $this->assertEquals('bar', $_SERVER['foo']);
+ $this->assertEquals('bar', $_FILES['foo']);
+ $this->assertEquals('bar', $_REQUEST['foo']);
+ }
+
+ /**
+ * @backupGlobals enabled
+ *
+ * @see https://github.com/sebastianbergmann/phpunit/issues/1181
+ */
+ public function testHandlePHPConfigurationDoesNotOverwrittenExistingEnvArrayVariables()
+ {
+ $_ENV['foo'] = false;
+ $this->configuration->handlePHPConfiguration();
+
+ $this->assertEquals(false, $_ENV['foo']);
+ $this->assertEquals(true, getenv('foo'));
+ }
+
+ /**
+ * @backupGlobals enabled
+ *
+ * @see https://github.com/sebastianbergmann/phpunit/issues/1181
+ */
+ public function testHandlePHPConfigurationDoesNotOverriteVariablesFromPutEnv()
+ {
+ putenv('foo=putenv');
+ $this->configuration->handlePHPConfiguration();
+
+ $this->assertEquals(true, $_ENV['foo']);
+ $this->assertEquals('putenv', getenv('foo'));
+ }
+
+ public function testPHPUnitConfigurationIsReadCorrectly()
+ {
+ $this->assertEquals(
+ [
+ 'backupGlobals' => true,
+ 'backupStaticAttributes' => false,
+ 'beStrictAboutChangesToGlobalState' => false,
+ 'bootstrap' => '/path/to/bootstrap.php',
+ 'cacheTokens' => false,
+ 'columns' => 80,
+ 'colors' => 'never',
+ 'stderr' => false,
+ 'convertErrorsToExceptions' => true,
+ 'convertNoticesToExceptions' => true,
+ 'convertWarningsToExceptions' => true,
+ 'forceCoversAnnotation' => false,
+ 'stopOnFailure' => false,
+ 'stopOnWarning' => false,
+ 'reportUselessTests' => false,
+ 'strictCoverage' => false,
+ 'disallowTestOutput' => false,
+ 'enforceTimeLimit' => false,
+ 'extensionsDirectory' => '/tmp',
+ 'printerClass' => 'PHPUnit_TextUI_ResultPrinter',
+ 'testSuiteLoaderClass' => 'PHPUnit_Runner_StandardTestSuiteLoader',
+ 'verbose' => false,
+ 'timeoutForSmallTests' => 1,
+ 'timeoutForMediumTests' => 10,
+ 'timeoutForLargeTests' => 60,
+ 'beStrictAboutResourceUsageDuringSmallTests' => false,
+ 'disallowTodoAnnotatedTests' => false,
+ 'failOnWarning' => false,
+ 'failOnRisky' => false
+ ],
+ $this->configuration->getPHPUnitConfiguration()
+ );
+ }
+
+ public function testXincludeInConfiguration()
+ {
+ $configurationWithXinclude = PHPUnit_Util_Configuration::getInstance(
+ dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'configuration_xinclude.xml'
+ );
+
+ $this->assertConfigurationEquals(
+ $this->configuration,
+ $configurationWithXinclude
+ );
+ }
+
+ /**
+ * @ticket 1311
+ *
+ * @uses PHPUnit_Util_Configuration::getInstance
+ */
+ public function testWithEmptyConfigurations()
+ {
+ $emptyConfiguration = PHPUnit_Util_Configuration::getInstance(
+ dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'configuration_empty.xml'
+ );
+
+ $logging = $emptyConfiguration->getLoggingConfiguration();
+ $this->assertEmpty($logging);
+
+ $php = $emptyConfiguration->getPHPConfiguration();
+ $this->assertEmpty($php['include_path']);
+
+ $phpunit = $emptyConfiguration->getPHPUnitConfiguration();
+ $this->assertArrayNotHasKey('bootstrap', $phpunit);
+ $this->assertArrayNotHasKey('testSuiteLoaderFile', $phpunit);
+ $this->assertArrayNotHasKey('printerFile', $phpunit);
+
+ $suite = $emptyConfiguration->getTestSuiteConfiguration();
+ $this->assertEmpty($suite->getGroups());
+
+ $filter = $emptyConfiguration->getFilterConfiguration();
+ $this->assertEmpty($filter['whitelist']['include']['directory']);
+ $this->assertEmpty($filter['whitelist']['include']['file']);
+ $this->assertEmpty($filter['whitelist']['exclude']['directory']);
+ $this->assertEmpty($filter['whitelist']['exclude']['file']);
+ }
+
+ /**
+ * Asserts that the values in $actualConfiguration equal $expectedConfiguration.
+ *
+ * @param PHPUnit_Util_Configuration $expectedConfiguration
+ * @param PHPUnit_Util_Configuration $actualConfiguration
+ */
+ protected function assertConfigurationEquals(PHPUnit_Util_Configuration $expectedConfiguration, PHPUnit_Util_Configuration $actualConfiguration)
+ {
+ $this->assertEquals(
+ $expectedConfiguration->getFilterConfiguration(),
+ $actualConfiguration->getFilterConfiguration()
+ );
+
+ $this->assertEquals(
+ $expectedConfiguration->getGroupConfiguration(),
+ $actualConfiguration->getGroupConfiguration()
+ );
+
+ $this->assertEquals(
+ $expectedConfiguration->getListenerConfiguration(),
+ $actualConfiguration->getListenerConfiguration()
+ );
+
+ $this->assertEquals(
+ $expectedConfiguration->getLoggingConfiguration(),
+ $actualConfiguration->getLoggingConfiguration()
+ );
+
+ $this->assertEquals(
+ $expectedConfiguration->getPHPConfiguration(),
+ $actualConfiguration->getPHPConfiguration()
+ );
+
+ $this->assertEquals(
+ $expectedConfiguration->getPHPUnitConfiguration(),
+ $actualConfiguration->getPHPUnitConfiguration()
+ );
+
+ $this->assertEquals(
+ $expectedConfiguration->getTestSuiteConfiguration(),
+ $actualConfiguration->getTestSuiteConfiguration()
+ );
+ }
+
+ public function testGetTestSuiteNamesReturnsTheNamesIfDefined()
+ {
+ $configuration = PHPUnit_Util_Configuration::getInstance(
+ dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'configuration.suites.xml'
+ );
+
+ $names = $configuration->getTestSuiteNames();
+
+ $this->assertEquals(['Suite One', 'Suite Two'], $names);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Util/GetoptTest.php b/vendor/phpunit/phpunit/tests/Util/GetoptTest.php
new file mode 100644
index 0000000..166cb96
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Util/GetoptTest.php
@@ -0,0 +1,60 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Util_GetoptTest extends PHPUnit_Framework_TestCase
+{
+ public function testItIncludeTheLongOptionsAfterTheArgument()
+ {
+ $args = [
+ 'command',
+ 'myArgument',
+ '--colors',
+ ];
+ $actual = PHPUnit_Util_Getopt::getopt($args, '', ['colors==']);
+
+ $expected = [
+ [
+ [
+ '--colors',
+ null,
+ ],
+ ],
+ [
+ 'myArgument',
+ ],
+ ];
+
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function testItIncludeTheShortOptionsAfterTheArgument()
+ {
+ $args = [
+ 'command',
+ 'myArgument',
+ '-v',
+ ];
+ $actual = PHPUnit_Util_Getopt::getopt($args, 'v');
+
+ $expected = [
+ [
+ [
+ 'v',
+ null,
+ ],
+ ],
+ [
+ 'myArgument',
+ ],
+ ];
+
+ $this->assertEquals($expected, $actual);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Util/GlobalStateTest.php b/vendor/phpunit/phpunit/tests/Util/GlobalStateTest.php
new file mode 100644
index 0000000..840b102
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Util/GlobalStateTest.php
@@ -0,0 +1,30 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Util_GlobalStateTest extends PHPUnit_Framework_TestCase
+{
+ public function testIncludedFilesAsStringSkipsVfsProtocols()
+ {
+ $dir = __DIR__;
+ $files = [
+ 'phpunit', // The 0 index is not used
+ $dir . '/ConfigurationTest.php',
+ $dir . '/GlobalStateTest.php',
+ 'vfs://' . $dir . '/RegexTest.php',
+ 'phpvfs53e46260465c7://' . $dir . '/TestTest.php',
+ 'file://' . $dir . '/XMLTest.php'
+ ];
+
+ $this->assertEquals(
+ "require_once '" . $dir . "/ConfigurationTest.php';\n" .
+ "require_once '" . $dir . "/GlobalStateTest.php';\n" .
+ "require_once 'file://" . $dir . "/XMLTest.php';\n", PHPUnit_Util_GlobalState::processIncludedFilesAsString($files));
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Util/PHPTest.php b/vendor/phpunit/phpunit/tests/Util/PHPTest.php
new file mode 100644
index 0000000..feb1225
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Util/PHPTest.php
@@ -0,0 +1,132 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @author Henrique Moody <henriquemoody@gmail.com>
+ * @copyright Sebastian Bergmann <sebastian@phpunit.de>
+ * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
+ *
+ * @link http://www.phpunit.de/
+ */
+class PHPUnit_Util_PHPTest extends PHPUnit_Framework_TestCase
+{
+ public function testShouldNotUseStderrRedirectionByDefault()
+ {
+ $phpMock = $this->getMockForAbstractClass('PHPUnit_Util_PHP');
+
+ $this->assertFalse($phpMock->useStderrRedirection());
+ }
+
+ public function testShouldDefinedIfUseStderrRedirection()
+ {
+ $phpMock = $this->getMockForAbstractClass('PHPUnit_Util_PHP');
+ $phpMock->setUseStderrRedirection(true);
+
+ $this->assertTrue($phpMock->useStderrRedirection());
+ }
+
+ public function testShouldDefinedIfDoNotUseStderrRedirection()
+ {
+ $phpMock = $this->getMockForAbstractClass('PHPUnit_Util_PHP');
+ $phpMock->setUseStderrRedirection(false);
+
+ $this->assertFalse($phpMock->useStderrRedirection());
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ * @expectedExceptionMessage Argument #1 (No Value) of PHPUnit_Util_PHP::setUseStderrRedirection() must be a boolean
+ */
+ public function testShouldThrowsExceptionWhenStderrRedirectionVariableIsNotABoolean()
+ {
+ $phpMock = $this->getMockForAbstractClass('PHPUnit_Util_PHP');
+ $phpMock->setUseStderrRedirection(null);
+ }
+
+ public function testShouldUseGivenSettingsToCreateCommand()
+ {
+ $phpMock = $this->getMockForAbstractClass('PHPUnit_Util_PHP');
+
+ $settings = [
+ 'allow_url_fopen=1',
+ 'auto_append_file=',
+ 'display_errors=1',
+ ];
+
+ $expectedCommandFormat = '%s -d allow_url_fopen=1 -d auto_append_file= -d display_errors=1';
+ $actualCommand = $phpMock->getCommand($settings);
+
+ $this->assertStringMatchesFormat($expectedCommandFormat, $actualCommand);
+ }
+
+ public function testShouldRedirectStderrToStdoutWhenDefined()
+ {
+ $phpMock = $this->getMockForAbstractClass('PHPUnit_Util_PHP');
+ $phpMock->setUseStderrRedirection(true);
+
+ $expectedCommandFormat = '%s 2>&1';
+ $actualCommand = $phpMock->getCommand([]);
+
+ $this->assertStringMatchesFormat($expectedCommandFormat, $actualCommand);
+ }
+
+ public function testShouldUseArgsToCreateCommand()
+ {
+ $phpMock = $this->getMockForAbstractClass('PHPUnit_Util_PHP');
+ $phpMock->setArgs('foo=bar');
+
+ $expectedCommandFormat = '%s -- foo=bar';
+ $actualCommand = $phpMock->getCommand([]);
+
+ $this->assertStringMatchesFormat($expectedCommandFormat, $actualCommand);
+ }
+
+ public function testShouldHaveFileToCreateCommand()
+ {
+ $phpMock = $this->getMockForAbstractClass('PHPUnit_Util_PHP');
+
+ $expectedCommandFormat = '%s -%c \'file.php\'';
+ $actualCommand = $phpMock->getCommand([], 'file.php');
+
+ $this->assertStringMatchesFormat($expectedCommandFormat, $actualCommand);
+ }
+
+ public function testStdinGetterAndSetter()
+ {
+ $phpMock = $this->getMockForAbstractClass('PHPUnit_Util_PHP');
+ $phpMock->setStdin('foo');
+
+ $this->assertEquals('foo', $phpMock->getStdin());
+ }
+
+ public function testArgsGetterAndSetter()
+ {
+ $phpMock = $this->getMockForAbstractClass('PHPUnit_Util_PHP');
+ $phpMock->setArgs('foo=bar');
+
+ $this->assertEquals('foo=bar', $phpMock->getArgs());
+ }
+
+ public function testEnvGetterAndSetter()
+ {
+ $phpMock = $this->getMockForAbstractClass('PHPUnit_Util_PHP');
+ $phpMock->setEnv(['foo' => 'bar']);
+
+ $this->assertEquals(['foo' => 'bar'], $phpMock->getEnv());
+ }
+
+ public function testTimeoutGetterAndSetter()
+ {
+ $phpMock = $this->getMockForAbstractClass('PHPUnit_Util_PHP');
+ $phpMock->setTimeout(30);
+
+ $this->assertEquals(30, $phpMock->getTimeout());
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Util/RegexTest.php b/vendor/phpunit/phpunit/tests/Util/RegexTest.php
new file mode 100644
index 0000000..f33807e
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Util/RegexTest.php
@@ -0,0 +1,47 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Util_RegexTest extends PHPUnit_Framework_TestCase
+{
+ public function validRegexpProvider()
+ {
+ return [
+ ['#valid regexp#', 'valid regexp', 1],
+ [';val.*xp;', 'valid regexp', 1],
+ ['/val.*xp/i', 'VALID REGEXP', 1],
+ ['/a val.*p/','valid regexp', 0],
+ ];
+ }
+
+ public function invalidRegexpProvider()
+ {
+ return [
+ ['valid regexp', 'valid regexp'],
+ [';val.*xp', 'valid regexp'],
+ ['val.*xp/i', 'VALID REGEXP'],
+ ];
+ }
+
+ /**
+ * @dataProvider validRegexpProvider
+ */
+ public function testValidRegex($pattern, $subject, $return)
+ {
+ $this->assertEquals($return, PHPUnit_Util_Regex::pregMatchSafe($pattern, $subject));
+ }
+
+ /**
+ * @dataProvider invalidRegexpProvider
+ */
+ public function testInvalidRegex($pattern, $subject)
+ {
+ $this->assertFalse(PHPUnit_Util_Regex::pregMatchSafe($pattern, $subject));
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Util/TestDox/NamePrettifierTest.php b/vendor/phpunit/phpunit/tests/Util/TestDox/NamePrettifierTest.php
new file mode 100644
index 0000000..cf0a9ff
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Util/TestDox/NamePrettifierTest.php
@@ -0,0 +1,66 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Util_TestDox_NamePrettifierTest extends PHPUnit_Framework_TestCase
+{
+ protected $namePrettifier;
+
+ protected function setUp()
+ {
+ $this->namePrettifier = new PHPUnit_Util_TestDox_NamePrettifier;
+ }
+
+ public function testTitleHasSensibleDefaults()
+ {
+ $this->assertEquals('Foo', $this->namePrettifier->prettifyTestClass('FooTest'));
+ $this->assertEquals('Foo', $this->namePrettifier->prettifyTestClass('TestFoo'));
+ $this->assertEquals('Foo', $this->namePrettifier->prettifyTestClass('TestFooTest'));
+ $this->assertEquals('Foo', $this->namePrettifier->prettifyTestClass('Test\FooTest'));
+ }
+
+ public function testCaterForUserDefinedSuffix()
+ {
+ $this->namePrettifier->setSuffix('TestCase');
+ $this->namePrettifier->setPrefix(null);
+
+ $this->assertEquals('Foo', $this->namePrettifier->prettifyTestClass('FooTestCase'));
+ $this->assertEquals('TestFoo', $this->namePrettifier->prettifyTestClass('TestFoo'));
+ $this->assertEquals('FooTest', $this->namePrettifier->prettifyTestClass('FooTest'));
+ }
+
+ public function testCaterForUserDefinedPrefix()
+ {
+ $this->namePrettifier->setSuffix(null);
+ $this->namePrettifier->setPrefix('XXX');
+
+ $this->assertEquals('Foo', $this->namePrettifier->prettifyTestClass('XXXFoo'));
+ $this->assertEquals('TestXXX', $this->namePrettifier->prettifyTestClass('TestXXX'));
+ $this->assertEquals('XXX', $this->namePrettifier->prettifyTestClass('XXXXXX'));
+ }
+
+ public function testTestNameIsConvertedToASentence()
+ {
+ $this->assertEquals('This is a test', $this->namePrettifier->prettifyTestMethod('testThisIsATest'));
+ $this->assertEquals('This is a test', $this->namePrettifier->prettifyTestMethod('testThisIsATest2'));
+ $this->assertEquals('This is a test', $this->namePrettifier->prettifyTestMethod('this_is_a_test'));
+ $this->assertEquals('Foo for bar is 0', $this->namePrettifier->prettifyTestMethod('testFooForBarIs0'));
+ $this->assertEquals('Foo for baz is 1', $this->namePrettifier->prettifyTestMethod('testFooForBazIs1'));
+ $this->assertEquals('', $this->namePrettifier->prettifyTestMethod('test'));
+ }
+
+ /**
+ * @ticket 224
+ */
+ public function testTestNameIsNotGroupedWhenNotInSequence()
+ {
+ $this->assertEquals('Sets redirect header on 301', $this->namePrettifier->prettifyTestMethod('testSetsRedirectHeaderOn301'));
+ $this->assertEquals('Sets redirect header on 302', $this->namePrettifier->prettifyTestMethod('testSetsRedirectHeaderOn302'));
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Util/TestTest.php b/vendor/phpunit/phpunit/tests/Util/TestTest.php
new file mode 100644
index 0000000..6e3fc9f
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Util/TestTest.php
@@ -0,0 +1,823 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+if (!defined('TEST_FILES_PATH')) {
+ define(
+ 'TEST_FILES_PATH',
+ dirname(__DIR__) . DIRECTORY_SEPARATOR .
+ '_files' . DIRECTORY_SEPARATOR
+ );
+}
+
+require TEST_FILES_PATH . 'CoverageNamespacedFunctionTest.php';
+require TEST_FILES_PATH . 'NamespaceCoveredFunction.php';
+require TEST_FILES_PATH . 'MultipleDataProviderTest.php';
+
+class Util_TestTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @todo Split up in separate tests
+ */
+ public function testGetExpectedException()
+ {
+ $this->assertArraySubset(
+ ['class' => 'FooBarBaz', 'code' => null, 'message' => ''],
+ PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testOne')
+ );
+
+ $this->assertArraySubset(
+ ['class' => 'Foo_Bar_Baz', 'code' => null, 'message' => ''],
+ PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testTwo')
+ );
+
+ $this->assertArraySubset(
+ ['class' => 'Foo\Bar\Baz', 'code' => null, 'message' => ''],
+ PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testThree')
+ );
+
+ $this->assertArraySubset(
+ ['class' => 'ほげ', 'code' => null, 'message' => ''],
+ PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testFour')
+ );
+
+ $this->assertArraySubset(
+ ['class' => 'Class', 'code' => 1234, 'message' => 'Message'],
+ PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testFive')
+ );
+
+ $this->assertArraySubset(
+ ['class' => 'Class', 'code' => 1234, 'message' => 'Message'],
+ PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testSix')
+ );
+
+ $this->assertArraySubset(
+ ['class' => 'Class', 'code' => 'ExceptionCode', 'message' => 'Message'],
+ PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testSeven')
+ );
+
+ $this->assertArraySubset(
+ ['class' => 'Class', 'code' => 0, 'message' => 'Message'],
+ PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testEight')
+ );
+
+ $this->assertArraySubset(
+ ['class' => 'Class', 'code' => ExceptionTest::ERROR_CODE, 'message' => ExceptionTest::ERROR_MESSAGE],
+ PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testNine')
+ );
+
+ $this->assertArraySubset(
+ ['class' => 'Class', 'code' => null, 'message' => ''],
+ PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testSingleLine')
+ );
+
+ $this->assertArraySubset(
+ ['class' => 'Class', 'code' => My\Space\ExceptionNamespaceTest::ERROR_CODE, 'message' => My\Space\ExceptionNamespaceTest::ERROR_MESSAGE],
+ PHPUnit_Util_Test::getExpectedException('My\Space\ExceptionNamespaceTest', 'testConstants')
+ );
+
+ // Ensure the Class::CONST expression is only evaluated when the constant really exists
+ $this->assertArraySubset(
+ ['class' => 'Class', 'code' => 'ExceptionTest::UNKNOWN_CODE_CONSTANT', 'message' => 'ExceptionTest::UNKNOWN_MESSAGE_CONSTANT'],
+ PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testUnknownConstants')
+ );
+
+ $this->assertArraySubset(
+ ['class' => 'Class', 'code' => 'My\Space\ExceptionNamespaceTest::UNKNOWN_CODE_CONSTANT', 'message' => 'My\Space\ExceptionNamespaceTest::UNKNOWN_MESSAGE_CONSTANT'],
+ PHPUnit_Util_Test::getExpectedException('My\Space\ExceptionNamespaceTest', 'testUnknownConstants')
+ );
+ }
+
+ public function testGetExpectedRegExp()
+ {
+ $this->assertArraySubset(
+ ['message_regex' => '#regex#'],
+ PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testWithRegexMessage')
+ );
+
+ $this->assertArraySubset(
+ ['message_regex' => '#regex#'],
+ PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testWithRegexMessageFromClassConstant')
+ );
+
+ $this->assertArraySubset(
+ ['message_regex' => 'ExceptionTest::UNKNOWN_MESSAGE_REGEX_CONSTANT'],
+ PHPUnit_Util_Test::getExpectedException('ExceptionTest', 'testWithUnknowRegexMessageFromClassConstant')
+ );
+ }
+
+ /**
+ * @dataProvider requirementsProvider
+ */
+ public function testGetRequirements($test, $result)
+ {
+ $this->assertEquals(
+ $result,
+ PHPUnit_Util_Test::getRequirements('RequirementsTest', $test)
+ );
+ }
+
+ public function requirementsProvider()
+ {
+ return [
+ ['testOne', []],
+ ['testTwo', ['PHPUnit' => ['version' => '1.0', 'operator' => '']]],
+ ['testThree', ['PHP' => ['version' => '2.0', 'operator' => '']]],
+ ['testFour', [
+ 'PHPUnit' => ['version' => '2.0', 'operator' => ''],
+ 'PHP' => ['version' => '1.0', 'operator' => '']]
+ ],
+ ['testFive', ['PHP' => ['version' => '5.4.0RC6', 'operator' => '']]],
+ ['testSix', ['PHP' => ['version' => '5.4.0-alpha1', 'operator' => '']]],
+ ['testSeven', ['PHP' => ['version' => '5.4.0beta2', 'operator' => '']]],
+ ['testEight', ['PHP' => ['version' => '5.4-dev', 'operator' => '']]],
+ ['testNine', ['functions' => ['testFunc']]],
+ ['testTen', ['extensions' => ['testExt']]],
+ ['testEleven', ['OS' => '/Linux/i']],
+ [
+ 'testSpace',
+ [
+ 'extensions' => ['spl'],
+ 'OS' => '/.*/i'
+ ]
+ ],
+ [
+ 'testAllPossibleRequirements',
+ [
+ 'PHP' => ['version' => '99-dev', 'operator' => ''],
+ 'PHPUnit' => ['version' => '9-dev', 'operator' => ''],
+ 'OS' => '/DOESNOTEXIST/i',
+ 'functions' => [
+ 'testFuncOne',
+ 'testFuncTwo',
+ ],
+ 'extensions' => [
+ 'testExtOne',
+ 'testExtTwo',
+ 'testExtThree',
+ ],
+ 'extension_versions' => [
+ 'testExtThree' => ['version' => '2.0', 'operator' => '']
+ ]
+ ]
+ ],
+ ['testSpecificExtensionVersion',
+ [
+ 'extension_versions' => ['testExt' => ['version' => '1.8.0', 'operator' => '']],
+ 'extensions' => ['testExt']
+ ]
+ ],
+ ['testPHPVersionOperatorLessThan',
+ [
+ 'PHP' => ['version' => '5.4', 'operator' => '<']
+ ]
+ ],
+ ['testPHPVersionOperatorLessThanEquals',
+ [
+ 'PHP' => ['version' => '5.4', 'operator' => '<=']
+ ]
+ ],
+ ['testPHPVersionOperatorGreaterThan',
+ [
+ 'PHP' => ['version' => '99', 'operator' => '>']
+ ]
+ ],
+ ['testPHPVersionOperatorGreaterThanEquals',
+ [
+ 'PHP' => ['version' => '99', 'operator' => '>=']
+ ]
+ ],
+ ['testPHPVersionOperatorEquals',
+ [
+ 'PHP' => ['version' => '5.4', 'operator' => '=']
+ ]
+ ],
+ ['testPHPVersionOperatorDoubleEquals',
+ [
+ 'PHP' => ['version' => '5.4', 'operator' => '==']
+ ]
+ ],
+ ['testPHPVersionOperatorBangEquals',
+ [
+ 'PHP' => ['version' => '99', 'operator' => '!=']
+ ]
+ ],
+ ['testPHPVersionOperatorNotEquals',
+ [
+ 'PHP' => ['version' => '99', 'operator' => '<>']
+ ]
+ ],
+ ['testPHPVersionOperatorNoSpace',
+ [
+ 'PHP' => ['version' => '99', 'operator' => '>=']
+ ]
+ ],
+ ['testPHPUnitVersionOperatorLessThan',
+ [
+ 'PHPUnit' => ['version' => '1.0', 'operator' => '<']
+ ]
+ ],
+ ['testPHPUnitVersionOperatorLessThanEquals',
+ [
+ 'PHPUnit' => ['version' => '1.0', 'operator' => '<=']
+ ]
+ ],
+ ['testPHPUnitVersionOperatorGreaterThan',
+ [
+ 'PHPUnit' => ['version' => '99', 'operator' => '>']
+ ]
+ ],
+ ['testPHPUnitVersionOperatorGreaterThanEquals',
+ [
+ 'PHPUnit' => ['version' => '99', 'operator' => '>=']
+ ]
+ ],
+ ['testPHPUnitVersionOperatorEquals',
+ [
+ 'PHPUnit' => ['version' => '1.0', 'operator' => '=']
+ ]
+ ],
+ ['testPHPUnitVersionOperatorDoubleEquals',
+ [
+ 'PHPUnit' => ['version' => '1.0', 'operator' => '==']
+ ]
+ ],
+ ['testPHPUnitVersionOperatorBangEquals',
+ [
+ 'PHPUnit' => ['version' => '99', 'operator' => '!=']
+ ]
+ ],
+ ['testPHPUnitVersionOperatorNotEquals',
+ [
+ 'PHPUnit' => ['version' => '99', 'operator' => '<>']
+ ]
+ ],
+ ['testPHPUnitVersionOperatorNoSpace',
+ [
+ 'PHPUnit' => ['version' => '99', 'operator' => '>=']
+ ]
+ ],
+ ['testExtensionVersionOperatorLessThanEquals',
+ [
+ 'extensions' => ['testExtOne'],
+ 'extension_versions' => ['testExtOne' => ['version' => '1.0', 'operator' => '<=']]
+ ]
+ ],
+ ['testExtensionVersionOperatorGreaterThan',
+ [
+ 'extensions' => ['testExtOne'],
+ 'extension_versions' => ['testExtOne' => ['version' => '99', 'operator' => '>']]
+ ]
+ ],
+ ['testExtensionVersionOperatorGreaterThanEquals',
+ [
+ 'extensions' => ['testExtOne'],
+ 'extension_versions' => ['testExtOne' => ['version' => '99', 'operator' => '>=']]
+ ]
+ ],
+ ['testExtensionVersionOperatorEquals',
+ [
+ 'extensions' => ['testExtOne'],
+ 'extension_versions' => ['testExtOne' => ['version' => '1.0', 'operator' => '=']]
+ ]
+ ],
+ ['testExtensionVersionOperatorDoubleEquals',
+ [
+ 'extensions' => ['testExtOne'],
+ 'extension_versions' => ['testExtOne' => ['version' => '1.0', 'operator' => '==']]
+ ]
+ ],
+ ['testExtensionVersionOperatorBangEquals',
+ [
+ 'extensions' => ['testExtOne'],
+ 'extension_versions' => ['testExtOne' => ['version' => '99', 'operator' => '!=']]
+ ]
+ ],
+ ['testExtensionVersionOperatorNotEquals',
+ [
+ 'extensions' => ['testExtOne'],
+ 'extension_versions' => ['testExtOne' => ['version' => '99', 'operator' => '<>']]
+ ]
+ ],
+ ['testExtensionVersionOperatorNoSpace',
+ [
+ 'extensions' => ['testExtOne'],
+ 'extension_versions' => ['testExtOne' => ['version' => '99', 'operator' => '>=']]
+ ]
+ ],
+ ];
+ }
+
+ public function testGetRequirementsMergesClassAndMethodDocBlocks()
+ {
+ $expectedAnnotations = [
+ 'PHP' => ['version' => '5.4', 'operator' => ''],
+ 'PHPUnit' => ['version' => '3.7', 'operator' => ''],
+ 'OS' => '/WINNT/i',
+ 'functions' => [
+ 'testFuncClass',
+ 'testFuncMethod',
+ ],
+ 'extensions' => [
+ 'testExtClass',
+ 'testExtMethod',
+ ]
+ ];
+
+ $this->assertEquals(
+ $expectedAnnotations,
+ PHPUnit_Util_Test::getRequirements('RequirementsClassDocBlockTest', 'testMethod')
+ );
+ }
+
+ /**
+ * @dataProvider missingRequirementsProvider
+ */
+ public function testGetMissingRequirements($test, $result)
+ {
+ $this->assertEquals(
+ $result,
+ PHPUnit_Util_Test::getMissingRequirements('RequirementsTest', $test)
+ );
+ }
+
+ public function missingRequirementsProvider()
+ {
+ return [
+ ['testOne', []],
+ ['testNine', ['Function testFunc is required.']],
+ ['testTen', ['Extension testExt is required.']],
+ ['testAlwaysSkip', ['PHPUnit >= 1111111 is required.']],
+ ['testAlwaysSkip2', ['PHP >= 9999999 is required.']],
+ ['testAlwaysSkip3', ['Operating system matching /DOESNOTEXIST/i is required.']],
+ ['testAllPossibleRequirements', [
+ 'PHP >= 99-dev is required.',
+ 'PHPUnit >= 9-dev is required.',
+ 'Operating system matching /DOESNOTEXIST/i is required.',
+ 'Function testFuncOne is required.',
+ 'Function testFuncTwo is required.',
+ 'Extension testExtOne is required.',
+ 'Extension testExtTwo is required.',
+ 'Extension testExtThree >= 2.0 is required.',
+ ]],
+ ['testPHPVersionOperatorLessThan', ['PHP < 5.4 is required.']],
+ ['testPHPVersionOperatorLessThanEquals', ['PHP <= 5.4 is required.']],
+ ['testPHPVersionOperatorGreaterThan', ['PHP > 99 is required.']],
+ ['testPHPVersionOperatorGreaterThanEquals', ['PHP >= 99 is required.']],
+ ['testPHPVersionOperatorNoSpace', ['PHP >= 99 is required.']],
+ ['testPHPVersionOperatorEquals', ['PHP = 5.4 is required.']],
+ ['testPHPVersionOperatorDoubleEquals', ['PHP == 5.4 is required.']],
+ ['testPHPUnitVersionOperatorLessThan', ['PHPUnit < 1.0 is required.']],
+ ['testPHPUnitVersionOperatorLessThanEquals', ['PHPUnit <= 1.0 is required.']],
+ ['testPHPUnitVersionOperatorGreaterThan', ['PHPUnit > 99 is required.']],
+ ['testPHPUnitVersionOperatorGreaterThanEquals', ['PHPUnit >= 99 is required.']],
+ ['testPHPUnitVersionOperatorEquals', ['PHPUnit = 1.0 is required.']],
+ ['testPHPUnitVersionOperatorDoubleEquals', ['PHPUnit == 1.0 is required.']],
+ ['testPHPUnitVersionOperatorNoSpace', ['PHPUnit >= 99 is required.']],
+ ['testExtensionVersionOperatorLessThan', ['Extension testExtOne < 1.0 is required.']],
+ ['testExtensionVersionOperatorLessThanEquals', ['Extension testExtOne <= 1.0 is required.']],
+ ['testExtensionVersionOperatorGreaterThan', ['Extension testExtOne > 99 is required.']],
+ ['testExtensionVersionOperatorGreaterThanEquals', ['Extension testExtOne >= 99 is required.']],
+ ['testExtensionVersionOperatorEquals', ['Extension testExtOne = 1.0 is required.']],
+ ['testExtensionVersionOperatorDoubleEquals', ['Extension testExtOne == 1.0 is required.']],
+ ['testExtensionVersionOperatorNoSpace', ['Extension testExtOne >= 99 is required.']],
+ ];
+ }
+
+ /**
+ * @todo This test does not really test functionality of PHPUnit_Util_Test
+ */
+ public function testGetProvidedDataRegEx()
+ {
+ $result = preg_match(PHPUnit_Util_Test::REGEX_DATA_PROVIDER, '@dataProvider method', $matches);
+ $this->assertEquals(1, $result);
+ $this->assertEquals('method', $matches[1]);
+
+ $result = preg_match(PHPUnit_Util_Test::REGEX_DATA_PROVIDER, '@dataProvider class::method', $matches);
+ $this->assertEquals(1, $result);
+ $this->assertEquals('class::method', $matches[1]);
+
+ $result = preg_match(PHPUnit_Util_Test::REGEX_DATA_PROVIDER, '@dataProvider namespace\class::method', $matches);
+ $this->assertEquals(1, $result);
+ $this->assertEquals('namespace\class::method', $matches[1]);
+
+ $result = preg_match(PHPUnit_Util_Test::REGEX_DATA_PROVIDER, '@dataProvider namespace\namespace\class::method', $matches);
+ $this->assertEquals(1, $result);
+ $this->assertEquals('namespace\namespace\class::method', $matches[1]);
+
+ $result = preg_match(PHPUnit_Util_Test::REGEX_DATA_PROVIDER, '@dataProvider メソッド', $matches);
+ $this->assertEquals(1, $result);
+ $this->assertEquals('メソッド', $matches[1]);
+ }
+
+ /**
+ * Check if all data providers are being merged.
+ */
+ public function testMultipleDataProviders()
+ {
+ $dataSets = PHPUnit_Util_Test::getProvidedData('MultipleDataProviderTest', 'testOne');
+
+ $this->assertCount(9, $dataSets);
+
+ $aCount = 0;
+ $bCount = 0;
+ $cCount = 0;
+
+ for ($i = 0; $i < 9; $i++) {
+ $aCount += $dataSets[$i][0] != null ? 1 : 0;
+ $bCount += $dataSets[$i][1] != null ? 1 : 0;
+ $cCount += $dataSets[$i][2] != null ? 1 : 0;
+ }
+
+ $this->assertEquals(3, $aCount);
+ $this->assertEquals(3, $bCount);
+ $this->assertEquals(3, $cCount);
+ }
+
+ /**
+ * Check with a multiple yield / iterator data providers.
+ */
+ public function testMultipleYieldIteratorDataProviders()
+ {
+ $dataSets = PHPUnit_Util_Test::getProvidedData('MultipleDataProviderTest', 'testTwo');
+
+ $this->assertEquals(9, count($dataSets));
+
+ $aCount = 0;
+ $bCount = 0;
+ $cCount = 0;
+
+ for ($i = 0; $i < 9; $i++) {
+ $aCount += $dataSets[$i][0] != null ? 1 : 0;
+ $bCount += $dataSets[$i][1] != null ? 1 : 0;
+ $cCount += $dataSets[$i][2] != null ? 1 : 0;
+ }
+
+ $this->assertEquals(3, $aCount);
+ $this->assertEquals(3, $bCount);
+ $this->assertEquals(3, $cCount);
+ }
+
+ public function testTestWithEmptyAnnotation()
+ {
+ $result = PHPUnit_Util_Test::getDataFromTestWithAnnotation("/**\n * @anotherAnnotation\n */");
+ $this->assertNull($result);
+ }
+
+ public function testTestWithSimpleCase()
+ {
+ $result = PHPUnit_Util_Test::getDataFromTestWithAnnotation('/**
+ * @testWith [1]
+ */');
+ $this->assertEquals([[1]], $result);
+ }
+
+ public function testTestWithMultiLineMultiParameterCase()
+ {
+ $result = PHPUnit_Util_Test::getDataFromTestWithAnnotation('/**
+ * @testWith [1, 2]
+ * [3, 4]
+ */');
+ $this->assertEquals([[1, 2], [3, 4]], $result);
+ }
+
+ public function testTestWithVariousTypes()
+ {
+ $result = PHPUnit_Util_Test::getDataFromTestWithAnnotation('/**
+ * @testWith ["ab"]
+ * [true]
+ * [null]
+ */');
+ $this->assertEquals([['ab'], [true], [null]], $result);
+ }
+
+ public function testTestWithAnnotationAfter()
+ {
+ $result = PHPUnit_Util_Test::getDataFromTestWithAnnotation('/**
+ * @testWith [1]
+ * [2]
+ * @annotation
+ */');
+ $this->assertEquals([[1], [2]], $result);
+ }
+
+ public function testTestWithSimpleTextAfter()
+ {
+ $result = PHPUnit_Util_Test::getDataFromTestWithAnnotation('/**
+ * @testWith [1]
+ * [2]
+ * blah blah
+ */');
+ $this->assertEquals([[1], [2]], $result);
+ }
+
+ public function testTestWithCharacterEscape()
+ {
+ $result = PHPUnit_Util_Test::getDataFromTestWithAnnotation('/**
+ * @testWith ["\"", "\""]
+ */');
+ $this->assertEquals([['"', '"']], $result);
+ }
+
+ public function testTestWithThrowsProperExceptionIfDatasetCannotBeParsed()
+ {
+ $this->expectException(PHPUnit_Framework_Exception::class);
+ $this->expectExceptionMessageRegExp('/^The dataset for the @testWith annotation cannot be parsed:/');
+
+ PHPUnit_Util_Test::getDataFromTestWithAnnotation('/**
+ * @testWith [s]
+ */');
+ }
+
+ public function testTestWithThrowsProperExceptionIfMultiLineDatasetCannotBeParsed()
+ {
+ $this->expectException(PHPUnit_Framework_Exception::class);
+ $this->expectExceptionMessageRegExp('/^The dataset for the @testWith annotation cannot be parsed:/');
+
+ PHPUnit_Util_Test::getDataFromTestWithAnnotation('/**
+ * @testWith ["valid"]
+ * [invalid]
+ */');
+ }
+
+ /**
+ * @todo Not sure what this test tests (name is misleading at least)
+ */
+ public function testParseAnnotation()
+ {
+ $this->assertEquals(
+ ['Foo', 'ほげ'],
+ PHPUnit_Util_Test::getDependencies(get_class($this), 'methodForTestParseAnnotation')
+ );
+ }
+
+ /**
+ * @depends Foo
+ * @depends ほげ
+ *
+ * @todo Remove fixture from test class
+ */
+ public function methodForTestParseAnnotation()
+ {
+ }
+
+ public function testParseAnnotationThatIsOnlyOneLine()
+ {
+ $this->assertEquals(
+ ['Bar'],
+ PHPUnit_Util_Test::getDependencies(get_class($this), 'methodForTestParseAnnotationThatIsOnlyOneLine')
+ );
+ }
+
+ /** @depends Bar */
+ public function methodForTestParseAnnotationThatIsOnlyOneLine()
+ {
+ // TODO Remove fixture from test class
+ }
+
+ /**
+ * @dataProvider getLinesToBeCoveredProvider
+ */
+ public function testGetLinesToBeCovered($test, $lines)
+ {
+ if (strpos($test, 'Namespace') === 0) {
+ $expected = [
+ TEST_FILES_PATH . 'NamespaceCoveredClass.php' => $lines
+ ];
+ } elseif ($test === 'CoverageNoneTest') {
+ $expected = [];
+ } elseif ($test === 'CoverageNothingTest') {
+ $expected = false;
+ } elseif ($test === 'CoverageFunctionTest') {
+ $expected = [
+ TEST_FILES_PATH . 'CoveredFunction.php' => $lines
+ ];
+ } else {
+ $expected = [TEST_FILES_PATH . 'CoveredClass.php' => $lines];
+ }
+
+ $this->assertEquals(
+ $expected,
+ PHPUnit_Util_Test::getLinesToBeCovered(
+ $test, 'testSomething'
+ )
+ );
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_CodeCoverageException
+ */
+ public function testGetLinesToBeCovered2()
+ {
+ PHPUnit_Util_Test::getLinesToBeCovered(
+ 'NotExistingCoveredElementTest', 'testOne'
+ );
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_CodeCoverageException
+ */
+ public function testGetLinesToBeCovered3()
+ {
+ PHPUnit_Util_Test::getLinesToBeCovered(
+ 'NotExistingCoveredElementTest', 'testTwo'
+ );
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_CodeCoverageException
+ */
+ public function testGetLinesToBeCovered4()
+ {
+ PHPUnit_Util_Test::getLinesToBeCovered(
+ 'NotExistingCoveredElementTest', 'testThree'
+ );
+ }
+
+ public function testGetLinesToBeCoveredSkipsNonExistentMethods()
+ {
+ $this->assertSame(
+ [],
+ PHPUnit_Util_Test::getLinesToBeCovered(
+ 'NotExistingCoveredElementTest',
+ 'methodDoesNotExist'
+ )
+ );
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_CodeCoverageException
+ */
+ public function testTwoCoversDefaultClassAnnoationsAreNotAllowed()
+ {
+ PHPUnit_Util_Test::getLinesToBeCovered(
+ 'CoverageTwoDefaultClassAnnotations',
+ 'testSomething'
+ );
+ }
+
+ public function testFunctionParenthesesAreAllowed()
+ {
+ $this->assertSame(
+ [TEST_FILES_PATH . 'CoveredFunction.php' => range(2, 4)],
+ PHPUnit_Util_Test::getLinesToBeCovered(
+ 'CoverageFunctionParenthesesTest',
+ 'testSomething'
+ )
+ );
+ }
+
+ public function testFunctionParenthesesAreAllowedWithWhitespace()
+ {
+ $this->assertSame(
+ [TEST_FILES_PATH . 'CoveredFunction.php' => range(2, 4)],
+ PHPUnit_Util_Test::getLinesToBeCovered(
+ 'CoverageFunctionParenthesesWhitespaceTest',
+ 'testSomething'
+ )
+ );
+ }
+
+ public function testMethodParenthesesAreAllowed()
+ {
+ $this->assertSame(
+ [TEST_FILES_PATH . 'CoveredClass.php' => range(31, 35)],
+ PHPUnit_Util_Test::getLinesToBeCovered(
+ 'CoverageMethodParenthesesTest',
+ 'testSomething'
+ )
+ );
+ }
+
+ public function testMethodParenthesesAreAllowedWithWhitespace()
+ {
+ $this->assertSame(
+ [TEST_FILES_PATH . 'CoveredClass.php' => range(31, 35)],
+ PHPUnit_Util_Test::getLinesToBeCovered(
+ 'CoverageMethodParenthesesWhitespaceTest',
+ 'testSomething'
+ )
+ );
+ }
+
+ public function testNamespacedFunctionCanBeCoveredOrUsed()
+ {
+ $this->assertEquals(
+ [
+ TEST_FILES_PATH . 'NamespaceCoveredFunction.php' => range(4, 7)
+ ],
+ PHPUnit_Util_Test::getLinesToBeCovered(
+ 'CoverageNamespacedFunctionTest',
+ 'testFunc'
+ )
+ );
+ }
+
+ public function getLinesToBeCoveredProvider()
+ {
+ return [
+ [
+ 'CoverageNoneTest',
+ []
+ ],
+ [
+ 'CoverageClassExtendedTest',
+ array_merge(range(19, 36), range(2, 17))
+ ],
+ [
+ 'CoverageClassTest',
+ range(19, 36)
+ ],
+ [
+ 'CoverageMethodTest',
+ range(31, 35)
+ ],
+ [
+ 'CoverageMethodOneLineAnnotationTest',
+ range(31, 35)
+ ],
+ [
+ 'CoverageNotPrivateTest',
+ array_merge(range(25, 29), range(31, 35))
+ ],
+ [
+ 'CoverageNotProtectedTest',
+ array_merge(range(21, 23), range(31, 35))
+ ],
+ [
+ 'CoverageNotPublicTest',
+ array_merge(range(21, 23), range(25, 29))
+ ],
+ [
+ 'CoveragePrivateTest',
+ range(21, 23)
+ ],
+ [
+ 'CoverageProtectedTest',
+ range(25, 29)
+ ],
+ [
+ 'CoveragePublicTest',
+ range(31, 35)
+ ],
+ [
+ 'CoverageFunctionTest',
+ range(2, 4)
+ ],
+ [
+ 'NamespaceCoverageClassExtendedTest',
+ array_merge(range(21, 38), range(4, 19))
+ ],
+ [
+ 'NamespaceCoverageClassTest',
+ range(21, 38)
+ ],
+ [
+ 'NamespaceCoverageMethodTest',
+ range(33, 37)
+ ],
+ [
+ 'NamespaceCoverageNotPrivateTest',
+ array_merge(range(27, 31), range(33, 37))
+ ],
+ [
+ 'NamespaceCoverageNotProtectedTest',
+ array_merge(range(23, 25), range(33, 37))
+ ],
+ [
+ 'NamespaceCoverageNotPublicTest',
+ array_merge(range(23, 25), range(27, 31))
+ ],
+ [
+ 'NamespaceCoveragePrivateTest',
+ range(23, 25)
+ ],
+ [
+ 'NamespaceCoverageProtectedTest',
+ range(27, 31)
+ ],
+ [
+ 'NamespaceCoveragePublicTest',
+ range(33, 37)
+ ],
+ [
+ 'NamespaceCoverageCoversClassTest',
+ array_merge(range(23, 25), range(27, 31), range(33, 37), range(6, 8), range(10, 13), range(15, 18))
+ ],
+ [
+ 'NamespaceCoverageCoversClassPublicTest',
+ range(33, 37)
+ ],
+ [
+ 'CoverageNothingTest',
+ false
+ ]
+ ];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/Util/XMLTest.php b/vendor/phpunit/phpunit/tests/Util/XMLTest.php
new file mode 100644
index 0000000..ae05464
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/Util/XMLTest.php
@@ -0,0 +1,90 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Util_XMLTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider charProvider
+ */
+ public function testPrepareString($char)
+ {
+ $e = null;
+
+ $escapedString = PHPUnit_Util_XML::prepareString($char);
+ $xml = "<?xml version='1.0' encoding='UTF-8' ?><tag>$escapedString</tag>";
+ $dom = new DomDocument('1.0', 'UTF-8');
+
+ try {
+ $dom->loadXML($xml);
+ } catch (Exception $e) {
+ }
+
+ $this->assertNull($e, sprintf(
+ 'PHPUnit_Util_XML::prepareString("\x%02x") should not crash DomDocument',
+ ord($char)
+ ));
+ }
+
+ public function charProvider()
+ {
+ $data = [];
+
+ for ($i = 0; $i < 256; $i++) {
+ $data[] = [chr($i)];
+ }
+
+ return $data;
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ * @expectedExceptionMessage Could not load XML from empty string
+ */
+ public function testLoadEmptyString()
+ {
+ PHPUnit_Util_XML::load('');
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ * @expectedExceptionMessage Could not load XML from array
+ */
+ public function testLoadArray()
+ {
+ PHPUnit_Util_XML::load([1, 2, 3]);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Exception
+ * @expectedExceptionMessage Could not load XML from boolean
+ */
+ public function testLoadBoolean()
+ {
+ PHPUnit_Util_XML::load(false);
+ }
+
+ public function testNestedXmlToVariable()
+ {
+ $xml = '<array><element key="a"><array><element key="b"><string>foo</string></element></array></element><element key="c"><string>bar</string></element></array>';
+ $dom = new DOMDocument();
+ $dom->loadXML($xml);
+
+ $expected = [
+ 'a' => [
+ 'b' => 'foo',
+ ],
+ 'c' => 'bar',
+ ];
+
+ $actual = PHPUnit_Util_XML::xmlToVariable($dom->documentElement);
+
+ $this->assertSame($expected, $actual);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/AbstractTest.php b/vendor/phpunit/phpunit/tests/_files/AbstractTest.php
new file mode 100644
index 0000000..556e7db
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/AbstractTest.php
@@ -0,0 +1,7 @@
+<?php
+abstract class AbstractTest extends PHPUnit_Framework_TestCase
+{
+ public function testOne()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/ArrayAccessible.php b/vendor/phpunit/phpunit/tests/_files/ArrayAccessible.php
new file mode 100644
index 0000000..4eb2fd1
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/ArrayAccessible.php
@@ -0,0 +1,40 @@
+<?php
+
+class ArrayAccessible implements ArrayAccess, IteratorAggregate
+{
+ private $array;
+
+ public function __construct(array $array = [])
+ {
+ $this->array = $array;
+ }
+
+ public function offsetExists($offset)
+ {
+ return array_key_exists($offset, $this->array);
+ }
+
+ public function offsetGet($offset)
+ {
+ return $this->array[$offset];
+ }
+
+ public function offsetSet($offset, $value)
+ {
+ if (null === $offset) {
+ $this->array[] = $value;
+ } else {
+ $this->array[$offset] = $value;
+ }
+ }
+
+ public function offsetUnset($offset)
+ {
+ unset($this->array[$offset]);
+ }
+
+ public function getIterator()
+ {
+ return new ArrayIterator($this->array);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/AssertionExample.php b/vendor/phpunit/phpunit/tests/_files/AssertionExample.php
new file mode 100644
index 0000000..d830f15
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/AssertionExample.php
@@ -0,0 +1,8 @@
+<?php
+class AssertionExample
+{
+ public function doSomething()
+ {
+ assert(false);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/AssertionExampleTest.php b/vendor/phpunit/phpunit/tests/_files/AssertionExampleTest.php
new file mode 100644
index 0000000..a28e9ab
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/AssertionExampleTest.php
@@ -0,0 +1,10 @@
+<?php
+class AssertionExampleTest extends PHPUnit_Framework_TestCase
+{
+ public function testOne()
+ {
+ $e = new AssertionExample;
+
+ $e->doSomething();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/Author.php b/vendor/phpunit/phpunit/tests/_files/Author.php
new file mode 100644
index 0000000..9959dac
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/Author.php
@@ -0,0 +1,26 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * An author.
+ *
+ */
+class Author
+{
+ // the order of properties is important for testing the cycle!
+ public $books = [];
+
+ private $name = '';
+
+ public function __construct($name)
+ {
+ $this->name = $name;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/BankAccount.php b/vendor/phpunit/phpunit/tests/_files/BankAccount.php
new file mode 100644
index 0000000..6acf7e9
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/BankAccount.php
@@ -0,0 +1,81 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class BankAccountException extends RuntimeException
+{
+}
+
+/**
+ * A bank account.
+ *
+ */
+class BankAccount
+{
+ /**
+ * The bank account's balance.
+ *
+ * @var float
+ */
+ protected $balance = 0;
+
+ /**
+ * Returns the bank account's balance.
+ *
+ * @return float
+ */
+ public function getBalance()
+ {
+ return $this->balance;
+ }
+
+ /**
+ * Sets the bank account's balance.
+ *
+ * @param float $balance
+ *
+ * @throws BankAccountException
+ */
+ protected function setBalance($balance)
+ {
+ if ($balance >= 0) {
+ $this->balance = $balance;
+ } else {
+ throw new BankAccountException;
+ }
+ }
+
+ /**
+ * Deposits an amount of money to the bank account.
+ *
+ * @param float $balance
+ *
+ * @throws BankAccountException
+ */
+ public function depositMoney($balance)
+ {
+ $this->setBalance($this->getBalance() + $balance);
+
+ return $this->getBalance();
+ }
+
+ /**
+ * Withdraws an amount of money from the bank account.
+ *
+ * @param float $balance
+ *
+ * @throws BankAccountException
+ */
+ public function withdrawMoney($balance)
+ {
+ $this->setBalance($this->getBalance() - $balance);
+
+ return $this->getBalance();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/BankAccountTest.php b/vendor/phpunit/phpunit/tests/_files/BankAccountTest.php
new file mode 100644
index 0000000..76c3ab3
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/BankAccountTest.php
@@ -0,0 +1,93 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Tests for the BankAccount class.
+ *
+ */
+class BankAccountTest extends PHPUnit_Framework_TestCase
+{
+ protected $ba;
+
+ protected function setUp()
+ {
+ $this->ba = new BankAccount;
+ }
+
+ /**
+ * @covers BankAccount::getBalance
+ * @group balanceIsInitiallyZero
+ * @group specification
+ */
+ public function testBalanceIsInitiallyZero()
+ {
+ /* @Given a fresh bank account */
+ $ba = new BankAccount;
+
+ /* @When I ask it for its balance */
+ $balance = $ba->getBalance();
+
+ /* @Then I should get 0 */
+ $this->assertEquals(0, $balance);
+ }
+
+ /**
+ * @covers BankAccount::withdrawMoney
+ * @group balanceCannotBecomeNegative
+ * @group specification
+ */
+ public function testBalanceCannotBecomeNegative()
+ {
+ try {
+ $this->ba->withdrawMoney(1);
+ } catch (BankAccountException $e) {
+ $this->assertEquals(0, $this->ba->getBalance());
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @covers BankAccount::depositMoney
+ * @group balanceCannotBecomeNegative
+ * @group specification
+ */
+ public function testBalanceCannotBecomeNegative2()
+ {
+ try {
+ $this->ba->depositMoney(-1);
+ } catch (BankAccountException $e) {
+ $this->assertEquals(0, $this->ba->getBalance());
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /*
+ * @covers BankAccount::getBalance
+ * @covers BankAccount::depositMoney
+ * @covers BankAccount::withdrawMoney
+ * @group balanceCannotBecomeNegative
+ */
+ /*
+ public function testDepositingAndWithdrawingMoneyWorks()
+ {
+ $this->assertEquals(0, $this->ba->getBalance());
+ $this->ba->depositMoney(1);
+ $this->assertEquals(1, $this->ba->getBalance());
+ $this->ba->withdrawMoney(1);
+ $this->assertEquals(0, $this->ba->getBalance());
+ }
+ */
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/BankAccountTest.test.php b/vendor/phpunit/phpunit/tests/_files/BankAccountTest.test.php
new file mode 100644
index 0000000..63962c5
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/BankAccountTest.test.php
@@ -0,0 +1,86 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Tests for the BankAccount class.
+ *
+ */
+class BankAccountWithCustomExtensionTest extends PHPUnit_Framework_TestCase
+{
+ protected $ba;
+
+ protected function setUp()
+ {
+ $this->ba = new BankAccount;
+ }
+
+ /**
+ * @covers BankAccount::getBalance
+ * @group balanceIsInitiallyZero
+ * @group specification
+ */
+ public function testBalanceIsInitiallyZero()
+ {
+ $this->assertEquals(0, $this->ba->getBalance());
+ }
+
+ /**
+ * @covers BankAccount::withdrawMoney
+ * @group balanceCannotBecomeNegative
+ * @group specification
+ */
+ public function testBalanceCannotBecomeNegative()
+ {
+ try {
+ $this->ba->withdrawMoney(1);
+ } catch (BankAccountException $e) {
+ $this->assertEquals(0, $this->ba->getBalance());
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /**
+ * @covers BankAccount::depositMoney
+ * @group balanceCannotBecomeNegative
+ * @group specification
+ */
+ public function testBalanceCannotBecomeNegative2()
+ {
+ try {
+ $this->ba->depositMoney(-1);
+ } catch (BankAccountException $e) {
+ $this->assertEquals(0, $this->ba->getBalance());
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ /*
+ * @covers BankAccount::getBalance
+ * @covers BankAccount::depositMoney
+ * @covers BankAccount::withdrawMoney
+ * @group balanceCannotBecomeNegative
+ */
+ /*
+ public function testDepositingAndWithdrawingMoneyWorks()
+ {
+ $this->assertEquals(0, $this->ba->getBalance());
+ $this->ba->depositMoney(1);
+ $this->assertEquals(1, $this->ba->getBalance());
+ $this->ba->withdrawMoney(1);
+ $this->assertEquals(0, $this->ba->getBalance());
+ }
+ */
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/BankAccountTest2.php b/vendor/phpunit/phpunit/tests/_files/BankAccountTest2.php
new file mode 100644
index 0000000..811c908
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/BankAccountTest2.php
@@ -0,0 +1,56 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use PHPUnit\Framework\TestCase;
+
+class BankAccountTest extends TestCase
+{
+ private $ba;
+
+ protected function setUp()
+ {
+ $this->ba = new BankAccount;
+ }
+
+ public function testBalanceIsInitiallyZero()
+ {
+ $ba = new BankAccount;
+
+ $balance = $ba->getBalance();
+
+ $this->assertEquals(0, $balance);
+ }
+
+ public function testBalanceCannotBecomeNegative()
+ {
+ try {
+ $this->ba->withdrawMoney(1);
+ } catch (BankAccountException $e) {
+ $this->assertEquals(0, $this->ba->getBalance());
+
+ return;
+ }
+
+ $this->fail();
+ }
+
+ public function testBalanceCannotBecomeNegative2()
+ {
+ try {
+ $this->ba->depositMoney(-1);
+ } catch (BankAccountException $e) {
+ $this->assertEquals(0, $this->ba->getBalance());
+
+ return;
+ }
+
+ $this->fail();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/BaseTestListenerSample.php b/vendor/phpunit/phpunit/tests/_files/BaseTestListenerSample.php
new file mode 100644
index 0000000..7753b28
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/BaseTestListenerSample.php
@@ -0,0 +1,11 @@
+<?php
+
+class BaseTestListenerSample extends PHPUnit_Framework_BaseTestListener
+{
+ public $endCount = 0;
+
+ public function endTest(PHPUnit_Framework_Test $test, $time)
+ {
+ $this->endCount++;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/BeforeAndAfterTest.php b/vendor/phpunit/phpunit/tests/_files/BeforeAndAfterTest.php
new file mode 100644
index 0000000..0b52526
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/BeforeAndAfterTest.php
@@ -0,0 +1,35 @@
+<?php
+class BeforeAndAfterTest extends PHPUnit_Framework_TestCase
+{
+ public static $beforeWasRun;
+ public static $afterWasRun;
+
+ public static function resetProperties()
+ {
+ self::$beforeWasRun = 0;
+ self::$afterWasRun = 0;
+ }
+
+ /**
+ * @before
+ */
+ public function initialSetup()
+ {
+ self::$beforeWasRun++;
+ }
+
+ /**
+ * @after
+ */
+ public function finalTeardown()
+ {
+ self::$afterWasRun++;
+ }
+
+ public function test1()
+ {
+ }
+ public function test2()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/BeforeClassAndAfterClassTest.php b/vendor/phpunit/phpunit/tests/_files/BeforeClassAndAfterClassTest.php
new file mode 100644
index 0000000..9afb4f1
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/BeforeClassAndAfterClassTest.php
@@ -0,0 +1,35 @@
+<?php
+class BeforeClassAndAfterClassTest extends PHPUnit_Framework_TestCase
+{
+ public static $beforeClassWasRun = 0;
+ public static $afterClassWasRun = 0;
+
+ public static function resetProperties()
+ {
+ self::$beforeClassWasRun = 0;
+ self::$afterClassWasRun = 0;
+ }
+
+ /**
+ * @beforeClass
+ */
+ public static function initialClassSetup()
+ {
+ self::$beforeClassWasRun++;
+ }
+
+ /**
+ * @afterClass
+ */
+ public static function finalClassTeardown()
+ {
+ self::$afterClassWasRun++;
+ }
+
+ public function test1()
+ {
+ }
+ public function test2()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/BeforeClassWithOnlyDataProviderTest.php b/vendor/phpunit/phpunit/tests/_files/BeforeClassWithOnlyDataProviderTest.php
new file mode 100644
index 0000000..8f556a0
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/BeforeClassWithOnlyDataProviderTest.php
@@ -0,0 +1,39 @@
+<?php
+class BeforeClassWithOnlyDataProviderTest extends \PHPUnit_Framework_TestCase
+{
+ public static $setUpBeforeClassWasCalled;
+ public static $beforeClassWasCalled;
+
+ public static function resetProperties()
+ {
+ self::$setUpBeforeClassWasCalled = false;
+ self::$beforeClassWasCalled = false;
+ }
+
+ public static function setUpBeforeClass()
+ {
+ self::$setUpBeforeClassWasCalled = true;
+ }
+
+ /**
+ * @beforeClass
+ */
+ public static function someAnnotatedSetupMethod()
+ {
+ self::$beforeClassWasCalled = true;
+ }
+
+ public function dummyProvider()
+ {
+ return [[1]];
+ }
+
+ /**
+ * @dataProvider dummyProvider
+ * delete annotation to fail test case
+ */
+ public function testDummy()
+ {
+ $this->assertFalse(false);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/Book.php b/vendor/phpunit/phpunit/tests/_files/Book.php
new file mode 100644
index 0000000..0c3485d
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/Book.php
@@ -0,0 +1,19 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A book.
+ *
+ */
+class Book
+{
+ // the order of properties is important for testing the cycle!
+ public $author = null;
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/Calculator.php b/vendor/phpunit/phpunit/tests/_files/Calculator.php
new file mode 100644
index 0000000..e269bd6
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/Calculator.php
@@ -0,0 +1,14 @@
+<?php
+class Calculator
+{
+ /**
+ * @assert (0, 0) == 0
+ * @assert (0, 1) == 1
+ * @assert (1, 0) == 1
+ * @assert (1, 1) == 2
+ */
+ public function add($a, $b)
+ {
+ return $a + $b;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/ChangeCurrentWorkingDirectoryTest.php b/vendor/phpunit/phpunit/tests/_files/ChangeCurrentWorkingDirectoryTest.php
new file mode 100644
index 0000000..70fab0b
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/ChangeCurrentWorkingDirectoryTest.php
@@ -0,0 +1,9 @@
+<?php
+class ChangeCurrentWorkingDirectoryTest extends PHPUnit_Framework_TestCase
+{
+ public function testSomethingThatChangesTheCwd()
+ {
+ chdir('../');
+ $this->assertTrue(true);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/ClassWithNonPublicAttributes.php b/vendor/phpunit/phpunit/tests/_files/ClassWithNonPublicAttributes.php
new file mode 100644
index 0000000..ec285b8
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/ClassWithNonPublicAttributes.php
@@ -0,0 +1,29 @@
+<?php
+class ParentClassWithPrivateAttributes
+{
+ private static $privateStaticParentAttribute = 'foo';
+ private $privateParentAttribute = 'bar';
+}
+
+class ParentClassWithProtectedAttributes extends ParentClassWithPrivateAttributes
+{
+ protected static $protectedStaticParentAttribute = 'foo';
+ protected $protectedParentAttribute = 'bar';
+}
+
+class ClassWithNonPublicAttributes extends ParentClassWithProtectedAttributes
+{
+ public static $publicStaticAttribute = 'foo';
+ protected static $protectedStaticAttribute = 'bar';
+ protected static $privateStaticAttribute = 'baz';
+
+ public $publicAttribute = 'foo';
+ public $foo = 1;
+ public $bar = 2;
+ protected $protectedAttribute = 'bar';
+ protected $privateAttribute = 'baz';
+
+ public $publicArray = ['foo'];
+ protected $protectedArray = ['bar'];
+ protected $privateArray = ['baz'];
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/ClassWithScalarTypeDeclarations.php b/vendor/phpunit/phpunit/tests/_files/ClassWithScalarTypeDeclarations.php
new file mode 100644
index 0000000..8f20f32
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/ClassWithScalarTypeDeclarations.php
@@ -0,0 +1,7 @@
+<?php
+class ClassWithScalarTypeDeclarations
+{
+ public function foo(string $string, int $int)
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/ClassWithToString.php b/vendor/phpunit/phpunit/tests/_files/ClassWithToString.php
new file mode 100644
index 0000000..0b6b497
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/ClassWithToString.php
@@ -0,0 +1,21 @@
+<?php
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * A class with a __toString() method.
+ *
+ */
+class ClassWithToString
+{
+ public function __toString()
+ {
+ return 'string representation';
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/ClonedDependencyTest.php b/vendor/phpunit/phpunit/tests/_files/ClonedDependencyTest.php
new file mode 100644
index 0000000..ce3b04d
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/ClonedDependencyTest.php
@@ -0,0 +1,39 @@
+<?php
+class ClonedDependencyTest extends PHPUnit_Framework_TestCase
+{
+ private static $dependency;
+
+ public static function setUpBeforeClass()
+ {
+ self::$dependency = new StdClass;
+ }
+
+ public function testOne()
+ {
+ return self::$dependency;
+ }
+
+ /**
+ * @depends testOne
+ */
+ public function testTwo($dependency)
+ {
+ $this->assertSame(self::$dependency, $dependency);
+ }
+
+ /**
+ * @depends !clone testOne
+ */
+ public function testThree($dependency)
+ {
+ $this->assertSame(self::$dependency, $dependency);
+ }
+
+ /**
+ * @depends clone testOne
+ */
+ public function testFour($dependency)
+ {
+ $this->assertNotSame(self::$dependency, $dependency);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/ConcreteTest.my.php b/vendor/phpunit/phpunit/tests/_files/ConcreteTest.my.php
new file mode 100644
index 0000000..fe01cee
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/ConcreteTest.my.php
@@ -0,0 +1,7 @@
+<?php
+class ConcreteWithMyCustomExtensionTest extends AbstractTest
+{
+ public function testTwo()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/ConcreteTest.php b/vendor/phpunit/phpunit/tests/_files/ConcreteTest.php
new file mode 100644
index 0000000..4f51a18
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/ConcreteTest.php
@@ -0,0 +1,7 @@
+<?php
+class ConcreteTest extends AbstractTest
+{
+ public function testTwo()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageClassExtendedTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageClassExtendedTest.php
new file mode 100644
index 0000000..df12d34
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoverageClassExtendedTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoverageClassExtendedTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass<extended>
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageClassTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageClassTest.php
new file mode 100644
index 0000000..7f569ae
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoverageClassTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoverageClassTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageFunctionParenthesesTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageFunctionParenthesesTest.php
new file mode 100644
index 0000000..33b5fe3
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoverageFunctionParenthesesTest.php
@@ -0,0 +1,11 @@
+<?php
+class CoverageFunctionParenthesesTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers ::globalFunction()
+ */
+ public function testSomething()
+ {
+ globalFunction();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageFunctionParenthesesWhitespaceTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageFunctionParenthesesWhitespaceTest.php
new file mode 100644
index 0000000..becc6c8
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoverageFunctionParenthesesWhitespaceTest.php
@@ -0,0 +1,11 @@
+<?php
+class CoverageFunctionParenthesesWhitespaceTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers ::globalFunction ( )
+ */
+ public function testSomething()
+ {
+ globalFunction();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageFunctionTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageFunctionTest.php
new file mode 100644
index 0000000..c621fd2
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoverageFunctionTest.php
@@ -0,0 +1,11 @@
+<?php
+class CoverageFunctionTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers ::globalFunction
+ */
+ public function testSomething()
+ {
+ globalFunction();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageMethodOneLineAnnotationTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageMethodOneLineAnnotationTest.php
new file mode 100644
index 0000000..55d7f57
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoverageMethodOneLineAnnotationTest.php
@@ -0,0 +1,11 @@
+<?php
+
+class CoverageMethodOneLineAnnotationTest extends PHPUnit_Framework_TestCase
+{
+ /** @covers CoveredClass::publicMethod */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageMethodParenthesesTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageMethodParenthesesTest.php
new file mode 100644
index 0000000..4223004
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoverageMethodParenthesesTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoverageMethodParenthesesTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::publicMethod()
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageMethodParenthesesWhitespaceTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageMethodParenthesesWhitespaceTest.php
new file mode 100644
index 0000000..d1be1c6
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoverageMethodParenthesesWhitespaceTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoverageMethodParenthesesWhitespaceTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::publicMethod ( )
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageMethodTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageMethodTest.php
new file mode 100644
index 0000000..167b3db
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoverageMethodTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoverageMethodTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::publicMethod
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageNamespacedFunctionTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageNamespacedFunctionTest.php
new file mode 100644
index 0000000..9fc056f
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoverageNamespacedFunctionTest.php
@@ -0,0 +1,11 @@
+<?php
+class CoverageNamespacedFunctionTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers foo\func()
+ */
+ public function testFunc()
+ {
+ foo\func();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageNoneTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageNoneTest.php
new file mode 100644
index 0000000..0b414c2
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoverageNoneTest.php
@@ -0,0 +1,9 @@
+<?php
+class CoverageNoneTest extends PHPUnit_Framework_TestCase
+{
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageNotPrivateTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageNotPrivateTest.php
new file mode 100644
index 0000000..12b56e8
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoverageNotPrivateTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoverageNotPrivateTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::<!private>
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageNotProtectedTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageNotProtectedTest.php
new file mode 100644
index 0000000..c69d261
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoverageNotProtectedTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoverageNotProtectedTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::<!protected>
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageNotPublicTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageNotPublicTest.php
new file mode 100644
index 0000000..aebfe4b
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoverageNotPublicTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoverageNotPublicTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::<!public>
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageNothingTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageNothingTest.php
new file mode 100644
index 0000000..5d5680d
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoverageNothingTest.php
@@ -0,0 +1,13 @@
+<?php
+class CoverageNothingTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::publicMethod
+ * @coversNothing
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoveragePrivateTest.php b/vendor/phpunit/phpunit/tests/_files/CoveragePrivateTest.php
new file mode 100644
index 0000000..f09560d
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoveragePrivateTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoveragePrivateTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::<private>
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageProtectedTest.php b/vendor/phpunit/phpunit/tests/_files/CoverageProtectedTest.php
new file mode 100644
index 0000000..9b3acbf
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoverageProtectedTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoverageProtectedTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::<protected>
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoveragePublicTest.php b/vendor/phpunit/phpunit/tests/_files/CoveragePublicTest.php
new file mode 100644
index 0000000..480a522
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoveragePublicTest.php
@@ -0,0 +1,12 @@
+<?php
+class CoveragePublicTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers CoveredClass::<public>
+ */
+ public function testSomething()
+ {
+ $o = new CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoverageTwoDefaultClassAnnotations.php b/vendor/phpunit/phpunit/tests/_files/CoverageTwoDefaultClassAnnotations.php
new file mode 100644
index 0000000..1011769
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoverageTwoDefaultClassAnnotations.php
@@ -0,0 +1,17 @@
+<?php
+
+/**
+ * @coversDefaultClass \NamespaceOne
+ * @coversDefaultClass \AnotherDefault\Name\Space\Does\Not\Work
+ */
+class CoverageTwoDefaultClassAnnotations
+{
+ /**
+ * @covers Foo\CoveredClass::<public>
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoveredClass.php b/vendor/phpunit/phpunit/tests/_files/CoveredClass.php
new file mode 100644
index 0000000..f382ce9
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoveredClass.php
@@ -0,0 +1,36 @@
+<?php
+class CoveredParentClass
+{
+ private function privateMethod()
+ {
+ }
+
+ protected function protectedMethod()
+ {
+ $this->privateMethod();
+ }
+
+ public function publicMethod()
+ {
+ $this->protectedMethod();
+ }
+}
+
+class CoveredClass extends CoveredParentClass
+{
+ private function privateMethod()
+ {
+ }
+
+ protected function protectedMethod()
+ {
+ parent::protectedMethod();
+ $this->privateMethod();
+ }
+
+ public function publicMethod()
+ {
+ parent::publicMethod();
+ $this->protectedMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CoveredFunction.php b/vendor/phpunit/phpunit/tests/_files/CoveredFunction.php
new file mode 100644
index 0000000..9989eb0
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CoveredFunction.php
@@ -0,0 +1,4 @@
+<?php
+function globalFunction()
+{
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/CustomPrinter.php b/vendor/phpunit/phpunit/tests/_files/CustomPrinter.php
new file mode 100644
index 0000000..0e5ddc3
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/CustomPrinter.php
@@ -0,0 +1,4 @@
+<?php
+class CustomPrinter extends PHPUnit_TextUI_ResultPrinter
+{
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/DataProviderDebugTest.php b/vendor/phpunit/phpunit/tests/_files/DataProviderDebugTest.php
new file mode 100644
index 0000000..53f7a97
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/DataProviderDebugTest.php
@@ -0,0 +1,48 @@
+<?php
+class DataProviderDebugTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider provider
+ */
+ public function testProvider()
+ {
+ $this->assertTrue(true);
+ }
+
+ public static function provider()
+ {
+ $obj2 = new \stdClass();
+ $obj2->foo = 'bar';
+
+ $obj3 = (object) [1,2,"Test\r\n",4,5,6,7,8];
+
+ $obj = new \stdClass();
+ //@codingStandardsIgnoreStart
+ $obj->null = null;
+ //@codingStandardsIgnoreEnd
+ $obj->boolean = true;
+ $obj->integer = 1;
+ $obj->double = 1.2;
+ $obj->string = '1';
+ $obj->text = "this\nis\na\nvery\nvery\nvery\nvery\nvery\nvery\rlong\n\rtext";
+ $obj->object = $obj2;
+ $obj->objectagain = $obj2;
+ $obj->array = ['foo' => 'bar'];
+ $obj->self = $obj;
+
+ $storage = new \SplObjectStorage();
+ $storage->attach($obj2);
+ $storage->foo = $obj2;
+
+ return [
+ [null, true, 1, 1.0],
+ [1.2, fopen('php://memory', 'r'), '1'],
+ [[[1,2,3], [3,4,5]]],
+ // \n\r and \r is converted to \n
+ ["this\nis\na\nvery\nvery\nvery\nvery\nvery\nvery\rlong\n\rtext"],
+ [new \stdClass(), $obj, [], $storage, $obj3],
+ [chr(0) . chr(1) . chr(2) . chr(3) . chr(4) . chr(5), implode('', array_map('chr', range(0x0e, 0x1f)))],
+ [chr(0x00) . chr(0x09)]
+ ];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/DataProviderDependencyTest.php b/vendor/phpunit/phpunit/tests/_files/DataProviderDependencyTest.php
new file mode 100644
index 0000000..70d8039
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/DataProviderDependencyTest.php
@@ -0,0 +1,25 @@
+<?php
+
+class DataProviderDependencyTest extends PHPUnit_Framework_TestCase
+{
+ public function testReference()
+ {
+ $this->markTestSkipped('This test should be skipped.');
+ $this->assertTrue(true);
+ }
+
+ /**
+ * @see https://github.com/sebastianbergmann/phpunit/issues/1896
+ * @depends testReference
+ * @dataProvider provider
+ */
+ public function testDependency($param)
+ {
+ }
+
+ public function provider()
+ {
+ $this->markTestSkipped('Any test with this data provider should be skipped.');
+ return [];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/DataProviderFilterTest.php b/vendor/phpunit/phpunit/tests/_files/DataProviderFilterTest.php
new file mode 100644
index 0000000..da5801d
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/DataProviderFilterTest.php
@@ -0,0 +1,39 @@
+<?php
+class DataProviderFilterTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider truthProvider
+ */
+ public function testTrue($truth)
+ {
+ $this->assertTrue($truth);
+ }
+
+ public static function truthProvider()
+ {
+ return [
+ [true],
+ [true],
+ [true],
+ [true]
+ ];
+ }
+
+ /**
+ * @dataProvider falseProvider
+ */
+ public function testFalse($false)
+ {
+ $this->assertFalse($false);
+ }
+
+ public static function falseProvider()
+ {
+ return [
+ 'false test' => [false],
+ 'false test 2' => [false],
+ 'other false test' => [false],
+ 'other false test2'=> [false]
+ ];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/DataProviderIncompleteTest.php b/vendor/phpunit/phpunit/tests/_files/DataProviderIncompleteTest.php
new file mode 100644
index 0000000..1570ab2
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/DataProviderIncompleteTest.php
@@ -0,0 +1,37 @@
+<?php
+class DataProviderIncompleteTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider incompleteTestProviderMethod
+ */
+ public function testIncomplete($a, $b, $c)
+ {
+ $this->assertTrue(true);
+ }
+
+ /**
+ * @dataProvider providerMethod
+ */
+ public function testAdd($a, $b, $c)
+ {
+ $this->assertEquals($c, $a + $b);
+ }
+
+ public function incompleteTestProviderMethod()
+ {
+ $this->markTestIncomplete('incomplete');
+
+ return [
+ [0, 0, 0],
+ [0, 1, 1],
+ ];
+ }
+
+ public static function providerMethod()
+ {
+ return [
+ [0, 0, 0],
+ [0, 1, 1],
+ ];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/DataProviderIssue2833/FirstTest.php b/vendor/phpunit/phpunit/tests/_files/DataProviderIssue2833/FirstTest.php
new file mode 100644
index 0000000..741aabf
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/DataProviderIssue2833/FirstTest.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Foo\DataProviderIssue2833;
+
+use PHPUnit\Framework\TestCase;
+
+class FirstTest extends TestCase
+{
+ /**
+ * @dataProvider provide
+ */
+ public function testFirst($x)
+ {
+ $this->assertTrue(true);
+ }
+
+ public function provide()
+ {
+ SecondTest::DUMMY;
+
+ return [[true]];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/DataProviderIssue2833/SecondTest.php b/vendor/phpunit/phpunit/tests/_files/DataProviderIssue2833/SecondTest.php
new file mode 100644
index 0000000..86adb28
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/DataProviderIssue2833/SecondTest.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace Foo\DataProviderIssue2833;
+
+use PHPUnit\Framework\TestCase;
+
+class SecondTest extends TestCase
+{
+ const DUMMY = 'dummy';
+
+ public function testSecond()
+ {
+ $this->assertTrue(true);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/DataProviderIssue2859/phpunit.xml b/vendor/phpunit/phpunit/tests/_files/DataProviderIssue2859/phpunit.xml
new file mode 100644
index 0000000..1e47e51
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/DataProviderIssue2859/phpunit.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit>
+ <testsuites>
+ <testsuite name="Test Suite">
+ <directory>./tests/</directory>
+ <directory>./tests/*/</directory>
+ </testsuite>
+ </testsuites>
+</phpunit>
diff --git a/vendor/phpunit/phpunit/tests/_files/DataProviderIssue2859/tests/another/TestWithDataProviderTest.php b/vendor/phpunit/phpunit/tests/_files/DataProviderIssue2859/tests/another/TestWithDataProviderTest.php
new file mode 100644
index 0000000..4bffb49
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/DataProviderIssue2859/tests/another/TestWithDataProviderTest.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Foo\DataProviderIssue2859;
+
+use PHPUnit\Framework\TestCase;
+
+class TestWithDataProviderTest extends TestCase
+{
+ /**
+ * @dataProvider provide
+ */
+ public function testFirst($x)
+ {
+ $this->assertTrue(true);
+ }
+
+ public function provide()
+ {
+ return [[true]];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/DataProviderIssue2922/FirstTest.php b/vendor/phpunit/phpunit/tests/_files/DataProviderIssue2922/FirstTest.php
new file mode 100644
index 0000000..8b3302c
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/DataProviderIssue2922/FirstTest.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Foo\DataProviderIssue2922;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @group foo
+ */
+class FirstTest extends TestCase
+{
+ /**
+ * @dataProvider provide
+ */
+ public function testFirst($x)
+ {
+ $this->assertTrue(true);
+ }
+
+ public function provide()
+ {
+ throw new \Exception();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/DataProviderIssue2922/SecondTest.php b/vendor/phpunit/phpunit/tests/_files/DataProviderIssue2922/SecondTest.php
new file mode 100644
index 0000000..570ae56
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/DataProviderIssue2922/SecondTest.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Foo\DataProviderIssue2922;
+
+use PHPUnit\Framework\TestCase;
+
+// the name of the class cannot match file name - if they match all is fine
+class SecondHelloWorldTest extends TestCase
+{
+ public function testSecond()
+ {
+ $this->assertTrue(true);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/DataProviderSkippedTest.php b/vendor/phpunit/phpunit/tests/_files/DataProviderSkippedTest.php
new file mode 100644
index 0000000..d85402b
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/DataProviderSkippedTest.php
@@ -0,0 +1,37 @@
+<?php
+class DataProviderSkippedTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider skippedTestProviderMethod
+ */
+ public function testSkipped($a, $b, $c)
+ {
+ $this->assertTrue(true);
+ }
+
+ /**
+ * @dataProvider providerMethod
+ */
+ public function testAdd($a, $b, $c)
+ {
+ $this->assertEquals($c, $a + $b);
+ }
+
+ public function skippedTestProviderMethod()
+ {
+ $this->markTestSkipped('skipped');
+
+ return [
+ [0, 0, 0],
+ [0, 1, 1],
+ ];
+ }
+
+ public static function providerMethod()
+ {
+ return [
+ [0, 0, 0],
+ [0, 1, 1],
+ ];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/DataProviderTest.php b/vendor/phpunit/phpunit/tests/_files/DataProviderTest.php
new file mode 100644
index 0000000..0546ad4
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/DataProviderTest.php
@@ -0,0 +1,21 @@
+<?php
+class DataProviderTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider providerMethod
+ */
+ public function testAdd($a, $b, $c)
+ {
+ $this->assertEquals($c, $a + $b);
+ }
+
+ public static function providerMethod()
+ {
+ return [
+ [0, 0, 0],
+ [0, 1, 1],
+ [1, 1, 3],
+ [1, 0, 1]
+ ];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/DataProviderTestDoxTest.php b/vendor/phpunit/phpunit/tests/_files/DataProviderTestDoxTest.php
new file mode 100644
index 0000000..e64fbbb
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/DataProviderTestDoxTest.php
@@ -0,0 +1,26 @@
+<?php
+class DataProviderTestDoxTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider provider
+ * @testdox Does something with
+ */
+ public function testOne()
+ {
+ }
+
+ /**
+ * @dataProvider provider
+ */
+ public function testDoesSomethingElseWith()
+ {
+ }
+
+ public function provider()
+ {
+ return [
+ 'one' => [1],
+ 'two' => [2]
+ ];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/DependencyFailureTest.php b/vendor/phpunit/phpunit/tests/_files/DependencyFailureTest.php
new file mode 100644
index 0000000..43cbd8f
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/DependencyFailureTest.php
@@ -0,0 +1,29 @@
+<?php
+class DependencyFailureTest extends PHPUnit_Framework_TestCase
+{
+ public function testOne()
+ {
+ $this->fail();
+ }
+
+ /**
+ * @depends testOne
+ */
+ public function testTwo()
+ {
+ }
+
+ /**
+ * @depends !clone testTwo
+ */
+ public function testThree()
+ {
+ }
+
+ /**
+ * @depends clone testOne
+ */
+ public function testFour()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/DependencySuccessTest.php b/vendor/phpunit/phpunit/tests/_files/DependencySuccessTest.php
new file mode 100644
index 0000000..0e4b5dd
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/DependencySuccessTest.php
@@ -0,0 +1,21 @@
+<?php
+class DependencySuccessTest extends PHPUnit_Framework_TestCase
+{
+ public function testOne()
+ {
+ }
+
+ /**
+ * @depends testOne
+ */
+ public function testTwo()
+ {
+ }
+
+ /**
+ * @depends DependencySuccessTest::testTwo
+ */
+ public function testThree()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/DependencyTestSuite.php b/vendor/phpunit/phpunit/tests/_files/DependencyTestSuite.php
new file mode 100644
index 0000000..b5babc7
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/DependencyTestSuite.php
@@ -0,0 +1,13 @@
+<?php
+class DependencyTestSuite
+{
+ public static function suite()
+ {
+ $suite = new PHPUnit_Framework_TestSuite('Test Dependencies');
+
+ $suite->addTestSuite('DependencySuccessTest');
+ $suite->addTestSuite('DependencyFailureTest');
+
+ return $suite;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/DoubleTestCase.php b/vendor/phpunit/phpunit/tests/_files/DoubleTestCase.php
new file mode 100644
index 0000000..b1f00a8
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/DoubleTestCase.php
@@ -0,0 +1,25 @@
+<?php
+class DoubleTestCase implements PHPUnit_Framework_Test
+{
+ protected $testCase;
+
+ public function __construct(PHPUnit_Framework_TestCase $testCase)
+ {
+ $this->testCase = $testCase;
+ }
+
+ public function count()
+ {
+ return 2;
+ }
+
+ public function run(PHPUnit_Framework_TestResult $result = null)
+ {
+ $result->startTest($this);
+
+ $this->testCase->runBare();
+ $this->testCase->runBare();
+
+ $result->endTest($this, 0);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/DummyException.php b/vendor/phpunit/phpunit/tests/_files/DummyException.php
new file mode 100644
index 0000000..29a69b9
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/DummyException.php
@@ -0,0 +1,5 @@
+<?php
+
+class DummyException extends Exception
+{
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/EmptyTestCaseTest.php b/vendor/phpunit/phpunit/tests/_files/EmptyTestCaseTest.php
new file mode 100644
index 0000000..2a77bb2
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/EmptyTestCaseTest.php
@@ -0,0 +1,4 @@
+<?php
+class EmptyTestCaseTest extends PHPUnit_Framework_TestCase
+{
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/ExceptionInAssertPostConditionsTest.php b/vendor/phpunit/phpunit/tests/_files/ExceptionInAssertPostConditionsTest.php
new file mode 100644
index 0000000..b86927e
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/ExceptionInAssertPostConditionsTest.php
@@ -0,0 +1,35 @@
+<?php
+class ExceptionInAssertPostConditionsTest extends PHPUnit_Framework_TestCase
+{
+ public $setUp = false;
+ public $assertPreConditions = false;
+ public $assertPostConditions = false;
+ public $tearDown = false;
+ public $testSomething = false;
+
+ protected function setUp()
+ {
+ $this->setUp = true;
+ }
+
+ protected function assertPreConditions()
+ {
+ $this->assertPreConditions = true;
+ }
+
+ public function testSomething()
+ {
+ $this->testSomething = true;
+ }
+
+ protected function assertPostConditions()
+ {
+ $this->assertPostConditions = true;
+ throw new Exception;
+ }
+
+ protected function tearDown()
+ {
+ $this->tearDown = true;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/ExceptionInAssertPreConditionsTest.php b/vendor/phpunit/phpunit/tests/_files/ExceptionInAssertPreConditionsTest.php
new file mode 100644
index 0000000..a375d05
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/ExceptionInAssertPreConditionsTest.php
@@ -0,0 +1,35 @@
+<?php
+class ExceptionInAssertPreConditionsTest extends PHPUnit_Framework_TestCase
+{
+ public $setUp = false;
+ public $assertPreConditions = false;
+ public $assertPostConditions = false;
+ public $tearDown = false;
+ public $testSomething = false;
+
+ protected function setUp()
+ {
+ $this->setUp = true;
+ }
+
+ protected function assertPreConditions()
+ {
+ $this->assertPreConditions = true;
+ throw new Exception;
+ }
+
+ public function testSomething()
+ {
+ $this->testSomething = true;
+ }
+
+ protected function assertPostConditions()
+ {
+ $this->assertPostConditions = true;
+ }
+
+ protected function tearDown()
+ {
+ $this->tearDown = true;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/ExceptionInSetUpTest.php b/vendor/phpunit/phpunit/tests/_files/ExceptionInSetUpTest.php
new file mode 100644
index 0000000..193b9a8
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/ExceptionInSetUpTest.php
@@ -0,0 +1,35 @@
+<?php
+class ExceptionInSetUpTest extends PHPUnit_Framework_TestCase
+{
+ public $setUp = false;
+ public $assertPreConditions = false;
+ public $assertPostConditions = false;
+ public $tearDown = false;
+ public $testSomething = false;
+
+ protected function setUp()
+ {
+ $this->setUp = true;
+ throw new Exception;
+ }
+
+ protected function assertPreConditions()
+ {
+ $this->assertPreConditions = true;
+ }
+
+ public function testSomething()
+ {
+ $this->testSomething = true;
+ }
+
+ protected function assertPostConditions()
+ {
+ $this->assertPostConditions = true;
+ }
+
+ protected function tearDown()
+ {
+ $this->tearDown = true;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/ExceptionInTearDownTest.php b/vendor/phpunit/phpunit/tests/_files/ExceptionInTearDownTest.php
new file mode 100644
index 0000000..5ee4a9d
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/ExceptionInTearDownTest.php
@@ -0,0 +1,35 @@
+<?php
+class ExceptionInTearDownTest extends PHPUnit_Framework_TestCase
+{
+ public $setUp = false;
+ public $assertPreConditions = false;
+ public $assertPostConditions = false;
+ public $tearDown = false;
+ public $testSomething = false;
+
+ protected function setUp()
+ {
+ $this->setUp = true;
+ }
+
+ protected function assertPreConditions()
+ {
+ $this->assertPreConditions = true;
+ }
+
+ public function testSomething()
+ {
+ $this->testSomething = true;
+ }
+
+ protected function assertPostConditions()
+ {
+ $this->assertPostConditions = true;
+ }
+
+ protected function tearDown()
+ {
+ $this->tearDown = true;
+ throw new Exception;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/ExceptionInTest.php b/vendor/phpunit/phpunit/tests/_files/ExceptionInTest.php
new file mode 100644
index 0000000..32c7e24
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/ExceptionInTest.php
@@ -0,0 +1,35 @@
+<?php
+class ExceptionInTest extends PHPUnit_Framework_TestCase
+{
+ public $setUp = false;
+ public $assertPreConditions = false;
+ public $assertPostConditions = false;
+ public $tearDown = false;
+ public $testSomething = false;
+
+ protected function setUp()
+ {
+ $this->setUp = true;
+ }
+
+ protected function assertPreConditions()
+ {
+ $this->assertPreConditions = true;
+ }
+
+ public function testSomething()
+ {
+ $this->testSomething = true;
+ throw new Exception;
+ }
+
+ protected function assertPostConditions()
+ {
+ $this->assertPostConditions = true;
+ }
+
+ protected function tearDown()
+ {
+ $this->tearDown = true;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/ExceptionNamespaceTest.php b/vendor/phpunit/phpunit/tests/_files/ExceptionNamespaceTest.php
new file mode 100644
index 0000000..22f3760
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/ExceptionNamespaceTest.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace My\Space;
+
+class ExceptionNamespaceTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * Exception message
+ *
+ * @var string
+ */
+ const ERROR_MESSAGE = 'Exception namespace message';
+
+ /**
+ * Exception code
+ *
+ * @var int
+ */
+ const ERROR_CODE = 200;
+
+ /**
+ * @expectedException Class
+ * @expectedExceptionMessage My\Space\ExceptionNamespaceTest::ERROR_MESSAGE
+ * @expectedExceptionCode My\Space\ExceptionNamespaceTest::ERROR_CODE
+ */
+ public function testConstants()
+ {
+ }
+
+ /**
+ * @expectedException Class
+ * @expectedExceptionCode My\Space\ExceptionNamespaceTest::UNKNOWN_CODE_CONSTANT
+ * @expectedExceptionMessage My\Space\ExceptionNamespaceTest::UNKNOWN_MESSAGE_CONSTANT
+ */
+ public function testUnknownConstants()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/ExceptionStackTest.php b/vendor/phpunit/phpunit/tests/_files/ExceptionStackTest.php
new file mode 100644
index 0000000..256ae1c
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/ExceptionStackTest.php
@@ -0,0 +1,21 @@
+<?php
+class ExceptionStackTest extends PHPUnit_Framework_TestCase
+{
+ public function testPrintingChildException()
+ {
+ try {
+ $this->assertEquals([1], [2], 'message');
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+ $message = $e->getMessage() . $e->getComparisonFailure()->getDiff();
+ throw new PHPUnit_Framework_Exception("Child exception\n$message", 101, $e);
+ }
+ }
+
+ public function testNestedExceptions()
+ {
+ $exceptionThree = new Exception('Three');
+ $exceptionTwo = new InvalidArgumentException('Two', 0, $exceptionThree);
+ $exceptionOne = new Exception('One', 0, $exceptionTwo);
+ throw $exceptionOne;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/ExceptionTest.php b/vendor/phpunit/phpunit/tests/_files/ExceptionTest.php
new file mode 100644
index 0000000..0213805
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/ExceptionTest.php
@@ -0,0 +1,139 @@
+<?php
+class ExceptionTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * Exception message
+ *
+ * @var string
+ */
+ const ERROR_MESSAGE = 'Exception message';
+
+ /**
+ * Exception message
+ *
+ * @var string
+ */
+ const ERROR_MESSAGE_REGEX = '#regex#';
+
+ /**
+ * Exception code
+ *
+ * @var int
+ */
+ const ERROR_CODE = 500;
+
+ /**
+ * @expectedException FooBarBaz
+ */
+ public function testOne()
+ {
+ }
+
+ /**
+ * @expectedException Foo_Bar_Baz
+ */
+ public function testTwo()
+ {
+ }
+
+ /**
+ * @expectedException Foo\Bar\Baz
+ */
+ public function testThree()
+ {
+ }
+
+ /**
+ * @expectedException ほげ
+ */
+ public function testFour()
+ {
+ }
+
+ /**
+ * @expectedException Class Message 1234
+ */
+ public function testFive()
+ {
+ }
+
+ /**
+ * @expectedException Class
+ * @expectedExceptionMessage Message
+ * @expectedExceptionCode 1234
+ */
+ public function testSix()
+ {
+ }
+
+ /**
+ * @expectedException Class
+ * @expectedExceptionMessage Message
+ * @expectedExceptionCode ExceptionCode
+ */
+ public function testSeven()
+ {
+ }
+
+ /**
+ * @expectedException Class
+ * @expectedExceptionMessage Message
+ * @expectedExceptionCode 0
+ */
+ public function testEight()
+ {
+ }
+
+ /**
+ * @expectedException Class
+ * @expectedExceptionMessage ExceptionTest::ERROR_MESSAGE
+ * @expectedExceptionCode ExceptionTest::ERROR_CODE
+ */
+ public function testNine()
+ {
+ }
+
+ /** @expectedException Class */
+ public function testSingleLine()
+ {
+ }
+
+ /**
+ * @expectedException Class
+ * @expectedExceptionCode ExceptionTest::UNKNOWN_CODE_CONSTANT
+ * @expectedExceptionMessage ExceptionTest::UNKNOWN_MESSAGE_CONSTANT
+ */
+ public function testUnknownConstants()
+ {
+ }
+
+ /**
+ * @expectedException Class
+ * @expectedExceptionCode 1234
+ * @expectedExceptionMessage Message
+ * @expectedExceptionMessageRegExp #regex#
+ */
+ public function testWithRegexMessage()
+ {
+ }
+
+ /**
+ * @expectedException Class
+ * @expectedExceptionCode 1234
+ * @expectedExceptionMessage Message
+ * @expectedExceptionMessageRegExp ExceptionTest::ERROR_MESSAGE_REGEX
+ */
+ public function testWithRegexMessageFromClassConstant()
+ {
+ }
+
+ /**
+ * @expectedException Class
+ * @expectedExceptionCode 1234
+ * @expectedExceptionMessage Message
+ * @expectedExceptionMessageRegExp ExceptionTest::UNKNOWN_MESSAGE_REGEX_CONSTANT
+ */
+ public function testWithUnknowRegexMessageFromClassConstant()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/Failure.php b/vendor/phpunit/phpunit/tests/_files/Failure.php
new file mode 100644
index 0000000..586aa54
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/Failure.php
@@ -0,0 +1,8 @@
+<?php
+class Failure extends PHPUnit_Framework_TestCase
+{
+ protected function runTest()
+ {
+ $this->fail();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/FailureTest.php b/vendor/phpunit/phpunit/tests/_files/FailureTest.php
new file mode 100644
index 0000000..47134aa
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/FailureTest.php
@@ -0,0 +1,75 @@
+<?php
+class FailureTest extends PHPUnit_Framework_TestCase
+{
+ public function testAssertArrayEqualsArray()
+ {
+ $this->assertEquals([1], [2], 'message');
+ }
+
+ public function testAssertIntegerEqualsInteger()
+ {
+ $this->assertEquals(1, 2, 'message');
+ }
+
+ public function testAssertObjectEqualsObject()
+ {
+ $a = new StdClass;
+ $a->foo = 'bar';
+
+ $b = new StdClass;
+ $b->bar = 'foo';
+
+ $this->assertEquals($a, $b, 'message');
+ }
+
+ public function testAssertNullEqualsString()
+ {
+ $this->assertEquals(null, 'bar', 'message');
+ }
+
+ public function testAssertStringEqualsString()
+ {
+ $this->assertEquals('foo', 'bar', 'message');
+ }
+
+ public function testAssertTextEqualsText()
+ {
+ $this->assertEquals("foo\nbar\n", "foo\nbaz\n", 'message');
+ }
+
+ public function testAssertStringMatchesFormat()
+ {
+ $this->assertStringMatchesFormat('*%s*', '**', 'message');
+ }
+
+ public function testAssertNumericEqualsNumeric()
+ {
+ $this->assertEquals(1, 2, 'message');
+ }
+
+ public function testAssertTextSameText()
+ {
+ $this->assertSame('foo', 'bar', 'message');
+ }
+
+ public function testAssertObjectSameObject()
+ {
+ $this->assertSame(new StdClass, new StdClass, 'message');
+ }
+
+ public function testAssertObjectSameNull()
+ {
+ $this->assertSame(new StdClass, null, 'message');
+ }
+
+ public function testAssertFloatSameFloat()
+ {
+ $this->assertSame(1.0, 1.5, 'message');
+ }
+
+ // Note that due to the implementation of this assertion it counts as 2 asserts
+ public function testAssertStringMatchesFormatFile()
+ {
+ $this->assertStringMatchesFormatFile(__DIR__ . '/expectedFileFormat.txt', '...BAR...');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/FatalTest.php b/vendor/phpunit/phpunit/tests/_files/FatalTest.php
new file mode 100644
index 0000000..bf005f9
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/FatalTest.php
@@ -0,0 +1,13 @@
+<?php
+
+class FatalTest extends PHPUnit_Framework_TestCase
+{
+ public function testFatalError()
+ {
+ if (extension_loaded('xdebug')) {
+ xdebug_disable();
+ }
+
+ eval('class FatalTest {}');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/IgnoreCodeCoverageClass.php b/vendor/phpunit/phpunit/tests/_files/IgnoreCodeCoverageClass.php
new file mode 100644
index 0000000..88c8660
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/IgnoreCodeCoverageClass.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * @codeCoverageIgnore
+ */
+class IgnoreCodeCoverageClass
+{
+ public function returnTrue()
+ {
+ return true;
+ }
+
+ public function returnFalse()
+ {
+ return false;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/IgnoreCodeCoverageClassTest.php b/vendor/phpunit/phpunit/tests/_files/IgnoreCodeCoverageClassTest.php
new file mode 100644
index 0000000..a610aa3
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/IgnoreCodeCoverageClassTest.php
@@ -0,0 +1,15 @@
+<?php
+class IgnoreCodeCoverageClassTest extends PHPUnit_Framework_TestCase
+{
+ public function testReturnTrue()
+ {
+ $sut = new IgnoreCodeCoverageClass();
+ $this->assertTrue($sut->returnTrue());
+ }
+
+ public function testReturnFalse()
+ {
+ $sut = new IgnoreCodeCoverageClass();
+ $this->assertFalse($sut->returnFalse());
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/IncompleteTest.php b/vendor/phpunit/phpunit/tests/_files/IncompleteTest.php
new file mode 100644
index 0000000..36ca8a0
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/IncompleteTest.php
@@ -0,0 +1,8 @@
+<?php
+class IncompleteTest extends PHPUnit_Framework_TestCase
+{
+ public function testIncomplete()
+ {
+ $this->markTestIncomplete('Test incomplete');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/Inheritance/InheritanceA.php b/vendor/phpunit/phpunit/tests/_files/Inheritance/InheritanceA.php
new file mode 100644
index 0000000..e189b7d
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/Inheritance/InheritanceA.php
@@ -0,0 +1,7 @@
+<?php
+
+require_once(__DIR__ . '/InheritanceB.php');
+
+class InheritanceA extends InheritanceB
+{
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/Inheritance/InheritanceB.php b/vendor/phpunit/phpunit/tests/_files/Inheritance/InheritanceB.php
new file mode 100644
index 0000000..24447e2
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/Inheritance/InheritanceB.php
@@ -0,0 +1,8 @@
+<?php
+
+class InheritanceB extends PHPUnit_Framework_TestCase
+{
+ public function testSomething()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/InheritedTestCase.php b/vendor/phpunit/phpunit/tests/_files/InheritedTestCase.php
new file mode 100644
index 0000000..3df7215
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/InheritedTestCase.php
@@ -0,0 +1,7 @@
+<?php
+class InheritedTestCase extends OneTestCase
+{
+ public function test2()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/IniTest.php b/vendor/phpunit/phpunit/tests/_files/IniTest.php
new file mode 100644
index 0000000..5846abf
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/IniTest.php
@@ -0,0 +1,8 @@
+<?php
+class IniTest extends PHPUnit_Framework_TestCase
+{
+ public function testIni()
+ {
+ $this->assertEquals('application/x-test', ini_get('default_mimetype'));
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/IsolationTest.php b/vendor/phpunit/phpunit/tests/_files/IsolationTest.php
new file mode 100644
index 0000000..df95c91
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/IsolationTest.php
@@ -0,0 +1,13 @@
+<?php
+class IsolationTest extends PHPUnit_Framework_TestCase
+{
+ public function testIsInIsolationReturnsFalse()
+ {
+ $this->assertFalse($this->isInIsolation());
+ }
+
+ public function testIsInIsolationReturnsTrue()
+ {
+ $this->assertTrue($this->isInIsolation());
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/JsonData/arrayObject.json b/vendor/phpunit/phpunit/tests/_files/JsonData/arrayObject.json
new file mode 100644
index 0000000..8a74fc5
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/JsonData/arrayObject.json
@@ -0,0 +1 @@
+["Mascott", "Tux", "OS", "Linux"]
diff --git a/vendor/phpunit/phpunit/tests/_files/JsonData/simpleObject.json b/vendor/phpunit/phpunit/tests/_files/JsonData/simpleObject.json
new file mode 100644
index 0000000..27085be
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/JsonData/simpleObject.json
@@ -0,0 +1 @@
+{"Mascott":"Tux"} \ No newline at end of file
diff --git a/vendor/phpunit/phpunit/tests/_files/MockRunner.php b/vendor/phpunit/phpunit/tests/_files/MockRunner.php
new file mode 100644
index 0000000..b3bc0cc
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/MockRunner.php
@@ -0,0 +1,7 @@
+<?php
+class MockRunner extends PHPUnit_Runner_BaseTestRunner
+{
+ protected function runFailed($message)
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/Mockable.php b/vendor/phpunit/phpunit/tests/_files/Mockable.php
new file mode 100644
index 0000000..95024e9
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/Mockable.php
@@ -0,0 +1,26 @@
+<?php
+class Mockable
+{
+ public $constructorCalled = false;
+ public $cloned = false;
+
+ public function __construct()
+ {
+ $this->constructorCalled = false;
+ }
+
+ public function foo()
+ {
+ return true;
+ }
+
+ public function bar()
+ {
+ return true;
+ }
+
+ public function __clone()
+ {
+ $this->cloned = true;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/MultiDependencyTest.php b/vendor/phpunit/phpunit/tests/_files/MultiDependencyTest.php
new file mode 100644
index 0000000..886a809
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/MultiDependencyTest.php
@@ -0,0 +1,23 @@
+<?php
+class MultiDependencyTest extends PHPUnit_Framework_TestCase
+{
+ public function testOne()
+ {
+ return 'foo';
+ }
+
+ public function testTwo()
+ {
+ return 'bar';
+ }
+
+ /**
+ * @depends testOne
+ * @depends testTwo
+ */
+ public function testThree($a, $b)
+ {
+ $this->assertEquals('foo', $a);
+ $this->assertEquals('bar', $b);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/MultipleDataProviderTest.php b/vendor/phpunit/phpunit/tests/_files/MultipleDataProviderTest.php
new file mode 100644
index 0000000..126c02b
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/MultipleDataProviderTest.php
@@ -0,0 +1,75 @@
+<?php
+class MultipleDataProviderTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @dataProvider providerA
+ * @dataProvider providerB
+ * @dataProvider providerC
+ */
+ public function testOne()
+ {
+ }
+
+ /**
+ * @dataProvider providerD
+ * @dataProvider providerE
+ * @dataProvider providerF
+ */
+ public function testTwo()
+ {
+ }
+
+ public static function providerA()
+ {
+ return [
+ ['ok', null, null],
+ ['ok', null, null],
+ ['ok', null, null]
+ ];
+ }
+
+ public static function providerB()
+ {
+ return [
+ [null, 'ok', null],
+ [null, 'ok', null],
+ [null, 'ok', null]
+ ];
+ }
+
+ public static function providerC()
+ {
+ return [
+ [null, null, 'ok'],
+ [null, null, 'ok'],
+ [null, null, 'ok']
+ ];
+ }
+
+ public static function providerD()
+ {
+ yield ['ok', null, null];
+ yield ['ok', null, null];
+ yield ['ok', null, null];
+ }
+
+ public static function providerE()
+ {
+ yield [null, 'ok', null];
+ yield [null, 'ok', null];
+ yield [null, 'ok', null];
+ }
+
+ public static function providerF()
+ {
+ $object = new ArrayObject(
+ [
+ [null, null, 'ok'],
+ [null, null, 'ok'],
+ [null, null, 'ok']
+ ]
+ );
+
+ return $object->getIterator();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/MyCommand.php b/vendor/phpunit/phpunit/tests/_files/MyCommand.php
new file mode 100644
index 0000000..c0abadb
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/MyCommand.php
@@ -0,0 +1,15 @@
+<?php
+
+class MyCommand extends PHPUnit_TextUI_Command
+{
+ public function __construct()
+ {
+ $this->longOptions['my-option='] = 'myHandler';
+ $this->longOptions['my-other-option'] = null;
+ }
+
+ public function myHandler($value)
+ {
+ echo __METHOD__ . " $value\n";
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageClassExtendedTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageClassExtendedTest.php
new file mode 100644
index 0000000..d0954cb
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageClassExtendedTest.php
@@ -0,0 +1,12 @@
+<?php
+class NamespaceCoverageClassExtendedTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Foo\CoveredClass<extended>
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageClassTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageClassTest.php
new file mode 100644
index 0000000..63912c0
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageClassTest.php
@@ -0,0 +1,12 @@
+<?php
+class NamespaceCoverageClassTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Foo\CoveredClass
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageCoversClassPublicTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageCoversClassPublicTest.php
new file mode 100644
index 0000000..45f583b
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageCoversClassPublicTest.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * @coversDefaultClass \Foo\CoveredClass
+ */
+class NamespaceCoverageCoversClassPublicTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers ::publicMethod
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageCoversClassTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageCoversClassTest.php
new file mode 100644
index 0000000..b336745
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageCoversClassTest.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * @coversDefaultClass \Foo\CoveredClass
+ */
+class NamespaceCoverageCoversClassTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers ::privateMethod
+ * @covers ::protectedMethod
+ * @covers ::publicMethod
+ * @covers \Foo\CoveredParentClass::privateMethod
+ * @covers \Foo\CoveredParentClass::protectedMethod
+ * @covers \Foo\CoveredParentClass::publicMethod
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageMethodTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageMethodTest.php
new file mode 100644
index 0000000..35dfb8b
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageMethodTest.php
@@ -0,0 +1,12 @@
+<?php
+class NamespaceCoverageMethodTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Foo\CoveredClass::publicMethod
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotPrivateTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotPrivateTest.php
new file mode 100644
index 0000000..552c9ec
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotPrivateTest.php
@@ -0,0 +1,12 @@
+<?php
+class NamespaceCoverageNotPrivateTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Foo\CoveredClass::<!private>
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotProtectedTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotProtectedTest.php
new file mode 100644
index 0000000..33fc8c7
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotProtectedTest.php
@@ -0,0 +1,12 @@
+<?php
+class NamespaceCoverageNotProtectedTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Foo\CoveredClass::<!protected>
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotPublicTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotPublicTest.php
new file mode 100644
index 0000000..ccbc500
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageNotPublicTest.php
@@ -0,0 +1,12 @@
+<?php
+class NamespaceCoverageNotPublicTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Foo\CoveredClass::<!public>
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoveragePrivateTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoveragePrivateTest.php
new file mode 100644
index 0000000..cce7ba9
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoveragePrivateTest.php
@@ -0,0 +1,12 @@
+<?php
+class NamespaceCoveragePrivateTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Foo\CoveredClass::<private>
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageProtectedTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageProtectedTest.php
new file mode 100644
index 0000000..dbbcc1c
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoverageProtectedTest.php
@@ -0,0 +1,12 @@
+<?php
+class NamespaceCoverageProtectedTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Foo\CoveredClass::<protected>
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoveragePublicTest.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoveragePublicTest.php
new file mode 100644
index 0000000..bf1bff8
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoveragePublicTest.php
@@ -0,0 +1,12 @@
+<?php
+class NamespaceCoveragePublicTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers Foo\CoveredClass::<public>
+ */
+ public function testSomething()
+ {
+ $o = new Foo\CoveredClass;
+ $o->publicMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoveredClass.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoveredClass.php
new file mode 100644
index 0000000..5bd0ddf
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoveredClass.php
@@ -0,0 +1,38 @@
+<?php
+namespace Foo;
+
+class CoveredParentClass
+{
+ private function privateMethod()
+ {
+ }
+
+ protected function protectedMethod()
+ {
+ $this->privateMethod();
+ }
+
+ public function publicMethod()
+ {
+ $this->protectedMethod();
+ }
+}
+
+class CoveredClass extends CoveredParentClass
+{
+ private function privateMethod()
+ {
+ }
+
+ protected function protectedMethod()
+ {
+ parent::protectedMethod();
+ $this->privateMethod();
+ }
+
+ public function publicMethod()
+ {
+ parent::publicMethod();
+ $this->protectedMethod();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NamespaceCoveredFunction.php b/vendor/phpunit/phpunit/tests/_files/NamespaceCoveredFunction.php
new file mode 100644
index 0000000..afc00d7
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NamespaceCoveredFunction.php
@@ -0,0 +1,7 @@
+<?php
+namespace foo;
+
+function func()
+{
+ return true;
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NoArgTestCaseTest.php b/vendor/phpunit/phpunit/tests/_files/NoArgTestCaseTest.php
new file mode 100644
index 0000000..5867ba3
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NoArgTestCaseTest.php
@@ -0,0 +1,7 @@
+<?php
+class NoArgTestCaseTest extends PHPUnit_Framework_TestCase
+{
+ public function testNothing()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NoTestCaseClass.php b/vendor/phpunit/phpunit/tests/_files/NoTestCaseClass.php
new file mode 100644
index 0000000..d64e4e1
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NoTestCaseClass.php
@@ -0,0 +1,4 @@
+<?php
+class NoTestCaseClass
+{
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NoTestCases.php b/vendor/phpunit/phpunit/tests/_files/NoTestCases.php
new file mode 100644
index 0000000..ae93233
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NoTestCases.php
@@ -0,0 +1,7 @@
+<?php
+class NoTestCases extends PHPUnit_Framework_TestCase
+{
+ public function noTestCase()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NonStatic.php b/vendor/phpunit/phpunit/tests/_files/NonStatic.php
new file mode 100644
index 0000000..48bad9a
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NonStatic.php
@@ -0,0 +1,8 @@
+<?php
+class NonStatic
+{
+ public function suite()
+ {
+ return;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NotExistingCoveredElementTest.php b/vendor/phpunit/phpunit/tests/_files/NotExistingCoveredElementTest.php
new file mode 100644
index 0000000..be07ef4
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NotExistingCoveredElementTest.php
@@ -0,0 +1,24 @@
+<?php
+class NotExistingCoveredElementTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @covers NotExistingClass
+ */
+ public function testOne()
+ {
+ }
+
+ /**
+ * @covers NotExistingClass::notExistingMethod
+ */
+ public function testTwo()
+ {
+ }
+
+ /**
+ * @covers NotExistingClass::<public>
+ */
+ public function testThree()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NotPublicTestCase.php b/vendor/phpunit/phpunit/tests/_files/NotPublicTestCase.php
new file mode 100644
index 0000000..a391010
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NotPublicTestCase.php
@@ -0,0 +1,11 @@
+<?php
+class NotPublicTestCase extends PHPUnit_Framework_TestCase
+{
+ public function testPublic()
+ {
+ }
+
+ protected function testNotPublic()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NotVoidTestCase.php b/vendor/phpunit/phpunit/tests/_files/NotVoidTestCase.php
new file mode 100644
index 0000000..19a9567
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NotVoidTestCase.php
@@ -0,0 +1,4 @@
+<?php
+class NotVoidTestCase extends PHPUnit_Framework_TestCase
+{
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/NothingTest.php b/vendor/phpunit/phpunit/tests/_files/NothingTest.php
new file mode 100644
index 0000000..b56d7d7
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/NothingTest.php
@@ -0,0 +1,7 @@
+<?php
+class NothingTest extends PHPUnit_Framework_TestCase
+{
+ public function testNothing()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/OneTestCase.php b/vendor/phpunit/phpunit/tests/_files/OneTestCase.php
new file mode 100644
index 0000000..15eeed9
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/OneTestCase.php
@@ -0,0 +1,11 @@
+<?php
+class OneTestCase extends PHPUnit_Framework_TestCase
+{
+ public function noTestCase()
+ {
+ }
+
+ public function testCase($arg = '')
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/OutputTestCase.php b/vendor/phpunit/phpunit/tests/_files/OutputTestCase.php
new file mode 100644
index 0000000..ae972b5
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/OutputTestCase.php
@@ -0,0 +1,27 @@
+<?php
+class OutputTestCase extends PHPUnit_Framework_TestCase
+{
+ public function testExpectOutputStringFooActualFoo()
+ {
+ $this->expectOutputString('foo');
+ print 'foo';
+ }
+
+ public function testExpectOutputStringFooActualBar()
+ {
+ $this->expectOutputString('foo');
+ print 'bar';
+ }
+
+ public function testExpectOutputRegexFooActualFoo()
+ {
+ $this->expectOutputRegex('/foo/');
+ print 'foo';
+ }
+
+ public function testExpectOutputRegexFooActualBar()
+ {
+ $this->expectOutputRegex('/foo/');
+ print 'bar';
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/OverrideTestCase.php b/vendor/phpunit/phpunit/tests/_files/OverrideTestCase.php
new file mode 100644
index 0000000..fcc276c
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/OverrideTestCase.php
@@ -0,0 +1,7 @@
+<?php
+class OverrideTestCase extends OneTestCase
+{
+ public function testCase($arg = '')
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/RequirementsClassBeforeClassHookTest.php b/vendor/phpunit/phpunit/tests/_files/RequirementsClassBeforeClassHookTest.php
new file mode 100644
index 0000000..002781f
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/RequirementsClassBeforeClassHookTest.php
@@ -0,0 +1,12 @@
+<?php
+
+/**
+ * @requires extension nonExistingExtension
+ */
+class RequirementsClassBeforeClassHookTest extends PHPUnit_Framework_TestCase
+{
+ public static function setUpBeforeClass()
+ {
+ throw new Exception(__METHOD__ . ' should not be called because of class requirements.');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/RequirementsClassDocBlockTest.php b/vendor/phpunit/phpunit/tests/_files/RequirementsClassDocBlockTest.php
new file mode 100644
index 0000000..c420afb
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/RequirementsClassDocBlockTest.php
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * @requires PHP 5.3
+ * @requires PHPUnit 4.0
+ * @requires OS Linux
+ * @requires function testFuncClass
+ * @requires extension testExtClass
+ */
+class RequirementsClassDocBlockTest
+{
+ /**
+ * @requires PHP 5.4
+ * @requires PHPUnit 3.7
+ * @requires OS WINNT
+ * @requires function testFuncMethod
+ * @requires extension testExtMethod
+ */
+ public function testMethod()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/RequirementsTest.php b/vendor/phpunit/phpunit/tests/_files/RequirementsTest.php
new file mode 100644
index 0000000..85902fa
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/RequirementsTest.php
@@ -0,0 +1,345 @@
+<?php
+class RequirementsTest extends PHPUnit_Framework_TestCase
+{
+ public function testOne()
+ {
+ }
+
+ /**
+ * @requires PHPUnit 1.0
+ */
+ public function testTwo()
+ {
+ }
+
+ /**
+ * @requires PHP 2.0
+ */
+ public function testThree()
+ {
+ }
+
+ /**
+ * @requires PHPUnit 2.0
+ * @requires PHP 1.0
+ */
+ public function testFour()
+ {
+ }
+
+ /**
+ * @requires PHP 5.4.0RC6
+ */
+ public function testFive()
+ {
+ }
+
+ /**
+ * @requires PHP 5.4.0-alpha1
+ */
+ public function testSix()
+ {
+ }
+
+ /**
+ * @requires PHP 5.4.0beta2
+ */
+ public function testSeven()
+ {
+ }
+
+ /**
+ * @requires PHP 5.4-dev
+ */
+ public function testEight()
+ {
+ }
+
+ /**
+ * @requires function testFunc
+ */
+ public function testNine()
+ {
+ }
+
+ /**
+ * @requires extension testExt
+ */
+ public function testTen()
+ {
+ }
+
+ /**
+ * @requires OS Linux
+ */
+ public function testEleven()
+ {
+ }
+
+ /**
+ * @requires PHP 99-dev
+ * @requires PHPUnit 9-dev
+ * @requires OS DOESNOTEXIST
+ * @requires function testFuncOne
+ * @requires function testFuncTwo
+ * @requires extension testExtOne
+ * @requires extension testExtTwo
+ * @requires extension testExtThree 2.0
+ */
+ public function testAllPossibleRequirements()
+ {
+ }
+
+ /**
+ * @requires function array_merge
+ */
+ public function testExistingFunction()
+ {
+ }
+
+ /**
+ * @requires function ReflectionMethod::setAccessible
+ */
+ public function testExistingMethod()
+ {
+ }
+
+ /**
+ * @requires extension spl
+ */
+ public function testExistingExtension()
+ {
+ }
+
+ /**
+ * @requires OS .*
+ */
+ public function testExistingOs()
+ {
+ }
+
+ /**
+ * @requires PHPUnit 1111111
+ */
+ public function testAlwaysSkip()
+ {
+ }
+
+ /**
+ * @requires PHP 9999999
+ */
+ public function testAlwaysSkip2()
+ {
+ }
+
+ /**
+ * @requires OS DOESNOTEXIST
+ */
+ public function testAlwaysSkip3()
+ {
+ }
+
+ /**
+ * @requires extension spl
+ * @requires OS .*
+ */
+ public function testSpace()
+ {
+ }
+
+ /**
+ * @requires extension testExt 1.8.0
+ */
+ public function testSpecificExtensionVersion()
+ {
+ }
+
+ /**
+ * @requires PHP < 5.4
+ */
+ public function testPHPVersionOperatorLessThan()
+ {
+ }
+
+ /**
+ * @requires PHP <= 5.4
+ */
+ public function testPHPVersionOperatorLessThanEquals()
+ {
+ }
+
+ /**
+ * @requires PHP > 99
+ */
+ public function testPHPVersionOperatorGreaterThan()
+ {
+ }
+
+ /**
+ * @requires PHP >= 99
+ */
+ public function testPHPVersionOperatorGreaterThanEquals()
+ {
+ }
+
+ /**
+ * @requires PHP = 5.4
+ */
+ public function testPHPVersionOperatorEquals()
+ {
+ }
+
+ /**
+ * @requires PHP == 5.4
+ */
+ public function testPHPVersionOperatorDoubleEquals()
+ {
+ }
+
+ /**
+ * @requires PHP != 99
+ */
+ public function testPHPVersionOperatorBangEquals()
+ {
+ }
+
+ /**
+ * @requires PHP <> 99
+ */
+ public function testPHPVersionOperatorNotEquals()
+ {
+ }
+
+ /**
+ * @requires PHP >=99
+ */
+ public function testPHPVersionOperatorNoSpace()
+ {
+ }
+
+ /**
+ * @requires PHPUnit < 1.0
+ */
+ public function testPHPUnitVersionOperatorLessThan()
+ {
+ }
+
+ /**
+ * @requires PHPUnit <= 1.0
+ */
+ public function testPHPUnitVersionOperatorLessThanEquals()
+ {
+ }
+
+ /**
+ * @requires PHPUnit > 99
+ */
+ public function testPHPUnitVersionOperatorGreaterThan()
+ {
+ }
+
+ /**
+ * @requires PHPUnit >= 99
+ */
+ public function testPHPUnitVersionOperatorGreaterThanEquals()
+ {
+ }
+
+ /**
+ * @requires PHPUnit = 1.0
+ */
+ public function testPHPUnitVersionOperatorEquals()
+ {
+ }
+
+ /**
+ * @requires PHPUnit == 1.0
+ */
+ public function testPHPUnitVersionOperatorDoubleEquals()
+ {
+ }
+
+ /**
+ * @requires PHPUnit != 99
+ */
+ public function testPHPUnitVersionOperatorBangEquals()
+ {
+ }
+
+ /**
+ * @requires PHPUnit <> 99
+ */
+ public function testPHPUnitVersionOperatorNotEquals()
+ {
+ }
+
+ /**
+ * @requires PHPUnit >=99
+ */
+ public function testPHPUnitVersionOperatorNoSpace()
+ {
+ }
+
+ /**
+ * @requires extension testExtOne < 1.0
+ */
+ public function testExtensionVersionOperatorLessThan()
+ {
+ }
+
+ /**
+ * @requires extension testExtOne <= 1.0
+ */
+ public function testExtensionVersionOperatorLessThanEquals()
+ {
+ }
+
+ /**
+ * @requires extension testExtOne > 99
+ */
+ public function testExtensionVersionOperatorGreaterThan()
+ {
+ }
+
+ /**
+ * @requires extension testExtOne >= 99
+ */
+ public function testExtensionVersionOperatorGreaterThanEquals()
+ {
+ }
+
+ /**
+ * @requires extension testExtOne = 1.0
+ */
+ public function testExtensionVersionOperatorEquals()
+ {
+ }
+
+ /**
+ * @requires extension testExtOne == 1.0
+ */
+ public function testExtensionVersionOperatorDoubleEquals()
+ {
+ }
+
+ /**
+ * @requires extension testExtOne != 99
+ */
+ public function testExtensionVersionOperatorBangEquals()
+ {
+ }
+
+ /**
+ * @requires extension testExtOne <> 99
+ */
+ public function testExtensionVersionOperatorNotEquals()
+ {
+ }
+
+ /**
+ * @requires extension testExtOne >=99
+ */
+ public function testExtensionVersionOperatorNoSpace()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/SampleArrayAccess.php b/vendor/phpunit/phpunit/tests/_files/SampleArrayAccess.php
new file mode 100644
index 0000000..7b68729
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/SampleArrayAccess.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Sample class that implements ArrayAccess copied from
+ * http://www.php.net/manual/en/class.arrayaccess.php
+ * with some minor changes
+ * This class required for PHPUnit_Framework_Constraint_ArrayHasKey testing
+ */
+class SampleArrayAccess implements ArrayAccess
+{
+ private $container;
+
+ public function __construct()
+ {
+ $this->container = [];
+ }
+ public function offsetSet($offset, $value)
+ {
+ if (is_null($offset)) {
+ $this->container[] = $value;
+ } else {
+ $this->container[$offset] = $value;
+ }
+ }
+ public function offsetExists($offset)
+ {
+ return isset($this->container[$offset]);
+ }
+ public function offsetUnset($offset)
+ {
+ unset($this->container[$offset]);
+ }
+ public function offsetGet($offset)
+ {
+ return isset($this->container[$offset]) ? $this->container[$offset] : null;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/SampleClass.php b/vendor/phpunit/phpunit/tests/_files/SampleClass.php
new file mode 100644
index 0000000..06c51c5
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/SampleClass.php
@@ -0,0 +1,14 @@
+<?php
+class SampleClass
+{
+ public $a;
+ protected $b;
+ protected $c;
+
+ public function __construct($a, $b, $c)
+ {
+ $this->a = $a;
+ $this->b = $b;
+ $this->c = $c;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/Singleton.php b/vendor/phpunit/phpunit/tests/_files/Singleton.php
new file mode 100644
index 0000000..bfdf3bb
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/Singleton.php
@@ -0,0 +1,22 @@
+<?php
+class Singleton
+{
+ private static $uniqueInstance = null;
+
+ protected function __construct()
+ {
+ }
+
+ final private function __clone()
+ {
+ }
+
+ public static function getInstance()
+ {
+ if (self::$uniqueInstance === null) {
+ self::$uniqueInstance = new self;
+ }
+
+ return self::$uniqueInstance;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/StackTest.php b/vendor/phpunit/phpunit/tests/_files/StackTest.php
new file mode 100644
index 0000000..15bb0d9
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/StackTest.php
@@ -0,0 +1,24 @@
+<?php
+class StackTest extends PHPUnit_Framework_TestCase
+{
+ public function testPush()
+ {
+ $stack = [];
+ $this->assertCount(0, $stack);
+
+ array_push($stack, 'foo');
+ $this->assertEquals('foo', $stack[count($stack)-1]);
+ $this->assertCount(1, $stack);
+
+ return $stack;
+ }
+
+ /**
+ * @depends testPush
+ */
+ public function testPop(array $stack)
+ {
+ $this->assertEquals('foo', array_pop($stack));
+ $this->assertCount(0, $stack);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/StatusTest.php b/vendor/phpunit/phpunit/tests/_files/StatusTest.php
new file mode 100644
index 0000000..7753d4e
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/StatusTest.php
@@ -0,0 +1,37 @@
+<?php
+class StatusTest extends \PHPUnit\Framework\TestCase
+{
+ public function testSuccess()
+ {
+ $this->assertTrue(true);
+ }
+
+ public function testFailure()
+ {
+ $this->assertTrue(false);
+ }
+
+ public function testError()
+ {
+ throw new \Exception;
+ }
+
+ public function testIncomplete()
+ {
+ $this->markTestIncomplete();
+ }
+
+ public function testSkipped()
+ {
+ $this->markTestSkipped();
+ }
+
+ public function testRisky()
+ {
+ }
+
+ public function testWarning()
+ {
+ throw new PHPUnit_Framework_Warning;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/StopOnWarningTestSuite.php b/vendor/phpunit/phpunit/tests/_files/StopOnWarningTestSuite.php
new file mode 100644
index 0000000..8910a3f
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/StopOnWarningTestSuite.php
@@ -0,0 +1,13 @@
+<?php
+class StopOnWarningTestSuite
+{
+ public static function suite()
+ {
+ $suite = new PHPUnit_Framework_TestSuite('Test Warnings');
+
+ $suite->addTestSuite('NoTestCases');
+ $suite->addTestSuite('CoverageClassTest');
+
+ return $suite;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/StopsOnWarningTest.php b/vendor/phpunit/phpunit/tests/_files/StopsOnWarningTest.php
new file mode 100644
index 0000000..1608e67
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/StopsOnWarningTest.php
@@ -0,0 +1,7 @@
+<?php
+class StopsOnWarningTest extends PHPUnit_Framework_TestCase
+{
+ public function testOne()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/Struct.php b/vendor/phpunit/phpunit/tests/_files/Struct.php
new file mode 100644
index 0000000..12977a9
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/Struct.php
@@ -0,0 +1,10 @@
+<?php
+class Struct
+{
+ public $var;
+
+ public function __construct($var)
+ {
+ $this->var = $var;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/Success.php b/vendor/phpunit/phpunit/tests/_files/Success.php
new file mode 100644
index 0000000..6d3dd61
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/Success.php
@@ -0,0 +1,7 @@
+<?php
+class Success extends PHPUnit_Framework_TestCase
+{
+ protected function runTest()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/TemplateMethodsTest.php b/vendor/phpunit/phpunit/tests/_files/TemplateMethodsTest.php
new file mode 100644
index 0000000..d6b1364
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/TemplateMethodsTest.php
@@ -0,0 +1,51 @@
+<?php
+class TemplateMethodsTest extends PHPUnit_Framework_TestCase
+{
+ public static function setUpBeforeClass()
+ {
+ print __METHOD__ . "\n";
+ }
+
+ protected function setUp()
+ {
+ print __METHOD__ . "\n";
+ }
+
+ protected function assertPreConditions()
+ {
+ print __METHOD__ . "\n";
+ }
+
+ public function testOne()
+ {
+ print __METHOD__ . "\n";
+ $this->assertTrue(true);
+ }
+
+ public function testTwo()
+ {
+ print __METHOD__ . "\n";
+ $this->assertTrue(false);
+ }
+
+ protected function assertPostConditions()
+ {
+ print __METHOD__ . "\n";
+ }
+
+ protected function tearDown()
+ {
+ print __METHOD__ . "\n";
+ }
+
+ public static function tearDownAfterClass()
+ {
+ print __METHOD__ . "\n";
+ }
+
+ protected function onNotSuccessfulTest(Exception $e)
+ {
+ print __METHOD__ . "\n";
+ throw $e;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/TestAutoreferenced.php b/vendor/phpunit/phpunit/tests/_files/TestAutoreferenced.php
new file mode 100644
index 0000000..8145bbc
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/TestAutoreferenced.php
@@ -0,0 +1,12 @@
+<?php
+use PHPUnit\Framework\TestCase;
+
+class TestAutoreferenced extends TestCase
+{
+ public $myTestData = null;
+
+ public function testJsonEncodeException($data)
+ {
+ $this->myTestData = $data;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/TestDoxGroupTest.php b/vendor/phpunit/phpunit/tests/_files/TestDoxGroupTest.php
new file mode 100644
index 0000000..68bf321
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/TestDoxGroupTest.php
@@ -0,0 +1,18 @@
+<?php
+
+class TestDoxGroupTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @group one
+ */
+ public function testOne()
+ {
+ }
+
+ /**
+ * @group two
+ */
+ public function testTwo()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/TestGeneratorMaker.php b/vendor/phpunit/phpunit/tests/_files/TestGeneratorMaker.php
new file mode 100644
index 0000000..2fe8982
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/TestGeneratorMaker.php
@@ -0,0 +1,11 @@
+<?php
+class TestGeneratorMaker
+{
+ public function create($array = [])
+ {
+ foreach ($array as $key => $value) {
+ yield $key => $value;
+ }
+ }
+}
+
diff --git a/vendor/phpunit/phpunit/tests/_files/TestIncomplete.php b/vendor/phpunit/phpunit/tests/_files/TestIncomplete.php
new file mode 100644
index 0000000..743a761
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/TestIncomplete.php
@@ -0,0 +1,8 @@
+<?php
+class TestIncomplete extends PHPUnit_Framework_TestCase
+{
+ protected function runTest()
+ {
+ $this->markTestIncomplete('Incomplete test');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/TestIterator.php b/vendor/phpunit/phpunit/tests/_files/TestIterator.php
new file mode 100644
index 0000000..d26ac85
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/TestIterator.php
@@ -0,0 +1,36 @@
+<?php
+class TestIterator implements Iterator
+{
+ protected $array;
+ protected $position = 0;
+
+ public function __construct($array = [])
+ {
+ $this->array = $array;
+ }
+
+ public function rewind()
+ {
+ $this->position = 0;
+ }
+
+ public function valid()
+ {
+ return $this->position < count($this->array);
+ }
+
+ public function key()
+ {
+ return $this->position;
+ }
+
+ public function current()
+ {
+ return $this->array[$this->position];
+ }
+
+ public function next()
+ {
+ $this->position++;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/TestIterator2.php b/vendor/phpunit/phpunit/tests/_files/TestIterator2.php
new file mode 100644
index 0000000..3b47fa3
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/TestIterator2.php
@@ -0,0 +1,35 @@
+<?php
+class TestIterator2 implements Iterator
+{
+ protected $data;
+
+ public function __construct(array $array)
+ {
+ $this->data = $array;
+ }
+
+ public function current()
+ {
+ return current($this->data);
+ }
+
+ public function next()
+ {
+ next($this->data);
+ }
+
+ public function key()
+ {
+ return key($this->data);
+ }
+
+ public function valid()
+ {
+ return key($this->data) !== null;
+ }
+
+ public function rewind()
+ {
+ reset($this->data);
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/TestSkipped.php b/vendor/phpunit/phpunit/tests/_files/TestSkipped.php
new file mode 100644
index 0000000..c2d68b2
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/TestSkipped.php
@@ -0,0 +1,8 @@
+<?php
+class TestSkipped extends PHPUnit_Framework_TestCase
+{
+ protected function runTest()
+ {
+ $this->markTestSkipped('Skipped test');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/TestTestError.php b/vendor/phpunit/phpunit/tests/_files/TestTestError.php
new file mode 100644
index 0000000..6f61b8e
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/TestTestError.php
@@ -0,0 +1,8 @@
+<?php
+class TestError extends PHPUnit_Framework_TestCase
+{
+ protected function runTest()
+ {
+ throw new Exception;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/TestWithTest.php b/vendor/phpunit/phpunit/tests/_files/TestWithTest.php
new file mode 100644
index 0000000..a80fdbe
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/TestWithTest.php
@@ -0,0 +1,24 @@
+<?php
+class TestWithTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @testWith [0, 0, 0]
+ * [0, 1, 1]
+ * [1, 2, 3]
+ * [20, 22, 42]
+ */
+ public function testAdd($a, $b, $c)
+ {
+ $this->assertEquals($c, $a + $b);
+ }
+
+ public static function providerMethod()
+ {
+ return [
+ [0, 0, 0],
+ [0, 1, 1],
+ [1, 1, 3],
+ [1, 0, 1]
+ ];
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/ThrowExceptionTestCase.php b/vendor/phpunit/phpunit/tests/_files/ThrowExceptionTestCase.php
new file mode 100644
index 0000000..1d2a769
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/ThrowExceptionTestCase.php
@@ -0,0 +1,8 @@
+<?php
+class ThrowExceptionTestCase extends PHPUnit_Framework_TestCase
+{
+ public function test()
+ {
+ throw new RuntimeException('A runtime error occurred');
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/ThrowNoExceptionTestCase.php b/vendor/phpunit/phpunit/tests/_files/ThrowNoExceptionTestCase.php
new file mode 100644
index 0000000..76958cb
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/ThrowNoExceptionTestCase.php
@@ -0,0 +1,7 @@
+<?php
+class ThrowNoExceptionTestCase extends PHPUnit_Framework_TestCase
+{
+ public function test()
+ {
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/WasRun.php b/vendor/phpunit/phpunit/tests/_files/WasRun.php
new file mode 100644
index 0000000..4221b6d
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/WasRun.php
@@ -0,0 +1,10 @@
+<?php
+class WasRun extends PHPUnit_Framework_TestCase
+{
+ public $wasRun = false;
+
+ protected function runTest()
+ {
+ $this->wasRun = true;
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/bar.xml b/vendor/phpunit/phpunit/tests/_files/bar.xml
new file mode 100644
index 0000000..5d3fa28
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/bar.xml
@@ -0,0 +1 @@
+<bar/>
diff --git a/vendor/phpunit/phpunit/tests/_files/configuration.colors.empty.xml b/vendor/phpunit/phpunit/tests/_files/configuration.colors.empty.xml
new file mode 100644
index 0000000..5f9e055
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/configuration.colors.empty.xml
@@ -0,0 +1 @@
+<phpunit colors=""></phpunit>
diff --git a/vendor/phpunit/phpunit/tests/_files/configuration.colors.false.xml b/vendor/phpunit/phpunit/tests/_files/configuration.colors.false.xml
new file mode 100644
index 0000000..dcd4aa4
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/configuration.colors.false.xml
@@ -0,0 +1 @@
+<phpunit colors="false"></phpunit>
diff --git a/vendor/phpunit/phpunit/tests/_files/configuration.colors.invalid.xml b/vendor/phpunit/phpunit/tests/_files/configuration.colors.invalid.xml
new file mode 100644
index 0000000..c5bd699
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/configuration.colors.invalid.xml
@@ -0,0 +1 @@
+<phpunit colors="Something else"></phpunit>
diff --git a/vendor/phpunit/phpunit/tests/_files/configuration.colors.true.xml b/vendor/phpunit/phpunit/tests/_files/configuration.colors.true.xml
new file mode 100644
index 0000000..1efe413
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/configuration.colors.true.xml
@@ -0,0 +1 @@
+<phpunit colors="true"></phpunit>
diff --git a/vendor/phpunit/phpunit/tests/_files/configuration.custom-printer.xml b/vendor/phpunit/phpunit/tests/_files/configuration.custom-printer.xml
new file mode 100644
index 0000000..7a5a1f1
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/configuration.custom-printer.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit printerFile="CustomPrinter.php" printerClass="CustomPrinter" /> \ No newline at end of file
diff --git a/vendor/phpunit/phpunit/tests/_files/configuration.suites.xml b/vendor/phpunit/phpunit/tests/_files/configuration.suites.xml
new file mode 100644
index 0000000..eb9ec3d
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/configuration.suites.xml
@@ -0,0 +1,6 @@
+<phpunit>
+ <testsuites>
+ <testsuite name="Suite One"></testsuite>
+ <testsuite name="Suite Two"></testsuite>
+ </testsuites>
+</phpunit>
diff --git a/vendor/phpunit/phpunit/tests/_files/configuration.xml b/vendor/phpunit/phpunit/tests/_files/configuration.xml
new file mode 100644
index 0000000..50699f9
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/configuration.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8" ?>
+
+<phpunit backupGlobals="true"
+ backupStaticAttributes="false"
+ bootstrap="/path/to/bootstrap.php"
+ cacheTokens="false"
+ columns="80"
+ colors="false"
+ stderr="false"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ forceCoversAnnotation="false"
+ stopOnFailure="false"
+ stopOnWarning="false"
+ failOnWarning="false"
+ failOnRisky="false"
+ extensionsDirectory="/tmp"
+ printerClass="PHPUnit_TextUI_ResultPrinter"
+ testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"
+ beStrictAboutChangesToGlobalState="false"
+ beStrictAboutOutputDuringTests="false"
+ beStrictAboutResourceUsageDuringSmallTests="false"
+ beStrictAboutTestsThatDoNotTestAnything="false"
+ beStrictAboutTodoAnnotatedTests="false"
+ beStrictAboutCoversAnnotation="false"
+ enforceTimeLimit="false"
+ timeoutForSmallTests="1"
+ timeoutForMediumTests="10"
+ timeoutForLargeTests="60"
+ verbose="false">
+ <testsuites>
+ <testsuite name="My Test Suite">
+ <directory suffix="Test.php" phpVersion="5.3.0" phpVersionOperator=">=">/path/to/files</directory>
+ <file phpVersion="5.3.0" phpVersionOperator=">=">/path/to/MyTest.php</file>
+ </testsuite>
+ </testsuites>
+
+ <groups>
+ <include>
+ <group>name</group>
+ </include>
+ <exclude>
+ <group>name</group>
+ </exclude>
+ </groups>
+
+ <testdoxGroups>
+ <include>
+ <group>name</group>
+ </include>
+ <exclude>
+ <group>name</group>
+ </exclude>
+ </testdoxGroups>
+
+ <filter>
+ <whitelist addUncoveredFilesFromWhitelist="true"
+ processUncoveredFilesFromWhitelist="false">
+ <directory suffix=".php">/path/to/files</directory>
+ <file>/path/to/file</file>
+ <file>
+ /path/to/file
+ </file>
+ <exclude>
+ <directory suffix=".php">/path/to/files</directory>
+ <file>/path/to/file</file>
+ </exclude>
+ </whitelist>
+ </filter>
+
+ <listeners>
+ <listener class="MyListener" file="/optional/path/to/MyListener.php">
+ <arguments>
+ <array>
+ <element key="0">
+ <string>Sebastian</string>
+ </element>
+ </array>
+ <integer>22</integer>
+ <string>April</string>
+ <double>19.78</double>
+ <null/>
+ <object class="stdClass"/>
+ <file>MyTestFile.php</file>
+ <directory>MyRelativePath</directory>
+ </arguments>
+ </listener>
+ <listener class="IncludePathListener" file="ConfigurationTest.php" />
+ <listener class="CompactArgumentsListener" file="/CompactArgumentsListener.php"><arguments><integer>42</integer></arguments></listener>
+ </listeners>
+
+ <logging>
+ <log type="coverage-html" target="/tmp/report" lowUpperBound="50" highLowerBound="90"/>
+ <log type="coverage-clover" target="/tmp/clover.xml"/>
+ <log type="json" target="/tmp/logfile.json"/>
+ <log type="plain" target="/tmp/logfile.txt"/>
+ <log type="tap" target="/tmp/logfile.tap"/>
+ <log type="junit" target="/tmp/logfile.xml" logIncompleteSkipped="false"/>
+ <log type="testdox-html" target="/tmp/testdox.html"/>
+ <log type="testdox-text" target="/tmp/testdox.txt"/>
+ <log type="testdox-xml" target="/tmp/testdox.xml"/>
+ </logging>
+
+ <php>
+ <includePath>.</includePath>
+ <includePath>/path/to/lib</includePath>
+ <ini name="foo" value="bar"/>
+ <const name="FOO" value="false"/>
+ <const name="BAR" value="true"/>
+ <var name="foo" value="false"/>
+ <env name="foo" value="true"/>
+ <post name="foo" value="bar"/>
+ <get name="foo" value="bar"/>
+ <cookie name="foo" value="bar"/>
+ <server name="foo" value="bar"/>
+ <files name="foo" value="bar"/>
+ <request name="foo" value="bar"/>
+ </php>
+</phpunit>
+
diff --git a/vendor/phpunit/phpunit/tests/_files/configuration_empty.xml b/vendor/phpunit/phpunit/tests/_files/configuration_empty.xml
new file mode 100644
index 0000000..13d090d
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/configuration_empty.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8" ?>
+
+<phpunit bootstrap=""
+ testSuiteLoaderFile=""
+ printerFile="">
+ <testsuites>
+ <testsuite name="My Test Suite">
+ <directory></directory>
+ <file></file>
+ </testsuite>
+ </testsuites>
+
+ <groups>
+ <include>
+ <group></group>
+ </include>
+ <exclude>
+ <group></group>
+ </exclude>
+ </groups>
+
+ <filter>
+ <whitelist>
+ <directory></directory>
+ <file></file>
+ <exclude>
+ <directory></directory>
+ <file></file>
+ </exclude>
+ </whitelist>
+ </filter>
+
+ <logging>
+ <log type="coverage-html" target=""/>
+ <log type="coverage-clover" target=""/>
+ <log type="json" target=""/>
+ <log type="plain" target=""/>
+ <log type="tap" target=""/>
+ <log type="junit" target="" logIncompleteSkipped="false"/>
+ <log type="testdox-html" target=""/>
+ <log type="testdox-text" target=""/>
+ </logging>
+
+ <php>
+ <includePath/>
+ <includePath></includePath>
+ </php>
+</phpunit>
+
diff --git a/vendor/phpunit/phpunit/tests/_files/configuration_stop_on_warning.xml b/vendor/phpunit/phpunit/tests/_files/configuration_stop_on_warning.xml
new file mode 100644
index 0000000..8bcd06a
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/configuration_stop_on_warning.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit stopOnWarning="true" /> \ No newline at end of file
diff --git a/vendor/phpunit/phpunit/tests/_files/configuration_xinclude.xml b/vendor/phpunit/phpunit/tests/_files/configuration_xinclude.xml
new file mode 100644
index 0000000..ea177d6
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/configuration_xinclude.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8" ?>
+
+<phpunit backupGlobals="true"
+ backupStaticAttributes="false"
+ bootstrap="/path/to/bootstrap.php"
+ cacheTokens="false"
+ columns="80"
+ colors="false"
+ stderr="false"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ forceCoversAnnotation="false"
+ stopOnFailure="false"
+ stopOnWarning="false"
+ failOnWarning="false"
+ failOnRisky="false"
+ extensionsDirectory="/tmp"
+ printerClass="PHPUnit_TextUI_ResultPrinter"
+ testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"
+ beStrictAboutChangesToGlobalState="false"
+ beStrictAboutOutputDuringTests="false"
+ beStrictAboutResourceUsageDuringSmallTests="false"
+ beStrictAboutTestsThatDoNotTestAnything="false"
+ beStrictAboutTodoAnnotatedTests="false"
+ beStrictAboutCoversAnnotation="false"
+ enforceTimeLimit="false"
+ timeoutForSmallTests="1"
+ timeoutForMediumTests="10"
+ timeoutForLargeTests="60"
+ verbose="false">
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="configuration.xml"
+ parse="xml"
+ xpointer="xpointer(/phpunit/testsuites)" />
+
+ <groups>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="configuration.xml"
+ parse="xml"
+ xpointer="xpointer(/phpunit/groups/*)" />
+ </groups>
+
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="configuration.xml"
+ parse="xml"
+ xpointer="xpointer(/phpunit/filter)" />
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="configuration.xml"
+ parse="xml"
+ xpointer="xpointer(/phpunit/listeners)" />
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="configuration.xml"
+ parse="xml"
+ xpointer="xpointer(/phpunit/logging)" />
+
+ <php>
+ <includePath>.</includePath>
+ <includePath>/path/to/lib</includePath>
+ <ini name="foo" value="bar"/>
+ <const name="FOO" value="false"/>
+ <const name="BAR" value="true"/>
+ <var name="foo" value="false"/>
+ <env name="foo" value="true"/>
+ <post name="foo" value="bar"/>
+ <get name="foo" value="bar"/>
+ <cookie name="foo" value="bar"/>
+ <server name="foo" value="bar"/>
+ <files name="foo" value="bar"/>
+ <request name="foo" value="bar"/>
+ </php>
+</phpunit>
+
diff --git a/vendor/phpunit/phpunit/tests/_files/expectedFileFormat.txt b/vendor/phpunit/phpunit/tests/_files/expectedFileFormat.txt
new file mode 100644
index 0000000..b7d6715
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/expectedFileFormat.txt
@@ -0,0 +1 @@
+FOO
diff --git a/vendor/phpunit/phpunit/tests/_files/foo.xml b/vendor/phpunit/phpunit/tests/_files/foo.xml
new file mode 100644
index 0000000..f1999f8
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/foo.xml
@@ -0,0 +1 @@
+<foo/>
diff --git a/vendor/phpunit/phpunit/tests/_files/phpt-for-coverage.phpt b/vendor/phpunit/phpunit/tests/_files/phpt-for-coverage.phpt
new file mode 100644
index 0000000..4e9a804
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/phpt-for-coverage.phpt
@@ -0,0 +1,8 @@
+--TEST--
+PHPT for testing coverage
+--FILE--
+<?php
+require __DIR__ . '/../bootstrap.php';
+$coveredClass = new CoveredClass();
+$coveredClass->publicMethod();
+--EXPECT--
diff --git a/vendor/phpunit/phpunit/tests/_files/phpt-xfail.phpt b/vendor/phpunit/phpunit/tests/_files/phpt-xfail.phpt
new file mode 100644
index 0000000..c8ccad9
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/phpt-xfail.phpt
@@ -0,0 +1,11 @@
+--TEST--
+PHPT runner supports XFAIL section
+--FILE--
+<?php
+{syntaxError}
+echo "Should not see this";
+?>
+--XFAIL--
+Syntax Error in PHPT is supposed to fail
+--EXPECT--
+Should not see this
diff --git a/vendor/phpunit/phpunit/tests/_files/phpunit-example-extension/phpunit.xml b/vendor/phpunit/phpunit/tests/_files/phpunit-example-extension/phpunit.xml
new file mode 100644
index 0000000..fe69eab
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/phpunit-example-extension/phpunit.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/5.7/phpunit.xsd"
+ verbose="true"
+ extensionsDirectory="tools/phpunit.d">
+ <testsuite>
+ <directory suffix="Test.php">tests</directory>
+ </testsuite>
+</phpunit>
+
diff --git a/vendor/phpunit/phpunit/tests/_files/phpunit-example-extension/tests/OneTest.php b/vendor/phpunit/phpunit/tests/_files/phpunit-example-extension/tests/OneTest.php
new file mode 100644
index 0000000..7d0a198
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/phpunit-example-extension/tests/OneTest.php
@@ -0,0 +1,12 @@
+<?php
+use PHPUnit\ExampleExtension\TestCaseTrait;
+
+class OneTest extends PHPUnit\Framework\TestCase
+{
+ use TestCaseTrait;
+
+ public function testOne()
+ {
+ $this->assertExampleExtensionInitialized();
+ }
+}
diff --git a/vendor/phpunit/phpunit/tests/_files/phpunit-example-extension/tools/phpunit.d/phpunit-example-extension-1.0.0.phar b/vendor/phpunit/phpunit/tests/_files/phpunit-example-extension/tools/phpunit.d/phpunit-example-extension-1.0.0.phar
new file mode 100644
index 0000000..1b3c030
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/phpunit-example-extension/tools/phpunit.d/phpunit-example-extension-1.0.0.phar
Binary files differ
diff --git a/vendor/phpunit/phpunit/tests/_files/structureAttributesAreSameButValuesAreNot.xml b/vendor/phpunit/phpunit/tests/_files/structureAttributesAreSameButValuesAreNot.xml
new file mode 100644
index 0000000..a5d9ab3
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/structureAttributesAreSameButValuesAreNot.xml
@@ -0,0 +1,10 @@
+<text:p xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">
+ <draw:frame xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" svg:width="12.567708175cm" svg:height="16.848541467cm" draw:style-name="Frame">
+ <draw:text-box>
+ <draw:frame svg:width="12.567708175cm" svg:height="15.848541467cm" draw:style-name="Image">
+ <draw:image xmlns:xlink="notthesame" xlink:href="Pictures/kristian.jpg"/>
+ </draw:frame>
+ <text:p text:style-name="Text">Image <text:sequence xmlns:style="notthesame" text:ref-name="refImage1" style:num-format="1" text:formula="ooow:Image+1" text:name="Image">1</text:sequence>: Dette er en test caption</text:p>
+ </draw:text-box>
+ </draw:frame>
+</text:p>
diff --git a/vendor/phpunit/phpunit/tests/_files/structureExpected.xml b/vendor/phpunit/phpunit/tests/_files/structureExpected.xml
new file mode 100644
index 0000000..d900105
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/structureExpected.xml
@@ -0,0 +1,10 @@
+<text:p xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">
+ <draw:frame xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" svg:width="12.567708175cm" svg:height="16.848541467cm" draw:style-name="Frame">
+ <draw:text-box>
+ <draw:frame svg:width="12.567708175cm" svg:height="15.848541467cm" draw:style-name="Image">
+ <draw:image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="Pictures/kristian.jpg"/>
+ </draw:frame>
+ <text:p text:style-name="Text">Image <text:sequence xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" text:ref-name="refImage1" style:num-format="1" text:formula="ooow:Image+1" text:name="Image">1</text:sequence>: Dette er en test caption</text:p>
+ </draw:text-box>
+ </draw:frame>
+</text:p>
diff --git a/vendor/phpunit/phpunit/tests/_files/structureIgnoreTextNodes.xml b/vendor/phpunit/phpunit/tests/_files/structureIgnoreTextNodes.xml
new file mode 100644
index 0000000..0771b60
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/structureIgnoreTextNodes.xml
@@ -0,0 +1,13 @@
+<text:p xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">
+ <draw:frame xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" svg:width="12.567708175cm" svg:height="16.848541467cm" draw:style-name="Frame">
+ <draw:text-box>
+ textnode
+ <draw:frame svg:width="12.567708175cm" svg:height="15.848541467cm" draw:style-name="Image">
+ <draw:image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="Pictures/kristian.jpg"/> textnode
+ </draw:frame>
+ textnode
+ <text:p text:style-name="Text">Image <text:sequence xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" text:ref-name="refImage1" style:num-format="1" text:formula="ooow:Image+1" text:name="Image">1</text:sequence>: Dette er en test caption</text:p>
+ textnode
+ </draw:text-box>
+ </draw:frame>
+</text:p>
diff --git a/vendor/phpunit/phpunit/tests/_files/structureIsSameButDataIsNot.xml b/vendor/phpunit/phpunit/tests/_files/structureIsSameButDataIsNot.xml
new file mode 100644
index 0000000..2ba21b9
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/structureIsSameButDataIsNot.xml
@@ -0,0 +1,10 @@
+<text:p xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">
+ <draw:frame xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" svg:width="12.567708175cm" svg:height="16.848541467cm" draw:style-name="Frame">
+ <draw:text-box>
+ <draw:frame svg:width="12.567708175cm" svg:height="15.848541467cm" draw:style-name="Image">
+ <draw:image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="Pictures/kristian.jpg"/>
+ </draw:frame>
+ <text:p text:style-name="Text">Image is not the same <text:sequence xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" text:ref-name="refImage1" style:num-format="1" text:formula="ooow:Image+1" text:name="Image">1</text:sequence>: Dette er en test caption</text:p>
+ </draw:text-box>
+ </draw:frame>
+</text:p>
diff --git a/vendor/phpunit/phpunit/tests/_files/structureWrongNumberOfAttributes.xml b/vendor/phpunit/phpunit/tests/_files/structureWrongNumberOfAttributes.xml
new file mode 100644
index 0000000..af9b974
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/structureWrongNumberOfAttributes.xml
@@ -0,0 +1,10 @@
+<text:p xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">
+ <draw:frame xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" svg:width="12.567708175cm" svg:height="16.848541467cm" draw:style-name="Frame">
+ <draw:text-box>
+ <draw:frame svg:width="12.567708175cm" svg:height="15.848541467cm" draw:style-name="Image">
+ <draw:image/>
+ </draw:frame>
+ <text:p text:style-name="Text">Image <text:sequence xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" text:ref-name="refImage1" style:num-format="1" text:formula="ooow:Image+1" text:name="Image">1</text:sequence>: Dette er en test caption</text:p>
+ </draw:text-box>
+ </draw:frame>
+</text:p>
diff --git a/vendor/phpunit/phpunit/tests/_files/structureWrongNumberOfNodes.xml b/vendor/phpunit/phpunit/tests/_files/structureWrongNumberOfNodes.xml
new file mode 100644
index 0000000..9a394e2
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/_files/structureWrongNumberOfNodes.xml
@@ -0,0 +1,9 @@
+<text:p xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">
+ <draw:frame xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" svg:width="12.567708175cm" svg:height="16.848541467cm" draw:style-name="Frame">
+ <draw:text-box>
+ <draw:frame svg:width="12.567708175cm" svg:height="15.848541467cm" draw:style-name="Image">
+ <draw:image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="Pictures/kristian.jpg"/>
+ </draw:frame>
+ </draw:text-box>
+ </draw:frame>
+</text:p>
diff --git a/vendor/phpunit/phpunit/tests/bootstrap.php b/vendor/phpunit/phpunit/tests/bootstrap.php
new file mode 100644
index 0000000..cc79889
--- /dev/null
+++ b/vendor/phpunit/phpunit/tests/bootstrap.php
@@ -0,0 +1,6 @@
+<?php
+// Needed for isolated tests
+require __DIR__ . '/../vendor/autoload.php';
+
+ini_set('precision', 14);
+ini_set('serialize_precision', 14);
diff --git a/vendor/psr/http-message/CHANGELOG.md b/vendor/psr/http-message/CHANGELOG.md
new file mode 100644
index 0000000..74b1ef9
--- /dev/null
+++ b/vendor/psr/http-message/CHANGELOG.md
@@ -0,0 +1,36 @@
+# Changelog
+
+All notable changes to this project will be documented in this file, in reverse chronological order by release.
+
+## 1.0.1 - 2016-08-06
+
+### Added
+
+- Nothing.
+
+### Deprecated
+
+- Nothing.
+
+### Removed
+
+- Nothing.
+
+### Fixed
+
+- Updated all `@return self` annotation references in interfaces to use
+ `@return static`, which more closelly follows the semantics of the
+ specification.
+- Updated the `MessageInterface::getHeaders()` return annotation to use the
+ value `string[][]`, indicating the format is a nested array of strings.
+- Updated the `@link` annotation for `RequestInterface::withRequestTarget()`
+ to point to the correct section of RFC 7230.
+- Updated the `ServerRequestInterface::withUploadedFiles()` parameter annotation
+ to add the parameter name (`$uploadedFiles`).
+- Updated a `@throws` annotation for the `UploadedFileInterface::moveTo()`
+ method to correctly reference the method parameter (it was referencing an
+ incorrect parameter name previously).
+
+## 1.0.0 - 2016-05-18
+
+Initial stable release; reflects accepted PSR-7 specification.
diff --git a/vendor/psr/http-message/LICENSE b/vendor/psr/http-message/LICENSE
new file mode 100644
index 0000000..c2d8e45
--- /dev/null
+++ b/vendor/psr/http-message/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2014 PHP Framework Interoperability Group
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/psr/http-message/README.md b/vendor/psr/http-message/README.md
new file mode 100644
index 0000000..2818533
--- /dev/null
+++ b/vendor/psr/http-message/README.md
@@ -0,0 +1,13 @@
+PSR Http Message
+================
+
+This repository holds all interfaces/classes/traits related to
+[PSR-7](http://www.php-fig.org/psr/psr-7/).
+
+Note that this is not a HTTP message implementation of its own. It is merely an
+interface that describes a HTTP message. See the specification for more details.
+
+Usage
+-----
+
+We'll certainly need some stuff in here. \ No newline at end of file
diff --git a/vendor/psr/http-message/composer.json b/vendor/psr/http-message/composer.json
new file mode 100644
index 0000000..b0d2937
--- /dev/null
+++ b/vendor/psr/http-message/composer.json
@@ -0,0 +1,26 @@
+{
+ "name": "psr/http-message",
+ "description": "Common interface for HTTP messages",
+ "keywords": ["psr", "psr-7", "http", "http-message", "request", "response"],
+ "homepage": "https://github.com/php-fig/http-message",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/psr/http-message/src/MessageInterface.php b/vendor/psr/http-message/src/MessageInterface.php
new file mode 100644
index 0000000..dd46e5e
--- /dev/null
+++ b/vendor/psr/http-message/src/MessageInterface.php
@@ -0,0 +1,187 @@
+<?php
+
+namespace Psr\Http\Message;
+
+/**
+ * HTTP messages consist of requests from a client to a server and responses
+ * from a server to a client. This interface defines the methods common to
+ * each.
+ *
+ * Messages are considered immutable; all methods that might change state MUST
+ * be implemented such that they retain the internal state of the current
+ * message and return an instance that contains the changed state.
+ *
+ * @link http://www.ietf.org/rfc/rfc7230.txt
+ * @link http://www.ietf.org/rfc/rfc7231.txt
+ */
+interface MessageInterface
+{
+ /**
+ * Retrieves the HTTP protocol version as a string.
+ *
+ * The string MUST contain only the HTTP version number (e.g., "1.1", "1.0").
+ *
+ * @return string HTTP protocol version.
+ */
+ public function getProtocolVersion();
+
+ /**
+ * Return an instance with the specified HTTP protocol version.
+ *
+ * The version string MUST contain only the HTTP version number (e.g.,
+ * "1.1", "1.0").
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * new protocol version.
+ *
+ * @param string $version HTTP protocol version
+ * @return static
+ */
+ public function withProtocolVersion($version);
+
+ /**
+ * Retrieves all message header values.
+ *
+ * The keys represent the header name as it will be sent over the wire, and
+ * each value is an array of strings associated with the header.
+ *
+ * // Represent the headers as a string
+ * foreach ($message->getHeaders() as $name => $values) {
+ * echo $name . ": " . implode(", ", $values);
+ * }
+ *
+ * // Emit headers iteratively:
+ * foreach ($message->getHeaders() as $name => $values) {
+ * foreach ($values as $value) {
+ * header(sprintf('%s: %s', $name, $value), false);
+ * }
+ * }
+ *
+ * While header names are not case-sensitive, getHeaders() will preserve the
+ * exact case in which headers were originally specified.
+ *
+ * @return string[][] Returns an associative array of the message's headers. Each
+ * key MUST be a header name, and each value MUST be an array of strings
+ * for that header.
+ */
+ public function getHeaders();
+
+ /**
+ * Checks if a header exists by the given case-insensitive name.
+ *
+ * @param string $name Case-insensitive header field name.
+ * @return bool Returns true if any header names match the given header
+ * name using a case-insensitive string comparison. Returns false if
+ * no matching header name is found in the message.
+ */
+ public function hasHeader($name);
+
+ /**
+ * Retrieves a message header value by the given case-insensitive name.
+ *
+ * This method returns an array of all the header values of the given
+ * case-insensitive header name.
+ *
+ * If the header does not appear in the message, this method MUST return an
+ * empty array.
+ *
+ * @param string $name Case-insensitive header field name.
+ * @return string[] An array of string values as provided for the given
+ * header. If the header does not appear in the message, this method MUST
+ * return an empty array.
+ */
+ public function getHeader($name);
+
+ /**
+ * Retrieves a comma-separated string of the values for a single header.
+ *
+ * This method returns all of the header values of the given
+ * case-insensitive header name as a string concatenated together using
+ * a comma.
+ *
+ * NOTE: Not all header values may be appropriately represented using
+ * comma concatenation. For such headers, use getHeader() instead
+ * and supply your own delimiter when concatenating.
+ *
+ * If the header does not appear in the message, this method MUST return
+ * an empty string.
+ *
+ * @param string $name Case-insensitive header field name.
+ * @return string A string of values as provided for the given header
+ * concatenated together using a comma. If the header does not appear in
+ * the message, this method MUST return an empty string.
+ */
+ public function getHeaderLine($name);
+
+ /**
+ * Return an instance with the provided value replacing the specified header.
+ *
+ * While header names are case-insensitive, the casing of the header will
+ * be preserved by this function, and returned from getHeaders().
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * new and/or updated header and value.
+ *
+ * @param string $name Case-insensitive header field name.
+ * @param string|string[] $value Header value(s).
+ * @return static
+ * @throws \InvalidArgumentException for invalid header names or values.
+ */
+ public function withHeader($name, $value);
+
+ /**
+ * Return an instance with the specified header appended with the given value.
+ *
+ * Existing values for the specified header will be maintained. The new
+ * value(s) will be appended to the existing list. If the header did not
+ * exist previously, it will be added.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * new header and/or value.
+ *
+ * @param string $name Case-insensitive header field name to add.
+ * @param string|string[] $value Header value(s).
+ * @return static
+ * @throws \InvalidArgumentException for invalid header names or values.
+ */
+ public function withAddedHeader($name, $value);
+
+ /**
+ * Return an instance without the specified header.
+ *
+ * Header resolution MUST be done without case-sensitivity.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that removes
+ * the named header.
+ *
+ * @param string $name Case-insensitive header field name to remove.
+ * @return static
+ */
+ public function withoutHeader($name);
+
+ /**
+ * Gets the body of the message.
+ *
+ * @return StreamInterface Returns the body as a stream.
+ */
+ public function getBody();
+
+ /**
+ * Return an instance with the specified message body.
+ *
+ * The body MUST be a StreamInterface object.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return a new instance that has the
+ * new body stream.
+ *
+ * @param StreamInterface $body Body.
+ * @return static
+ * @throws \InvalidArgumentException When the body is not valid.
+ */
+ public function withBody(StreamInterface $body);
+}
diff --git a/vendor/psr/http-message/src/RequestInterface.php b/vendor/psr/http-message/src/RequestInterface.php
new file mode 100644
index 0000000..a96d4fd
--- /dev/null
+++ b/vendor/psr/http-message/src/RequestInterface.php
@@ -0,0 +1,129 @@
+<?php
+
+namespace Psr\Http\Message;
+
+/**
+ * Representation of an outgoing, client-side request.
+ *
+ * Per the HTTP specification, this interface includes properties for
+ * each of the following:
+ *
+ * - Protocol version
+ * - HTTP method
+ * - URI
+ * - Headers
+ * - Message body
+ *
+ * During construction, implementations MUST attempt to set the Host header from
+ * a provided URI if no Host header is provided.
+ *
+ * Requests are considered immutable; all methods that might change state MUST
+ * be implemented such that they retain the internal state of the current
+ * message and return an instance that contains the changed state.
+ */
+interface RequestInterface extends MessageInterface
+{
+ /**
+ * Retrieves the message's request target.
+ *
+ * Retrieves the message's request-target either as it will appear (for
+ * clients), as it appeared at request (for servers), or as it was
+ * specified for the instance (see withRequestTarget()).
+ *
+ * In most cases, this will be the origin-form of the composed URI,
+ * unless a value was provided to the concrete implementation (see
+ * withRequestTarget() below).
+ *
+ * If no URI is available, and no request-target has been specifically
+ * provided, this method MUST return the string "/".
+ *
+ * @return string
+ */
+ public function getRequestTarget();
+
+ /**
+ * Return an instance with the specific request-target.
+ *
+ * If the request needs a non-origin-form request-target — e.g., for
+ * specifying an absolute-form, authority-form, or asterisk-form —
+ * this method may be used to create an instance with the specified
+ * request-target, verbatim.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * changed request target.
+ *
+ * @link http://tools.ietf.org/html/rfc7230#section-5.3 (for the various
+ * request-target forms allowed in request messages)
+ * @param mixed $requestTarget
+ * @return static
+ */
+ public function withRequestTarget($requestTarget);
+
+ /**
+ * Retrieves the HTTP method of the request.
+ *
+ * @return string Returns the request method.
+ */
+ public function getMethod();
+
+ /**
+ * Return an instance with the provided HTTP method.
+ *
+ * While HTTP method names are typically all uppercase characters, HTTP
+ * method names are case-sensitive and thus implementations SHOULD NOT
+ * modify the given string.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * changed request method.
+ *
+ * @param string $method Case-sensitive method.
+ * @return static
+ * @throws \InvalidArgumentException for invalid HTTP methods.
+ */
+ public function withMethod($method);
+
+ /**
+ * Retrieves the URI instance.
+ *
+ * This method MUST return a UriInterface instance.
+ *
+ * @link http://tools.ietf.org/html/rfc3986#section-4.3
+ * @return UriInterface Returns a UriInterface instance
+ * representing the URI of the request.
+ */
+ public function getUri();
+
+ /**
+ * Returns an instance with the provided URI.
+ *
+ * This method MUST update the Host header of the returned request by
+ * default if the URI contains a host component. If the URI does not
+ * contain a host component, any pre-existing Host header MUST be carried
+ * over to the returned request.
+ *
+ * You can opt-in to preserving the original state of the Host header by
+ * setting `$preserveHost` to `true`. When `$preserveHost` is set to
+ * `true`, this method interacts with the Host header in the following ways:
+ *
+ * - If the Host header is missing or empty, and the new URI contains
+ * a host component, this method MUST update the Host header in the returned
+ * request.
+ * - If the Host header is missing or empty, and the new URI does not contain a
+ * host component, this method MUST NOT update the Host header in the returned
+ * request.
+ * - If a Host header is present and non-empty, this method MUST NOT update
+ * the Host header in the returned request.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * new UriInterface instance.
+ *
+ * @link http://tools.ietf.org/html/rfc3986#section-4.3
+ * @param UriInterface $uri New request URI to use.
+ * @param bool $preserveHost Preserve the original state of the Host header.
+ * @return static
+ */
+ public function withUri(UriInterface $uri, $preserveHost = false);
+}
diff --git a/vendor/psr/http-message/src/ResponseInterface.php b/vendor/psr/http-message/src/ResponseInterface.php
new file mode 100644
index 0000000..c306514
--- /dev/null
+++ b/vendor/psr/http-message/src/ResponseInterface.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Psr\Http\Message;
+
+/**
+ * Representation of an outgoing, server-side response.
+ *
+ * Per the HTTP specification, this interface includes properties for
+ * each of the following:
+ *
+ * - Protocol version
+ * - Status code and reason phrase
+ * - Headers
+ * - Message body
+ *
+ * Responses are considered immutable; all methods that might change state MUST
+ * be implemented such that they retain the internal state of the current
+ * message and return an instance that contains the changed state.
+ */
+interface ResponseInterface extends MessageInterface
+{
+ /**
+ * Gets the response status code.
+ *
+ * The status code is a 3-digit integer result code of the server's attempt
+ * to understand and satisfy the request.
+ *
+ * @return int Status code.
+ */
+ public function getStatusCode();
+
+ /**
+ * Return an instance with the specified status code and, optionally, reason phrase.
+ *
+ * If no reason phrase is specified, implementations MAY choose to default
+ * to the RFC 7231 or IANA recommended reason phrase for the response's
+ * status code.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated status and reason phrase.
+ *
+ * @link http://tools.ietf.org/html/rfc7231#section-6
+ * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
+ * @param int $code The 3-digit integer result code to set.
+ * @param string $reasonPhrase The reason phrase to use with the
+ * provided status code; if none is provided, implementations MAY
+ * use the defaults as suggested in the HTTP specification.
+ * @return static
+ * @throws \InvalidArgumentException For invalid status code arguments.
+ */
+ public function withStatus($code, $reasonPhrase = '');
+
+ /**
+ * Gets the response reason phrase associated with the status code.
+ *
+ * Because a reason phrase is not a required element in a response
+ * status line, the reason phrase value MAY be null. Implementations MAY
+ * choose to return the default RFC 7231 recommended reason phrase (or those
+ * listed in the IANA HTTP Status Code Registry) for the response's
+ * status code.
+ *
+ * @link http://tools.ietf.org/html/rfc7231#section-6
+ * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
+ * @return string Reason phrase; must return an empty string if none present.
+ */
+ public function getReasonPhrase();
+}
diff --git a/vendor/psr/http-message/src/ServerRequestInterface.php b/vendor/psr/http-message/src/ServerRequestInterface.php
new file mode 100644
index 0000000..0251234
--- /dev/null
+++ b/vendor/psr/http-message/src/ServerRequestInterface.php
@@ -0,0 +1,261 @@
+<?php
+
+namespace Psr\Http\Message;
+
+/**
+ * Representation of an incoming, server-side HTTP request.
+ *
+ * Per the HTTP specification, this interface includes properties for
+ * each of the following:
+ *
+ * - Protocol version
+ * - HTTP method
+ * - URI
+ * - Headers
+ * - Message body
+ *
+ * Additionally, it encapsulates all data as it has arrived to the
+ * application from the CGI and/or PHP environment, including:
+ *
+ * - The values represented in $_SERVER.
+ * - Any cookies provided (generally via $_COOKIE)
+ * - Query string arguments (generally via $_GET, or as parsed via parse_str())
+ * - Upload files, if any (as represented by $_FILES)
+ * - Deserialized body parameters (generally from $_POST)
+ *
+ * $_SERVER values MUST be treated as immutable, as they represent application
+ * state at the time of request; as such, no methods are provided to allow
+ * modification of those values. The other values provide such methods, as they
+ * can be restored from $_SERVER or the request body, and may need treatment
+ * during the application (e.g., body parameters may be deserialized based on
+ * content type).
+ *
+ * Additionally, this interface recognizes the utility of introspecting a
+ * request to derive and match additional parameters (e.g., via URI path
+ * matching, decrypting cookie values, deserializing non-form-encoded body
+ * content, matching authorization headers to users, etc). These parameters
+ * are stored in an "attributes" property.
+ *
+ * Requests are considered immutable; all methods that might change state MUST
+ * be implemented such that they retain the internal state of the current
+ * message and return an instance that contains the changed state.
+ */
+interface ServerRequestInterface extends RequestInterface
+{
+ /**
+ * Retrieve server parameters.
+ *
+ * Retrieves data related to the incoming request environment,
+ * typically derived from PHP's $_SERVER superglobal. The data IS NOT
+ * REQUIRED to originate from $_SERVER.
+ *
+ * @return array
+ */
+ public function getServerParams();
+
+ /**
+ * Retrieve cookies.
+ *
+ * Retrieves cookies sent by the client to the server.
+ *
+ * The data MUST be compatible with the structure of the $_COOKIE
+ * superglobal.
+ *
+ * @return array
+ */
+ public function getCookieParams();
+
+ /**
+ * Return an instance with the specified cookies.
+ *
+ * The data IS NOT REQUIRED to come from the $_COOKIE superglobal, but MUST
+ * be compatible with the structure of $_COOKIE. Typically, this data will
+ * be injected at instantiation.
+ *
+ * This method MUST NOT update the related Cookie header of the request
+ * instance, nor related values in the server params.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated cookie values.
+ *
+ * @param array $cookies Array of key/value pairs representing cookies.
+ * @return static
+ */
+ public function withCookieParams(array $cookies);
+
+ /**
+ * Retrieve query string arguments.
+ *
+ * Retrieves the deserialized query string arguments, if any.
+ *
+ * Note: the query params might not be in sync with the URI or server
+ * params. If you need to ensure you are only getting the original
+ * values, you may need to parse the query string from `getUri()->getQuery()`
+ * or from the `QUERY_STRING` server param.
+ *
+ * @return array
+ */
+ public function getQueryParams();
+
+ /**
+ * Return an instance with the specified query string arguments.
+ *
+ * These values SHOULD remain immutable over the course of the incoming
+ * request. They MAY be injected during instantiation, such as from PHP's
+ * $_GET superglobal, or MAY be derived from some other value such as the
+ * URI. In cases where the arguments are parsed from the URI, the data
+ * MUST be compatible with what PHP's parse_str() would return for
+ * purposes of how duplicate query parameters are handled, and how nested
+ * sets are handled.
+ *
+ * Setting query string arguments MUST NOT change the URI stored by the
+ * request, nor the values in the server params.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated query string arguments.
+ *
+ * @param array $query Array of query string arguments, typically from
+ * $_GET.
+ * @return static
+ */
+ public function withQueryParams(array $query);
+
+ /**
+ * Retrieve normalized file upload data.
+ *
+ * This method returns upload metadata in a normalized tree, with each leaf
+ * an instance of Psr\Http\Message\UploadedFileInterface.
+ *
+ * These values MAY be prepared from $_FILES or the message body during
+ * instantiation, or MAY be injected via withUploadedFiles().
+ *
+ * @return array An array tree of UploadedFileInterface instances; an empty
+ * array MUST be returned if no data is present.
+ */
+ public function getUploadedFiles();
+
+ /**
+ * Create a new instance with the specified uploaded files.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated body parameters.
+ *
+ * @param array $uploadedFiles An array tree of UploadedFileInterface instances.
+ * @return static
+ * @throws \InvalidArgumentException if an invalid structure is provided.
+ */
+ public function withUploadedFiles(array $uploadedFiles);
+
+ /**
+ * Retrieve any parameters provided in the request body.
+ *
+ * If the request Content-Type is either application/x-www-form-urlencoded
+ * or multipart/form-data, and the request method is POST, this method MUST
+ * return the contents of $_POST.
+ *
+ * Otherwise, this method may return any results of deserializing
+ * the request body content; as parsing returns structured content, the
+ * potential types MUST be arrays or objects only. A null value indicates
+ * the absence of body content.
+ *
+ * @return null|array|object The deserialized body parameters, if any.
+ * These will typically be an array or object.
+ */
+ public function getParsedBody();
+
+ /**
+ * Return an instance with the specified body parameters.
+ *
+ * These MAY be injected during instantiation.
+ *
+ * If the request Content-Type is either application/x-www-form-urlencoded
+ * or multipart/form-data, and the request method is POST, use this method
+ * ONLY to inject the contents of $_POST.
+ *
+ * The data IS NOT REQUIRED to come from $_POST, but MUST be the results of
+ * deserializing the request body content. Deserialization/parsing returns
+ * structured data, and, as such, this method ONLY accepts arrays or objects,
+ * or a null value if nothing was available to parse.
+ *
+ * As an example, if content negotiation determines that the request data
+ * is a JSON payload, this method could be used to create a request
+ * instance with the deserialized parameters.
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated body parameters.
+ *
+ * @param null|array|object $data The deserialized body data. This will
+ * typically be in an array or object.
+ * @return static
+ * @throws \InvalidArgumentException if an unsupported argument type is
+ * provided.
+ */
+ public function withParsedBody($data);
+
+ /**
+ * Retrieve attributes derived from the request.
+ *
+ * The request "attributes" may be used to allow injection of any
+ * parameters derived from the request: e.g., the results of path
+ * match operations; the results of decrypting cookies; the results of
+ * deserializing non-form-encoded message bodies; etc. Attributes
+ * will be application and request specific, and CAN be mutable.
+ *
+ * @return array Attributes derived from the request.
+ */
+ public function getAttributes();
+
+ /**
+ * Retrieve a single derived request attribute.
+ *
+ * Retrieves a single derived request attribute as described in
+ * getAttributes(). If the attribute has not been previously set, returns
+ * the default value as provided.
+ *
+ * This method obviates the need for a hasAttribute() method, as it allows
+ * specifying a default value to return if the attribute is not found.
+ *
+ * @see getAttributes()
+ * @param string $name The attribute name.
+ * @param mixed $default Default value to return if the attribute does not exist.
+ * @return mixed
+ */
+ public function getAttribute($name, $default = null);
+
+ /**
+ * Return an instance with the specified derived request attribute.
+ *
+ * This method allows setting a single derived request attribute as
+ * described in getAttributes().
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that has the
+ * updated attribute.
+ *
+ * @see getAttributes()
+ * @param string $name The attribute name.
+ * @param mixed $value The value of the attribute.
+ * @return static
+ */
+ public function withAttribute($name, $value);
+
+ /**
+ * Return an instance that removes the specified derived request attribute.
+ *
+ * This method allows removing a single derived request attribute as
+ * described in getAttributes().
+ *
+ * This method MUST be implemented in such a way as to retain the
+ * immutability of the message, and MUST return an instance that removes
+ * the attribute.
+ *
+ * @see getAttributes()
+ * @param string $name The attribute name.
+ * @return static
+ */
+ public function withoutAttribute($name);
+}
diff --git a/vendor/psr/http-message/src/StreamInterface.php b/vendor/psr/http-message/src/StreamInterface.php
new file mode 100644
index 0000000..f68f391
--- /dev/null
+++ b/vendor/psr/http-message/src/StreamInterface.php
@@ -0,0 +1,158 @@
+<?php
+
+namespace Psr\Http\Message;
+
+/**
+ * Describes a data stream.
+ *
+ * Typically, an instance will wrap a PHP stream; this interface provides
+ * a wrapper around the most common operations, including serialization of
+ * the entire stream to a string.
+ */
+interface StreamInterface
+{
+ /**
+ * Reads all data from the stream into a string, from the beginning to end.
+ *
+ * This method MUST attempt to seek to the beginning of the stream before
+ * reading data and read the stream until the end is reached.
+ *
+ * Warning: This could attempt to load a large amount of data into memory.
+ *
+ * This method MUST NOT raise an exception in order to conform with PHP's
+ * string casting operations.
+ *
+ * @see http://php.net/manual/en/language.oop5.magic.php#object.tostring
+ * @return string
+ */
+ public function __toString();
+
+ /**
+ * Closes the stream and any underlying resources.
+ *
+ * @return void
+ */
+ public function close();
+
+ /**
+ * Separates any underlying resources from the stream.
+ *
+ * After the stream has been detached, the stream is in an unusable state.
+ *
+ * @return resource|null Underlying PHP stream, if any
+ */
+ public function detach();
+
+ /**
+ * Get the size of the stream if known.
+ *
+ * @return int|null Returns the size in bytes if known, or null if unknown.
+ */
+ public function getSize();
+
+ /**
+ * Returns the current position of the file read/write pointer
+ *
+ * @return int Position of the file pointer
+ * @throws \RuntimeException on error.
+ */
+ public function tell();
+
+ /**
+ * Returns true if the stream is at the end of the stream.
+ *
+ * @return bool
+ */
+ public function eof();
+
+ /**
+ * Returns whether or not the stream is seekable.
+ *
+ * @return bool
+ */
+ public function isSeekable();
+
+ /**
+ * Seek to a position in the stream.
+ *
+ * @link http://www.php.net/manual/en/function.fseek.php
+ * @param int $offset Stream offset
+ * @param int $whence Specifies how the cursor position will be calculated
+ * based on the seek offset. Valid values are identical to the built-in
+ * PHP $whence values for `fseek()`. SEEK_SET: Set position equal to
+ * offset bytes SEEK_CUR: Set position to current location plus offset
+ * SEEK_END: Set position to end-of-stream plus offset.
+ * @throws \RuntimeException on failure.
+ */
+ public function seek($offset, $whence = SEEK_SET);
+
+ /**
+ * Seek to the beginning of the stream.
+ *
+ * If the stream is not seekable, this method will raise an exception;
+ * otherwise, it will perform a seek(0).
+ *
+ * @see seek()
+ * @link http://www.php.net/manual/en/function.fseek.php
+ * @throws \RuntimeException on failure.
+ */
+ public function rewind();
+
+ /**
+ * Returns whether or not the stream is writable.
+ *
+ * @return bool
+ */
+ public function isWritable();
+
+ /**
+ * Write data to the stream.
+ *
+ * @param string $string The string that is to be written.
+ * @return int Returns the number of bytes written to the stream.
+ * @throws \RuntimeException on failure.
+ */
+ public function write($string);
+
+ /**
+ * Returns whether or not the stream is readable.
+ *
+ * @return bool
+ */
+ public function isReadable();
+
+ /**
+ * Read data from the stream.
+ *
+ * @param int $length Read up to $length bytes from the object and return
+ * them. Fewer than $length bytes may be returned if underlying stream
+ * call returns fewer bytes.
+ * @return string Returns the data read from the stream, or an empty string
+ * if no bytes are available.
+ * @throws \RuntimeException if an error occurs.
+ */
+ public function read($length);
+
+ /**
+ * Returns the remaining contents in a string
+ *
+ * @return string
+ * @throws \RuntimeException if unable to read or an error occurs while
+ * reading.
+ */
+ public function getContents();
+
+ /**
+ * Get stream metadata as an associative array or retrieve a specific key.
+ *
+ * The keys returned are identical to the keys returned from PHP's
+ * stream_get_meta_data() function.
+ *
+ * @link http://php.net/manual/en/function.stream-get-meta-data.php
+ * @param string $key Specific metadata to retrieve.
+ * @return array|mixed|null Returns an associative array if no key is
+ * provided. Returns a specific key value if a key is provided and the
+ * value is found, or null if the key is not found.
+ */
+ public function getMetadata($key = null);
+}
diff --git a/vendor/psr/http-message/src/UploadedFileInterface.php b/vendor/psr/http-message/src/UploadedFileInterface.php
new file mode 100644
index 0000000..f8a6901
--- /dev/null
+++ b/vendor/psr/http-message/src/UploadedFileInterface.php
@@ -0,0 +1,123 @@
+<?php
+
+namespace Psr\Http\Message;
+
+/**
+ * Value object representing a file uploaded through an HTTP request.
+ *
+ * Instances of this interface are considered immutable; all methods that
+ * might change state MUST be implemented such that they retain the internal
+ * state of the current instance and return an instance that contains the
+ * changed state.
+ */
+interface UploadedFileInterface
+{
+ /**
+ * Retrieve a stream representing the uploaded file.
+ *
+ * This method MUST return a StreamInterface instance, representing the
+ * uploaded file. The purpose of this method is to allow utilizing native PHP
+ * stream functionality to manipulate the file upload, such as
+ * stream_copy_to_stream() (though the result will need to be decorated in a
+ * native PHP stream wrapper to work with such functions).
+ *
+ * If the moveTo() method has been called previously, this method MUST raise
+ * an exception.
+ *
+ * @return StreamInterface Stream representation of the uploaded file.
+ * @throws \RuntimeException in cases when no stream is available or can be
+ * created.
+ */
+ public function getStream();
+
+ /**
+ * Move the uploaded file to a new location.
+ *
+ * Use this method as an alternative to move_uploaded_file(). This method is
+ * guaranteed to work in both SAPI and non-SAPI environments.
+ * Implementations must determine which environment they are in, and use the
+ * appropriate method (move_uploaded_file(), rename(), or a stream
+ * operation) to perform the operation.
+ *
+ * $targetPath may be an absolute path, or a relative path. If it is a
+ * relative path, resolution should be the same as used by PHP's rename()
+ * function.
+ *
+ * The original file or stream MUST be removed on completion.
+ *
+ * If this method is called more than once, any subsequent calls MUST raise
+ * an exception.
+ *
+ * When used in an SAPI environment where $_FILES is populated, when writing
+ * files via moveTo(), is_uploaded_file() and move_uploaded_file() SHOULD be
+ * used to ensure permissions and upload status are verified correctly.
+ *
+ * If you wish to move to a stream, use getStream(), as SAPI operations
+ * cannot guarantee writing to stream destinations.
+ *
+ * @see http://php.net/is_uploaded_file
+ * @see http://php.net/move_uploaded_file
+ * @param string $targetPath Path to which to move the uploaded file.
+ * @throws \InvalidArgumentException if the $targetPath specified is invalid.
+ * @throws \RuntimeException on any error during the move operation, or on
+ * the second or subsequent call to the method.
+ */
+ public function moveTo($targetPath);
+
+ /**
+ * Retrieve the file size.
+ *
+ * Implementations SHOULD return the value stored in the "size" key of
+ * the file in the $_FILES array if available, as PHP calculates this based
+ * on the actual size transmitted.
+ *
+ * @return int|null The file size in bytes or null if unknown.
+ */
+ public function getSize();
+
+ /**
+ * Retrieve the error associated with the uploaded file.
+ *
+ * The return value MUST be one of PHP's UPLOAD_ERR_XXX constants.
+ *
+ * If the file was uploaded successfully, this method MUST return
+ * UPLOAD_ERR_OK.
+ *
+ * Implementations SHOULD return the value stored in the "error" key of
+ * the file in the $_FILES array.
+ *
+ * @see http://php.net/manual/en/features.file-upload.errors.php
+ * @return int One of PHP's UPLOAD_ERR_XXX constants.
+ */
+ public function getError();
+
+ /**
+ * Retrieve the filename sent by the client.
+ *
+ * Do not trust the value returned by this method. A client could send
+ * a malicious filename with the intention to corrupt or hack your
+ * application.
+ *
+ * Implementations SHOULD return the value stored in the "name" key of
+ * the file in the $_FILES array.
+ *
+ * @return string|null The filename sent by the client or null if none
+ * was provided.
+ */
+ public function getClientFilename();
+
+ /**
+ * Retrieve the media type sent by the client.
+ *
+ * Do not trust the value returned by this method. A client could send
+ * a malicious media type with the intention to corrupt or hack your
+ * application.
+ *
+ * Implementations SHOULD return the value stored in the "type" key of
+ * the file in the $_FILES array.
+ *
+ * @return string|null The media type sent by the client or null if none
+ * was provided.
+ */
+ public function getClientMediaType();
+}
diff --git a/vendor/psr/http-message/src/UriInterface.php b/vendor/psr/http-message/src/UriInterface.php
new file mode 100644
index 0000000..9d7ab9e
--- /dev/null
+++ b/vendor/psr/http-message/src/UriInterface.php
@@ -0,0 +1,323 @@
+<?php
+namespace Psr\Http\Message;
+
+/**
+ * Value object representing a URI.
+ *
+ * This interface is meant to represent URIs according to RFC 3986 and to
+ * provide methods for most common operations. Additional functionality for
+ * working with URIs can be provided on top of the interface or externally.
+ * Its primary use is for HTTP requests, but may also be used in other
+ * contexts.
+ *
+ * Instances of this interface are considered immutable; all methods that
+ * might change state MUST be implemented such that they retain the internal
+ * state of the current instance and return an instance that contains the
+ * changed state.
+ *
+ * Typically the Host header will be also be present in the request message.
+ * For server-side requests, the scheme will typically be discoverable in the
+ * server parameters.
+ *
+ * @link http://tools.ietf.org/html/rfc3986 (the URI specification)
+ */
+interface UriInterface
+{
+ /**
+ * Retrieve the scheme component of the URI.
+ *
+ * If no scheme is present, this method MUST return an empty string.
+ *
+ * The value returned MUST be normalized to lowercase, per RFC 3986
+ * Section 3.1.
+ *
+ * The trailing ":" character is not part of the scheme and MUST NOT be
+ * added.
+ *
+ * @see https://tools.ietf.org/html/rfc3986#section-3.1
+ * @return string The URI scheme.
+ */
+ public function getScheme();
+
+ /**
+ * Retrieve the authority component of the URI.
+ *
+ * If no authority information is present, this method MUST return an empty
+ * string.
+ *
+ * The authority syntax of the URI is:
+ *
+ * <pre>
+ * [user-info@]host[:port]
+ * </pre>
+ *
+ * If the port component is not set or is the standard port for the current
+ * scheme, it SHOULD NOT be included.
+ *
+ * @see https://tools.ietf.org/html/rfc3986#section-3.2
+ * @return string The URI authority, in "[user-info@]host[:port]" format.
+ */
+ public function getAuthority();
+
+ /**
+ * Retrieve the user information component of the URI.
+ *
+ * If no user information is present, this method MUST return an empty
+ * string.
+ *
+ * If a user is present in the URI, this will return that value;
+ * additionally, if the password is also present, it will be appended to the
+ * user value, with a colon (":") separating the values.
+ *
+ * The trailing "@" character is not part of the user information and MUST
+ * NOT be added.
+ *
+ * @return string The URI user information, in "username[:password]" format.
+ */
+ public function getUserInfo();
+
+ /**
+ * Retrieve the host component of the URI.
+ *
+ * If no host is present, this method MUST return an empty string.
+ *
+ * The value returned MUST be normalized to lowercase, per RFC 3986
+ * Section 3.2.2.
+ *
+ * @see http://tools.ietf.org/html/rfc3986#section-3.2.2
+ * @return string The URI host.
+ */
+ public function getHost();
+
+ /**
+ * Retrieve the port component of the URI.
+ *
+ * If a port is present, and it is non-standard for the current scheme,
+ * this method MUST return it as an integer. If the port is the standard port
+ * used with the current scheme, this method SHOULD return null.
+ *
+ * If no port is present, and no scheme is present, this method MUST return
+ * a null value.
+ *
+ * If no port is present, but a scheme is present, this method MAY return
+ * the standard port for that scheme, but SHOULD return null.
+ *
+ * @return null|int The URI port.
+ */
+ public function getPort();
+
+ /**
+ * Retrieve the path component of the URI.
+ *
+ * The path can either be empty or absolute (starting with a slash) or
+ * rootless (not starting with a slash). Implementations MUST support all
+ * three syntaxes.
+ *
+ * Normally, the empty path "" and absolute path "/" are considered equal as
+ * defined in RFC 7230 Section 2.7.3. But this method MUST NOT automatically
+ * do this normalization because in contexts with a trimmed base path, e.g.
+ * the front controller, this difference becomes significant. It's the task
+ * of the user to handle both "" and "/".
+ *
+ * The value returned MUST be percent-encoded, but MUST NOT double-encode
+ * any characters. To determine what characters to encode, please refer to
+ * RFC 3986, Sections 2 and 3.3.
+ *
+ * As an example, if the value should include a slash ("/") not intended as
+ * delimiter between path segments, that value MUST be passed in encoded
+ * form (e.g., "%2F") to the instance.
+ *
+ * @see https://tools.ietf.org/html/rfc3986#section-2
+ * @see https://tools.ietf.org/html/rfc3986#section-3.3
+ * @return string The URI path.
+ */
+ public function getPath();
+
+ /**
+ * Retrieve the query string of the URI.
+ *
+ * If no query string is present, this method MUST return an empty string.
+ *
+ * The leading "?" character is not part of the query and MUST NOT be
+ * added.
+ *
+ * The value returned MUST be percent-encoded, but MUST NOT double-encode
+ * any characters. To determine what characters to encode, please refer to
+ * RFC 3986, Sections 2 and 3.4.
+ *
+ * As an example, if a value in a key/value pair of the query string should
+ * include an ampersand ("&") not intended as a delimiter between values,
+ * that value MUST be passed in encoded form (e.g., "%26") to the instance.
+ *
+ * @see https://tools.ietf.org/html/rfc3986#section-2
+ * @see https://tools.ietf.org/html/rfc3986#section-3.4
+ * @return string The URI query string.
+ */
+ public function getQuery();
+
+ /**
+ * Retrieve the fragment component of the URI.
+ *
+ * If no fragment is present, this method MUST return an empty string.
+ *
+ * The leading "#" character is not part of the fragment and MUST NOT be
+ * added.
+ *
+ * The value returned MUST be percent-encoded, but MUST NOT double-encode
+ * any characters. To determine what characters to encode, please refer to
+ * RFC 3986, Sections 2 and 3.5.
+ *
+ * @see https://tools.ietf.org/html/rfc3986#section-2
+ * @see https://tools.ietf.org/html/rfc3986#section-3.5
+ * @return string The URI fragment.
+ */
+ public function getFragment();
+
+ /**
+ * Return an instance with the specified scheme.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified scheme.
+ *
+ * Implementations MUST support the schemes "http" and "https" case
+ * insensitively, and MAY accommodate other schemes if required.
+ *
+ * An empty scheme is equivalent to removing the scheme.
+ *
+ * @param string $scheme The scheme to use with the new instance.
+ * @return static A new instance with the specified scheme.
+ * @throws \InvalidArgumentException for invalid or unsupported schemes.
+ */
+ public function withScheme($scheme);
+
+ /**
+ * Return an instance with the specified user information.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified user information.
+ *
+ * Password is optional, but the user information MUST include the
+ * user; an empty string for the user is equivalent to removing user
+ * information.
+ *
+ * @param string $user The user name to use for authority.
+ * @param null|string $password The password associated with $user.
+ * @return static A new instance with the specified user information.
+ */
+ public function withUserInfo($user, $password = null);
+
+ /**
+ * Return an instance with the specified host.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified host.
+ *
+ * An empty host value is equivalent to removing the host.
+ *
+ * @param string $host The hostname to use with the new instance.
+ * @return static A new instance with the specified host.
+ * @throws \InvalidArgumentException for invalid hostnames.
+ */
+ public function withHost($host);
+
+ /**
+ * Return an instance with the specified port.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified port.
+ *
+ * Implementations MUST raise an exception for ports outside the
+ * established TCP and UDP port ranges.
+ *
+ * A null value provided for the port is equivalent to removing the port
+ * information.
+ *
+ * @param null|int $port The port to use with the new instance; a null value
+ * removes the port information.
+ * @return static A new instance with the specified port.
+ * @throws \InvalidArgumentException for invalid ports.
+ */
+ public function withPort($port);
+
+ /**
+ * Return an instance with the specified path.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified path.
+ *
+ * The path can either be empty or absolute (starting with a slash) or
+ * rootless (not starting with a slash). Implementations MUST support all
+ * three syntaxes.
+ *
+ * If the path is intended to be domain-relative rather than path relative then
+ * it must begin with a slash ("/"). Paths not starting with a slash ("/")
+ * are assumed to be relative to some base path known to the application or
+ * consumer.
+ *
+ * Users can provide both encoded and decoded path characters.
+ * Implementations ensure the correct encoding as outlined in getPath().
+ *
+ * @param string $path The path to use with the new instance.
+ * @return static A new instance with the specified path.
+ * @throws \InvalidArgumentException for invalid paths.
+ */
+ public function withPath($path);
+
+ /**
+ * Return an instance with the specified query string.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified query string.
+ *
+ * Users can provide both encoded and decoded query characters.
+ * Implementations ensure the correct encoding as outlined in getQuery().
+ *
+ * An empty query string value is equivalent to removing the query string.
+ *
+ * @param string $query The query string to use with the new instance.
+ * @return static A new instance with the specified query string.
+ * @throws \InvalidArgumentException for invalid query strings.
+ */
+ public function withQuery($query);
+
+ /**
+ * Return an instance with the specified URI fragment.
+ *
+ * This method MUST retain the state of the current instance, and return
+ * an instance that contains the specified URI fragment.
+ *
+ * Users can provide both encoded and decoded fragment characters.
+ * Implementations ensure the correct encoding as outlined in getFragment().
+ *
+ * An empty fragment value is equivalent to removing the fragment.
+ *
+ * @param string $fragment The fragment to use with the new instance.
+ * @return static A new instance with the specified fragment.
+ */
+ public function withFragment($fragment);
+
+ /**
+ * Return the string representation as a URI reference.
+ *
+ * Depending on which components of the URI are present, the resulting
+ * string is either a full URI or relative reference according to RFC 3986,
+ * Section 4.1. The method concatenates the various components of the URI,
+ * using the appropriate delimiters:
+ *
+ * - If a scheme is present, it MUST be suffixed by ":".
+ * - If an authority is present, it MUST be prefixed by "//".
+ * - The path can be concatenated without delimiters. But there are two
+ * cases where the path has to be adjusted to make the URI reference
+ * valid as PHP does not allow to throw an exception in __toString():
+ * - If the path is rootless and an authority is present, the path MUST
+ * be prefixed by "/".
+ * - If the path is starting with more than one "/" and no authority is
+ * present, the starting slashes MUST be reduced to one.
+ * - If a query is present, it MUST be prefixed by "?".
+ * - If a fragment is present, it MUST be prefixed by "#".
+ *
+ * @see http://tools.ietf.org/html/rfc3986#section-4.1
+ * @return string
+ */
+ public function __toString();
+}
diff --git a/vendor/sebastian/code-unit-reverse-lookup/.gitignore b/vendor/sebastian/code-unit-reverse-lookup/.gitignore
new file mode 100644
index 0000000..9e5f1db
--- /dev/null
+++ b/vendor/sebastian/code-unit-reverse-lookup/.gitignore
@@ -0,0 +1,4 @@
+/.idea
+/composer.lock
+/vendor
+
diff --git a/vendor/sebastian/code-unit-reverse-lookup/.php_cs b/vendor/sebastian/code-unit-reverse-lookup/.php_cs
new file mode 100644
index 0000000..b7393bd
--- /dev/null
+++ b/vendor/sebastian/code-unit-reverse-lookup/.php_cs
@@ -0,0 +1,67 @@
+<?php
+$finder = Symfony\CS\Finder\DefaultFinder::create()
+ ->files()
+ ->in('src')
+ ->in('tests')
+ ->name('*.php');
+
+return Symfony\CS\Config\Config::create()
+ ->level(\Symfony\CS\FixerInterface::NONE_LEVEL)
+ ->fixers(
+ array(
+ 'align_double_arrow',
+ 'align_equals',
+ 'braces',
+ 'concat_with_spaces',
+ 'duplicate_semicolon',
+ 'elseif',
+ 'empty_return',
+ 'encoding',
+ 'eof_ending',
+ 'extra_empty_lines',
+ 'function_call_space',
+ 'function_declaration',
+ 'indentation',
+ 'join_function',
+ 'line_after_namespace',
+ 'linefeed',
+ 'list_commas',
+ 'lowercase_constants',
+ 'lowercase_keywords',
+ 'method_argument_space',
+ 'multiple_use',
+ 'namespace_no_leading_whitespace',
+ 'no_blank_lines_after_class_opening',
+ 'no_empty_lines_after_phpdocs',
+ 'parenthesis',
+ 'php_closing_tag',
+ 'phpdoc_indent',
+ 'phpdoc_no_access',
+ 'phpdoc_no_empty_return',
+ 'phpdoc_no_package',
+ 'phpdoc_params',
+ 'phpdoc_scalar',
+ 'phpdoc_separation',
+ 'phpdoc_to_comment',
+ 'phpdoc_trim',
+ 'phpdoc_types',
+ 'phpdoc_var_without_name',
+ 'remove_lines_between_uses',
+ 'return',
+ 'self_accessor',
+ 'short_array_syntax',
+ 'short_tag',
+ 'single_line_after_imports',
+ 'single_quote',
+ 'spaces_before_semicolon',
+ 'spaces_cast',
+ 'ternary_spaces',
+ 'trailing_spaces',
+ 'trim_array_spaces',
+ 'unused_use',
+ 'visibility',
+ 'whitespacy_lines'
+ )
+ )
+ ->finder($finder);
+
diff --git a/vendor/sebastian/code-unit-reverse-lookup/.travis.yml b/vendor/sebastian/code-unit-reverse-lookup/.travis.yml
new file mode 100644
index 0000000..9d9c9d9
--- /dev/null
+++ b/vendor/sebastian/code-unit-reverse-lookup/.travis.yml
@@ -0,0 +1,25 @@
+language: php
+
+php:
+ - 5.6
+ - 7.0
+ - 7.0snapshot
+ - 7.1
+ - 7.1snapshot
+ - master
+
+sudo: false
+
+before_install:
+ - composer self-update
+ - composer clear-cache
+
+install:
+ - travis_retry composer update --no-interaction --no-ansi --no-progress --no-suggest --optimize-autoloader --prefer-stable
+
+script:
+ - ./vendor/bin/phpunit
+
+notifications:
+ email: false
+
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 0000000..6da1003
--- /dev/null
+++ b/vendor/sebastian/code-unit-reverse-lookup/ChangeLog.md
@@ -0,0 +1,10 @@
+# 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.
+
+## 1.0.0 - 2016-02-13
+
+### Added
+
+* Initial release
+
diff --git a/vendor/sebastian/code-unit-reverse-lookup/LICENSE b/vendor/sebastian/code-unit-reverse-lookup/LICENSE
new file mode 100644
index 0000000..8f24384
--- /dev/null
+++ b/vendor/sebastian/code-unit-reverse-lookup/LICENSE
@@ -0,0 +1,33 @@
+code-unit-reverse-lookup
+
+Copyright (c) 2016-2017, Sebastian Bergmann <sebastian@phpunit.de>.
+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 0000000..2bf26af
--- /dev/null
+++ b/vendor/sebastian/code-unit-reverse-lookup/README.md
@@ -0,0 +1,14 @@
+# 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/build.xml b/vendor/sebastian/code-unit-reverse-lookup/build.xml
new file mode 100644
index 0000000..24cf32e
--- /dev/null
+++ b/vendor/sebastian/code-unit-reverse-lookup/build.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="code-unit-reverse-lookup" default="setup">
+ <target name="setup" depends="clean,composer"/>
+
+ <target name="clean" description="Cleanup build artifacts">
+ <delete dir="${basedir}/vendor"/>
+ <delete file="${basedir}/composer.lock"/>
+ </target>
+
+ <target name="composer" depends="clean" description="Install dependencies with Composer">
+ <exec executable="composer" taskname="composer">
+ <arg value="update"/>
+ <arg value="--no-interaction"/>
+ <arg value="--no-progress"/>
+ <arg value="--no-ansi"/>
+ <arg value="--no-suggest"/>
+ <arg value="--optimize-autoloader"/>
+ <arg value="--prefer-stable"/>
+ </exec>
+ </target>
+</project>
+
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 0000000..b9a2419
--- /dev/null
+++ b/vendor/sebastian/code-unit-reverse-lookup/composer.json
@@ -0,0 +1,28 @@
+{
+ "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": "sebastian@phpunit.de"
+ }
+ ],
+ "require": {
+ "php": "^5.6 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7 || ^6.0"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/code-unit-reverse-lookup/phpunit.xml b/vendor/sebastian/code-unit-reverse-lookup/phpunit.xml
new file mode 100644
index 0000000..2c0569e
--- /dev/null
+++ b/vendor/sebastian/code-unit-reverse-lookup/phpunit.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/5.4/phpunit.xsd"
+ bootstrap="vendor/autoload.php"
+ backupGlobals="false"
+ backupStaticAttributes="false"
+ beStrictAboutCoversAnnotation="true"
+ beStrictAboutOutputDuringTests="true"
+ beStrictAboutTestsThatDoNotTestAnything="true"
+ beStrictAboutTodoAnnotatedTests="true"
+ verbose="true">
+ <testsuite>
+ <directory suffix="Test.php">tests</directory>
+ </testsuite>
+
+ <filter>
+ <whitelist processUncoveredFilesFromWhitelist="true">
+ <directory suffix=".php">src</directory>
+ </whitelist>
+ </filter>
+</phpunit>
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 0000000..20f8880
--- /dev/null
+++ b/vendor/sebastian/code-unit-reverse-lookup/src/Wizard.php
@@ -0,0 +1,111 @@
+<?php
+/*
+ * This file is part of code-unit-reverse-lookup.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeUnitReverseLookup;
+
+/**
+ * @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];
+ } else {
+ return $filename . ':' . $lineNumber;
+ }
+ }
+
+ private function updateLookupTable()
+ {
+ $this->processClassesAndTraits();
+ $this->processFunctions();
+ }
+
+ private function processClassesAndTraits()
+ {
+ foreach (array_merge(get_declared_classes(), get_declared_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()
+ {
+ foreach (get_defined_functions()['user'] as $function) {
+ if (isset($this->processedFunctions[$function])) {
+ continue;
+ }
+
+ $this->processFunctionOrMethod(new \ReflectionFunction($function));
+
+ $this->processedFunctions[$function] = true;
+ }
+ }
+
+ /**
+ * @param \ReflectionFunctionAbstract $functionOrMethod
+ */
+ private function processFunctionOrMethod(\ReflectionFunctionAbstract $functionOrMethod)
+ {
+ 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-reverse-lookup/tests/WizardTest.php b/vendor/sebastian/code-unit-reverse-lookup/tests/WizardTest.php
new file mode 100644
index 0000000..84d0ac3
--- /dev/null
+++ b/vendor/sebastian/code-unit-reverse-lookup/tests/WizardTest.php
@@ -0,0 +1,45 @@
+<?php
+/*
+ * This file is part of code-unit-reverse-lookup.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\CodeUnitReverseLookup;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers SebastianBergmann\CodeUnitReverseLookup\Wizard
+ */
+class WizardTest extends TestCase
+{
+ /**
+ * @var Wizard
+ */
+ private $wizard;
+
+ protected function setUp()
+ {
+ $this->wizard = new Wizard;
+ }
+
+ public function testMethodCanBeLookedUp()
+ {
+ $this->assertEquals(
+ __METHOD__,
+ $this->wizard->lookup(__FILE__, __LINE__)
+ );
+ }
+
+ public function testReturnsFilenameAndLineNumberAsStringWhenNotInCodeUnit()
+ {
+ $this->assertEquals(
+ 'file.php:1',
+ $this->wizard->lookup('file.php', 1)
+ );
+ }
+}
diff --git a/vendor/sebastian/comparator/.gitignore b/vendor/sebastian/comparator/.gitignore
new file mode 100644
index 0000000..c2990fc
--- /dev/null
+++ b/vendor/sebastian/comparator/.gitignore
@@ -0,0 +1,6 @@
+/build/coverage
+/composer.lock
+/composer.phar
+/phpunit.xml
+/.idea
+/vendor
diff --git a/vendor/sebastian/comparator/.travis.yml b/vendor/sebastian/comparator/.travis.yml
new file mode 100644
index 0000000..082370f
--- /dev/null
+++ b/vendor/sebastian/comparator/.travis.yml
@@ -0,0 +1,25 @@
+language: php
+
+sudo: false
+
+install:
+ - travis_retry composer install --no-interaction --prefer-source
+
+script: ./vendor/bin/phpunit --configuration ./build/travis-ci.xml
+
+php:
+ - 5.3.3
+ - 5.3
+ - 5.4
+ - 5.5
+ - 5.6
+ - hhvm
+
+notifications:
+ email: false
+ webhooks:
+ urls:
+ - https://webhooks.gitter.im/e/6668f52f3dd4e3f81960
+ on_success: always
+ on_failure: always
+ on_start: false
diff --git a/vendor/sebastian/comparator/LICENSE b/vendor/sebastian/comparator/LICENSE
new file mode 100644
index 0000000..334b637
--- /dev/null
+++ b/vendor/sebastian/comparator/LICENSE
@@ -0,0 +1,33 @@
+Comparator
+
+Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
+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 0000000..2409c34
--- /dev/null
+++ b/vendor/sebastian/comparator/README.md
@@ -0,0 +1,39 @@
+[![Build Status](https://travis-ci.org/sebastianbergmann/comparator.svg?branch=master)](https://travis-ci.org/sebastianbergmann/comparator)
+
+# 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/build.xml b/vendor/sebastian/comparator/build.xml
new file mode 100644
index 0000000..552ebce
--- /dev/null
+++ b/vendor/sebastian/comparator/build.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="comparator">
+ <target name="clean" description="Cleanup build artifacts">
+ <delete dir="${basedir}/vendor"/>
+ <delete file="${basedir}/composer.lock"/>
+ </target>
+
+ <target name="composer" depends="clean" description="Install dependencies with Composer">
+ <tstamp>
+ <format property="thirty.days.ago" pattern="MM/dd/yyyy hh:mm aa" offset="-30" unit="day"/>
+ </tstamp>
+ <delete>
+ <fileset dir="${basedir}">
+ <include name="composer.phar" />
+ <date datetime="${thirty.days.ago}" when="before"/>
+ </fileset>
+ </delete>
+
+ <get src="https://getcomposer.org/composer.phar" dest="${basedir}/composer.phar" skipexisting="true"/>
+
+ <exec executable="php">
+ <arg value="composer.phar"/>
+ <arg value="install"/>
+ </exec>
+ </target>
+
+ <target name="phpab" description="Generate autoloader script">
+ <exec executable="phpab">
+ <arg value="--output" />
+ <arg path="tests/autoload.php" />
+ <arg path="tests" />
+ </exec>
+ </target>
+</project>
diff --git a/vendor/sebastian/comparator/build/travis-ci.xml b/vendor/sebastian/comparator/build/travis-ci.xml
new file mode 100644
index 0000000..751a3bc
--- /dev/null
+++ b/vendor/sebastian/comparator/build/travis-ci.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.2/phpunit.xsd"
+ bootstrap="../tests/bootstrap.php"
+ backupGlobals="false"
+ verbose="true">
+ <testsuite name="Comparator">
+ <directory suffix="Test.php">../tests</directory>
+ </testsuite>
+</phpunit>
+
diff --git a/vendor/sebastian/comparator/composer.json b/vendor/sebastian/comparator/composer.json
new file mode 100644
index 0000000..38db40e
--- /dev/null
+++ b/vendor/sebastian/comparator/composer.json
@@ -0,0 +1,44 @@
+{
+ "name": "sebastian/comparator",
+ "description": "Provides the functionality to compare PHP values for equality",
+ "keywords": ["comparator","compare","equality"],
+ "homepage": "http://www.github.com/sebastianbergmann/comparator",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3",
+ "sebastian/diff": "~1.2",
+ "sebastian/exporter": "~1.2 || ~2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ }
+}
+
diff --git a/vendor/sebastian/comparator/phpunit.xml.dist b/vendor/sebastian/comparator/phpunit.xml.dist
new file mode 100644
index 0000000..e1eaf2c
--- /dev/null
+++ b/vendor/sebastian/comparator/phpunit.xml.dist
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+ bootstrap="tests/bootstrap.php"
+ backupGlobals="false"
+ verbose="true">
+ <testsuite name="Comparator">
+ <directory suffix="Test.php">tests</directory>
+ </testsuite>
+
+ <logging>
+ <log type="coverage-html" target="build/coverage"/>
+ </logging>
+
+ <filter>
+ <whitelist processUncoveredFilesFromWhitelist="true">
+ <directory suffix=".php">src</directory>
+ </whitelist>
+ </filter>
+</phpunit>
+
diff --git a/vendor/sebastian/comparator/src/ArrayComparator.php b/vendor/sebastian/comparator/src/ArrayComparator.php
new file mode 100644
index 0000000..16f805d
--- /dev/null
+++ b/vendor/sebastian/comparator/src/ArrayComparator.php
@@ -0,0 +1,132 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * Compares arrays for equality.
+ */
+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 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 = array())
+ {
+ if ($canonicalize) {
+ sort($expected);
+ sort($actual);
+ }
+
+ $remaining = $actual;
+ $expString = $actString = "Array (\n";
+ $equal = true;
+
+ foreach ($expected as $key => $value) {
+ unset($remaining[$key]);
+
+ if (!array_key_exists($key, $actual)) {
+ $expString .= 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);
+
+ $expString .= sprintf(
+ " %s => %s\n",
+ $this->exporter->export($key),
+ $this->exporter->shortenedExport($value)
+ );
+ $actString .= sprintf(
+ " %s => %s\n",
+ $this->exporter->export($key),
+ $this->exporter->shortenedExport($actual[$key])
+ );
+ } catch (ComparisonFailure $e) {
+ $expString .= sprintf(
+ " %s => %s\n",
+ $this->exporter->export($key),
+ $e->getExpectedAsString()
+ ? $this->indent($e->getExpectedAsString())
+ : $this->exporter->shortenedExport($e->getExpected())
+ );
+
+ $actString .= 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) {
+ $actString .= sprintf(
+ " %s => %s\n",
+ $this->exporter->export($key),
+ $this->exporter->shortenedExport($value)
+ );
+
+ $equal = false;
+ }
+
+ $expString .= ')';
+ $actString .= ')';
+
+ if (!$equal) {
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ $expString,
+ $actString,
+ 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 0000000..5483167
--- /dev/null
+++ b/vendor/sebastian/comparator/src/Comparator.php
@@ -0,0 +1,64 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * 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;
+ }
+
+ /**
+ * @param Factory $factory
+ */
+ public function setFactory(Factory $factory)
+ {
+ $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 0000000..2c25453
--- /dev/null
+++ b/vendor/sebastian/comparator/src/ComparisonFailure.php
@@ -0,0 +1,129 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+use SebastianBergmann\Diff\Differ;
+
+/**
+ * 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;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getActual()
+ {
+ return $this->actual;
+ }
+
+ /**
+ * @return mixed
+ */
+ 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("\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 0000000..db624b7
--- /dev/null
+++ b/vendor/sebastian/comparator/src/DOMNodeComparator.php
@@ -0,0 +1,107 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+use DOMDocument;
+use DOMNode;
+
+/**
+ * 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 = array())
+ {
+ $expectedAsString = $this->nodeToText($expected, true, $ignoreCase);
+ $actualAsString = $this->nodeToText($actual, true, $ignoreCase);
+
+ if ($expectedAsString !== $actualAsString) {
+ if ($expected instanceof DOMDocument) {
+ $type = 'documents';
+ } else {
+ $type = '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.
+ *
+ * @param DOMNode $node
+ * @param bool $canonicalize
+ * @param bool $ignoreCase
+ * @return string
+ */
+ private function nodeToText(DOMNode $node, $canonicalize, $ignoreCase)
+ {
+ if ($canonicalize) {
+ $document = new DOMDocument;
+ $document->loadXML($node->C14N());
+
+ $node = $document;
+ }
+
+ if ($node instanceof DOMDocument) {
+ $document = $node;
+ } else {
+ $document = $node->ownerDocument;
+ }
+
+ $document->formatOutput = true;
+ $document->normalizeDocument();
+
+ if ($node instanceof DOMDocument) {
+ $text = $node->saveXML();
+ } else {
+ $text = $document->saveXML($node);
+ }
+
+ if ($ignoreCase) {
+ $text = strtolower($text);
+ }
+
+ return $text;
+ }
+}
diff --git a/vendor/sebastian/comparator/src/DateTimeComparator.php b/vendor/sebastian/comparator/src/DateTimeComparator.php
new file mode 100644
index 0000000..f9a1f2c
--- /dev/null
+++ b/vendor/sebastian/comparator/src/DateTimeComparator.php
@@ -0,0 +1,77 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * 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 ComparisonFailure
+ */
+ public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array())
+ {
+ $delta = new \DateInterval(sprintf('PT%sS', abs($delta)));
+
+ $expectedLower = clone $expected;
+ $expectedUpper = clone $expected;
+
+ if ($actual < $expectedLower->sub($delta) ||
+ $actual > $expectedUpper->add($delta)) {
+ 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.
+ *
+ * @param \DateTimeInterface $datetime
+ * @return string
+ */
+ private function dateTimeToString($datetime)
+ {
+ $string = $datetime->format('Y-m-d\TH:i:s.uO');
+
+ return $string ? $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 0000000..7f7501e
--- /dev/null
+++ b/vendor/sebastian/comparator/src/DoubleComparator.php
@@ -0,0 +1,56 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * Compares doubles for equality.
+ */
+class DoubleComparator extends NumericComparator
+{
+ /**
+ * Smallest value available in PHP.
+ *
+ * @var float
+ */
+ 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_double($expected) || is_double($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)
+ {
+ 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 0000000..5233646
--- /dev/null
+++ b/vendor/sebastian/comparator/src/ExceptionComparator.php
@@ -0,0 +1,51 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * 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 0000000..ed3d5e1
--- /dev/null
+++ b/vendor/sebastian/comparator/src/Factory.php
@@ -0,0 +1,107 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * Factory for comparators which compare values for equality.
+ */
+class Factory
+{
+ /**
+ * @var Comparator[]
+ */
+ private $comparators = array();
+
+ /**
+ * @var Factory
+ */
+ private static $instance;
+
+ /**
+ * Constructs a new factory.
+ */
+ public function __construct()
+ {
+ $this->register(new TypeComparator);
+ $this->register(new ScalarComparator);
+ $this->register(new NumericComparator);
+ $this->register(new DoubleComparator);
+ $this->register(new ArrayComparator);
+ $this->register(new ResourceComparator);
+ $this->register(new ObjectComparator);
+ $this->register(new ExceptionComparator);
+ $this->register(new SplObjectStorageComparator);
+ $this->register(new DOMNodeComparator);
+ $this->register(new MockObjectComparator);
+ $this->register(new DateTimeComparator);
+ }
+
+ /**
+ * @return Factory
+ */
+ public static function getInstance()
+ {
+ if (self::$instance === null) {
+ self::$instance = new self;
+ }
+
+ return self::$instance;
+ }
+
+ /**
+ * 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->comparators as $comparator) {
+ if ($comparator->accepts($expected, $actual)) {
+ return $comparator;
+ }
+ }
+ }
+
+ /**
+ * Registers a new comparator.
+ *
+ * This comparator will be returned by getInstance() 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 tested
+ * before those of the other comparators.
+ *
+ * @param Comparator $comparator The registered comparator
+ */
+ public function register(Comparator $comparator)
+ {
+ array_unshift($this->comparators, $comparator);
+
+ $comparator->setFactory($this);
+ }
+
+ /**
+ * Unregisters a comparator.
+ *
+ * This comparator will no longer be returned by getInstance().
+ *
+ * @param Comparator $comparator The unregistered comparator
+ */
+ public function unregister(Comparator $comparator)
+ {
+ foreach ($this->comparators as $key => $_comparator) {
+ if ($comparator === $_comparator) {
+ unset($this->comparators[$key]);
+ }
+ }
+ }
+}
diff --git a/vendor/sebastian/comparator/src/MockObjectComparator.php b/vendor/sebastian/comparator/src/MockObjectComparator.php
new file mode 100644
index 0000000..a16903c
--- /dev/null
+++ b/vendor/sebastian/comparator/src/MockObjectComparator.php
@@ -0,0 +1,45 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * 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 \PHPUnit_Framework_MockObject_MockObject && $actual instanceof \PHPUnit_Framework_MockObject_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;
+ }
+} \ No newline at end of file
diff --git a/vendor/sebastian/comparator/src/NumericComparator.php b/vendor/sebastian/comparator/src/NumericComparator.php
new file mode 100644
index 0000000..3e04a83
--- /dev/null
+++ b/vendor/sebastian/comparator/src/NumericComparator.php
@@ -0,0 +1,68 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * 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_double($expected) || is_double($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)
+ {
+ if (is_infinite($actual) && is_infinite($expected)) {
+ return;
+ }
+
+ if ((is_infinite($actual) xor is_infinite($expected)) ||
+ (is_nan($actual) or is_nan($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)
+ )
+ );
+ }
+ }
+}
diff --git a/vendor/sebastian/comparator/src/ObjectComparator.php b/vendor/sebastian/comparator/src/ObjectComparator.php
new file mode 100644
index 0000000..3c00aad
--- /dev/null
+++ b/vendor/sebastian/comparator/src/ObjectComparator.php
@@ -0,0 +1,105 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * 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 = array())
+ {
+ 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(array($actual, $expected), $processed, true) ||
+ in_array(array($expected, $actual), $processed, true)) {
+ return;
+ }
+
+ $processed[] = array($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 0000000..95d649f
--- /dev/null
+++ b/vendor/sebastian/comparator/src/ResourceComparator.php
@@ -0,0 +1,52 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * 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)
+ {
+ 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 0000000..772be63
--- /dev/null
+++ b/vendor/sebastian/comparator/src/ScalarComparator.php
@@ -0,0 +1,90 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * 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)
+ {
+ $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) {
+ if (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.'
+ );
+ }
+
+ 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 0000000..2dc980f
--- /dev/null
+++ b/vendor/sebastian/comparator/src/SplObjectStorageComparator.php
@@ -0,0 +1,69 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * 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)
+ {
+ 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 0000000..73d65cf
--- /dev/null
+++ b/vendor/sebastian/comparator/src/TypeComparator.php
@@ -0,0 +1,59 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * 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)
+ {
+ 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/tests/ArrayComparatorTest.php b/vendor/sebastian/comparator/tests/ArrayComparatorTest.php
new file mode 100644
index 0000000..ee44615
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/ArrayComparatorTest.php
@@ -0,0 +1,163 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * @coversDefaultClass SebastianBergmann\Comparator\ArrayComparator
+ *
+ */
+class ArrayComparatorTest extends \PHPUnit_Framework_TestCase
+{
+ private $comparator;
+
+ protected function setUp()
+ {
+ $this->comparator = new ArrayComparator;
+ $this->comparator->setFactory(new Factory);
+ }
+
+ public function acceptsFailsProvider()
+ {
+ return array(
+ array(array(), null),
+ array(null, array()),
+ array(null, null)
+ );
+ }
+
+ public function assertEqualsSucceedsProvider()
+ {
+ return array(
+ array(
+ array('a' => 1, 'b' => 2),
+ array('b' => 2, 'a' => 1)
+ ),
+ array(
+ array(1),
+ array('1')
+ ),
+ array(
+ array(3, 2, 1),
+ array(2, 3, 1),
+ 0,
+ true
+ ),
+ array(
+ array(2.3),
+ array(2.5),
+ 0.5
+ ),
+ array(
+ array(array(2.3)),
+ array(array(2.5)),
+ 0.5
+ ),
+ array(
+ array(new Struct(2.3)),
+ array(new Struct(2.5)),
+ 0.5
+ ),
+ );
+ }
+
+ public function assertEqualsFailsProvider()
+ {
+ return array(
+ array(
+ array(),
+ array(0 => 1)
+ ),
+ array(
+ array(0 => 1),
+ array()
+ ),
+ array(
+ array(0 => null),
+ array()
+ ),
+ array(
+ array(0 => 1, 1 => 2),
+ array(0 => 1, 1 => 3)
+ ),
+ array(
+ array('a', 'b' => array(1, 2)),
+ array('a', 'b' => array(2, 1))
+ ),
+ array(
+ array(2.3),
+ array(4.2),
+ 0.5
+ ),
+ array(
+ array(array(2.3)),
+ array(array(4.2)),
+ 0.5
+ ),
+ array(
+ array(new Struct(2.3)),
+ array(new Struct(4.2)),
+ 0.5
+ )
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ */
+ public function testAcceptsSucceeds()
+ {
+ $this->assertTrue(
+ $this->comparator->accepts(array(), array())
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsFailsProvider
+ */
+ public function testAcceptsFails($expected, $actual)
+ {
+ $this->assertFalse(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsSucceedsProvider
+ */
+ public function testAssertEqualsSucceeds($expected, $actual, $delta = 0.0, $canonicalize = false)
+ {
+ $exception = null;
+
+ try {
+ $this->comparator->assertEquals($expected, $actual, $delta, $canonicalize);
+ }
+
+ catch (ComparisonFailure $exception) {
+ }
+
+ $this->assertNull($exception, 'Unexpected ComparisonFailure');
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsFailsProvider
+ */
+ public function testAssertEqualsFails($expected, $actual,$delta = 0.0, $canonicalize = false)
+ {
+ $this->setExpectedException(
+ 'SebastianBergmann\\Comparator\\ComparisonFailure',
+ 'Failed asserting that two arrays are equal'
+ );
+ $this->comparator->assertEquals($expected, $actual, $delta, $canonicalize);
+ }
+}
diff --git a/vendor/sebastian/comparator/tests/DOMNodeComparatorTest.php b/vendor/sebastian/comparator/tests/DOMNodeComparatorTest.php
new file mode 100644
index 0000000..a769b84
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/DOMNodeComparatorTest.php
@@ -0,0 +1,162 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+use DOMNode;
+use DOMDocument;
+
+/**
+ * @coversDefaultClass SebastianBergmann\Comparator\DOMNodeComparator
+ *
+ */
+class DOMNodeComparatorTest extends \PHPUnit_Framework_TestCase
+{
+ private $comparator;
+
+ protected function setUp()
+ {
+ $this->comparator = new DOMNodeComparator;
+ }
+
+ public function acceptsSucceedsProvider()
+ {
+ $document = new DOMDocument;
+ $node = new DOMNode;
+
+ return array(
+ array($document, $document),
+ array($node, $node),
+ array($document, $node),
+ array($node, $document)
+ );
+ }
+
+ public function acceptsFailsProvider()
+ {
+ $document = new DOMDocument;
+
+ return array(
+ array($document, null),
+ array(null, $document),
+ array(null, null)
+ );
+ }
+
+ public function assertEqualsSucceedsProvider()
+ {
+ return array(
+ array(
+ $this->createDOMDocument('<root></root>'),
+ $this->createDOMDocument('<root/>')
+ ),
+ array(
+ $this->createDOMDocument('<root attr="bar"></root>'),
+ $this->createDOMDocument('<root attr="bar"/>')
+ ),
+ array(
+ $this->createDOMDocument('<root><foo attr="bar"></foo></root>'),
+ $this->createDOMDocument('<root><foo attr="bar"/></root>')
+ ),
+ array(
+ $this->createDOMDocument("<root>\n <child/>\n</root>"),
+ $this->createDOMDocument('<root><child/></root>')
+ ),
+ );
+ }
+
+ public function assertEqualsFailsProvider()
+ {
+ return array(
+ array(
+ $this->createDOMDocument('<root></root>'),
+ $this->createDOMDocument('<bar/>')
+ ),
+ array(
+ $this->createDOMDocument('<foo attr1="bar"/>'),
+ $this->createDOMDocument('<foo attr1="foobar"/>')
+ ),
+ array(
+ $this->createDOMDocument('<foo> bar </foo>'),
+ $this->createDOMDocument('<foo />')
+ ),
+ array(
+ $this->createDOMDocument('<foo xmlns="urn:myns:bar"/>'),
+ $this->createDOMDocument('<foo xmlns="urn:notmyns:bar"/>')
+ ),
+ array(
+ $this->createDOMDocument('<foo> bar </foo>'),
+ $this->createDOMDocument('<foo> bir </foo>')
+ )
+ );
+ }
+
+ private function createDOMDocument($content)
+ {
+ $document = new DOMDocument;
+ $document->preserveWhiteSpace = false;
+ $document->loadXML($content);
+
+ return $document;
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsSucceedsProvider
+ */
+ public function testAcceptsSucceeds($expected, $actual)
+ {
+ $this->assertTrue(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsFailsProvider
+ */
+ public function testAcceptsFails($expected, $actual)
+ {
+ $this->assertFalse(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsSucceedsProvider
+ */
+ public function testAssertEqualsSucceeds($expected, $actual)
+ {
+ $exception = null;
+
+ try {
+ $this->comparator->assertEquals($expected, $actual);
+ }
+
+ catch (ComparisonFailure $exception) {
+ }
+
+ $this->assertNull($exception, 'Unexpected ComparisonFailure');
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsFailsProvider
+ */
+ public function testAssertEqualsFails($expected, $actual)
+ {
+ $this->setExpectedException(
+ 'SebastianBergmann\\Comparator\\ComparisonFailure',
+ 'Failed asserting that two DOM'
+ );
+ $this->comparator->assertEquals($expected, $actual);
+ }
+}
diff --git a/vendor/sebastian/comparator/tests/DateTimeComparatorTest.php b/vendor/sebastian/comparator/tests/DateTimeComparatorTest.php
new file mode 100644
index 0000000..9abcff7
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/DateTimeComparatorTest.php
@@ -0,0 +1,216 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+use DateTime;
+use DateTimeImmutable;
+use DateTimeZone;
+
+/**
+ * @coversDefaultClass SebastianBergmann\Comparator\DateTimeComparator
+ *
+ */
+class DateTimeComparatorTest extends \PHPUnit_Framework_TestCase
+{
+ private $comparator;
+
+ protected function setUp()
+ {
+ $this->comparator = new DateTimeComparator;
+ }
+
+ public function acceptsFailsProvider()
+ {
+ $datetime = new DateTime;
+
+ return array(
+ array($datetime, null),
+ array(null, $datetime),
+ array(null, null)
+ );
+ }
+
+ public function assertEqualsSucceedsProvider()
+ {
+ return array(
+ array(
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York'))
+ ),
+ array(
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 04:13:25', new DateTimeZone('America/New_York')),
+ 10
+ ),
+ array(
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 04:14:40', new DateTimeZone('America/New_York')),
+ 65
+ ),
+ array(
+ new DateTime('2013-03-29', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29', new DateTimeZone('America/New_York'))
+ ),
+ array(
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/Chicago'))
+ ),
+ array(
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 03:13:49', new DateTimeZone('America/Chicago')),
+ 15
+ ),
+ array(
+ new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 23:00:00', new DateTimeZone('America/Chicago'))
+ ),
+ array(
+ new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 23:01:30', new DateTimeZone('America/Chicago')),
+ 100
+ ),
+ array(
+ new DateTime('@1364616000'),
+ new DateTime('2013-03-29 23:00:00', new DateTimeZone('America/Chicago'))
+ ),
+ array(
+ new DateTime('2013-03-29T05:13:35-0500'),
+ new DateTime('2013-03-29T04:13:35-0600')
+ )
+ );
+ }
+
+ public function assertEqualsFailsProvider()
+ {
+ return array(
+ array(
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/New_York'))
+ ),
+ array(
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 03:13:35', new DateTimeZone('America/New_York')),
+ 3500
+ ),
+ array(
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 05:13:35', new DateTimeZone('America/New_York')),
+ 3500
+ ),
+ array(
+ new DateTime('2013-03-29', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-30', new DateTimeZone('America/New_York'))
+ ),
+ array(
+ new DateTime('2013-03-29', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
+ 43200
+ ),
+ array(
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/Chicago')),
+ ),
+ array(
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/Chicago')),
+ 3500
+ ),
+ array(
+ new DateTime('2013-03-30', new DateTimeZone('America/New_York')),
+ new DateTime('2013-03-30', new DateTimeZone('America/Chicago'))
+ ),
+ array(
+ new DateTime('2013-03-29T05:13:35-0600'),
+ new DateTime('2013-03-29T04:13:35-0600')
+ ),
+ array(
+ new DateTime('2013-03-29T05:13:35-0600'),
+ new DateTime('2013-03-29T05:13:35-0500')
+ ),
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ */
+ public function testAcceptsSucceeds()
+ {
+ $this->assertTrue(
+ $this->comparator->accepts(
+ new DateTime,
+ new DateTime
+ )
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsFailsProvider
+ */
+ public function testAcceptsFails($expected, $actual)
+ {
+ $this->assertFalse(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsSucceedsProvider
+ */
+ public function testAssertEqualsSucceeds($expected, $actual, $delta = 0.0)
+ {
+ $exception = null;
+
+ try {
+ $this->comparator->assertEquals($expected, $actual, $delta);
+ }
+
+ catch (ComparisonFailure $exception) {
+ }
+
+ $this->assertNull($exception, 'Unexpected ComparisonFailure');
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsFailsProvider
+ */
+ public function testAssertEqualsFails($expected, $actual, $delta = 0.0)
+ {
+ $this->setExpectedException(
+ 'SebastianBergmann\\Comparator\\ComparisonFailure',
+ 'Failed asserting that two DateTime objects are equal.'
+ );
+ $this->comparator->assertEquals($expected, $actual, $delta);
+ }
+
+ /**
+ * @requires PHP 5.5
+ * @covers ::accepts
+ */
+ public function testAcceptsDateTimeInterface()
+ {
+ $this->assertTrue($this->comparator->accepts(new DateTime, new DateTimeImmutable));
+ }
+
+ /**
+ * @requires PHP 5.5
+ * @covers ::assertEquals
+ */
+ public function testSupportsDateTimeInterface()
+ {
+ $this->comparator->assertEquals(
+ new DateTime('2013-03-29 04:13:35', new DateTimeZone('America/New_York')),
+ new DateTimeImmutable('2013-03-29 04:13:35', new DateTimeZone('America/New_York'))
+ );
+ }
+}
diff --git a/vendor/sebastian/comparator/tests/DoubleComparatorTest.php b/vendor/sebastian/comparator/tests/DoubleComparatorTest.php
new file mode 100644
index 0000000..6b898ba
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/DoubleComparatorTest.php
@@ -0,0 +1,134 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * @coversDefaultClass SebastianBergmann\Comparator\DoubleComparator
+ *
+ */
+class DoubleComparatorTest extends \PHPUnit_Framework_TestCase
+{
+ private $comparator;
+
+ protected function setUp()
+ {
+ $this->comparator = new DoubleComparator;
+ }
+
+ public function acceptsSucceedsProvider()
+ {
+ return array(
+ array(0, 5.0),
+ array(5.0, 0),
+ array('5', 4.5),
+ array(1.2e3, 7E-10),
+ array(3, acos(8)),
+ array(acos(8), 3),
+ array(acos(8), acos(8))
+ );
+ }
+
+ public function acceptsFailsProvider()
+ {
+ return array(
+ array(5, 5),
+ array('4.5', 5),
+ array(0x539, 02471),
+ array(5.0, false),
+ array(null, 5.0)
+ );
+ }
+
+ public function assertEqualsSucceedsProvider()
+ {
+ return array(
+ array(2.3, 2.3),
+ array('2.3', 2.3),
+ array(5.0, 5),
+ array(5, 5.0),
+ array(5.0, '5'),
+ array(1.2e3, 1200),
+ array(2.3, 2.5, 0.5),
+ array(3, 3.05, 0.05),
+ array(1.2e3, 1201, 1),
+ array((string)(1/3), 1 - 2/3),
+ array(1/3, (string)(1 - 2/3))
+ );
+ }
+
+ public function assertEqualsFailsProvider()
+ {
+ return array(
+ array(2.3, 4.2),
+ array('2.3', 4.2),
+ array(5.0, '4'),
+ array(5.0, 6),
+ array(1.2e3, 1201),
+ array(2.3, 2.5, 0.2),
+ array(3, 3.05, 0.04),
+ array(3, acos(8)),
+ array(acos(8), 3),
+ array(acos(8), acos(8))
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsSucceedsProvider
+ */
+ public function testAcceptsSucceeds($expected, $actual)
+ {
+ $this->assertTrue(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsFailsProvider
+ */
+ public function testAcceptsFails($expected, $actual)
+ {
+ $this->assertFalse(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsSucceedsProvider
+ */
+ public function testAssertEqualsSucceeds($expected, $actual, $delta = 0.0)
+ {
+ $exception = null;
+
+ try {
+ $this->comparator->assertEquals($expected, $actual, $delta);
+ }
+
+ catch (ComparisonFailure $exception) {
+ }
+
+ $this->assertNull($exception, 'Unexpected ComparisonFailure');
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsFailsProvider
+ */
+ public function testAssertEqualsFails($expected, $actual, $delta = 0.0)
+ {
+ $this->setExpectedException(
+ 'SebastianBergmann\\Comparator\\ComparisonFailure', 'matches expected'
+ );
+ $this->comparator->assertEquals($expected, $actual, $delta);
+ }
+}
diff --git a/vendor/sebastian/comparator/tests/ExceptionComparatorTest.php b/vendor/sebastian/comparator/tests/ExceptionComparatorTest.php
new file mode 100644
index 0000000..fa8cc0a
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/ExceptionComparatorTest.php
@@ -0,0 +1,136 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+use \Exception;
+use \RuntimeException;
+
+/**
+ * @coversDefaultClass SebastianBergmann\Comparator\ExceptionComparator
+ *
+ */
+class ExceptionComparatorTest extends \PHPUnit_Framework_TestCase
+{
+ private $comparator;
+
+ protected function setUp()
+ {
+ $this->comparator = new ExceptionComparator;
+ $this->comparator->setFactory(new Factory);
+ }
+
+ public function acceptsSucceedsProvider()
+ {
+ return array(
+ array(new Exception, new Exception),
+ array(new RuntimeException, new RuntimeException),
+ array(new Exception, new RuntimeException)
+ );
+ }
+
+ public function acceptsFailsProvider()
+ {
+ return array(
+ array(new Exception, null),
+ array(null, new Exception),
+ array(null, null)
+ );
+ }
+
+ public function assertEqualsSucceedsProvider()
+ {
+ $exception1 = new Exception;
+ $exception2 = new Exception;
+
+ $exception3 = new RunTimeException('Error', 100);
+ $exception4 = new RunTimeException('Error', 100);
+
+ return array(
+ array($exception1, $exception1),
+ array($exception1, $exception2),
+ array($exception3, $exception3),
+ array($exception3, $exception4)
+ );
+ }
+
+ public function assertEqualsFailsProvider()
+ {
+ $typeMessage = 'not instance of expected class';
+ $equalMessage = 'Failed asserting that two objects are equal.';
+
+ $exception1 = new Exception('Error', 100);
+ $exception2 = new Exception('Error', 101);
+ $exception3 = new Exception('Errors', 101);
+
+ $exception4 = new RunTimeException('Error', 100);
+ $exception5 = new RunTimeException('Error', 101);
+
+ return array(
+ array($exception1, $exception2, $equalMessage),
+ array($exception1, $exception3, $equalMessage),
+ array($exception1, $exception4, $typeMessage),
+ array($exception2, $exception3, $equalMessage),
+ array($exception4, $exception5, $equalMessage)
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsSucceedsProvider
+ */
+ public function testAcceptsSucceeds($expected, $actual)
+ {
+ $this->assertTrue(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsFailsProvider
+ */
+ public function testAcceptsFails($expected, $actual)
+ {
+ $this->assertFalse(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsSucceedsProvider
+ */
+ public function testAssertEqualsSucceeds($expected, $actual)
+ {
+ $exception = null;
+
+ try {
+ $this->comparator->assertEquals($expected, $actual);
+ }
+
+ catch (ComparisonFailure $exception) {
+ }
+
+ $this->assertNull($exception, 'Unexpected ComparisonFailure');
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsFailsProvider
+ */
+ public function testAssertEqualsFails($expected, $actual, $message)
+ {
+ $this->setExpectedException(
+ 'SebastianBergmann\\Comparator\\ComparisonFailure', $message
+ );
+ $this->comparator->assertEquals($expected, $actual);
+ }
+}
diff --git a/vendor/sebastian/comparator/tests/FactoryTest.php b/vendor/sebastian/comparator/tests/FactoryTest.php
new file mode 100644
index 0000000..cb58c20
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/FactoryTest.php
@@ -0,0 +1,115 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * @coversDefaultClass SebastianBergmann\Comparator\Factory
+ *
+ */
+class FactoryTest extends \PHPUnit_Framework_TestCase
+{
+ public function instanceProvider()
+ {
+ $tmpfile = tmpfile();
+
+ return array(
+ array(NULL, NULL, 'SebastianBergmann\\Comparator\\ScalarComparator'),
+ array(NULL, TRUE, 'SebastianBergmann\\Comparator\\ScalarComparator'),
+ array(TRUE, NULL, 'SebastianBergmann\\Comparator\\ScalarComparator'),
+ array(TRUE, TRUE, 'SebastianBergmann\\Comparator\\ScalarComparator'),
+ array(FALSE, FALSE, 'SebastianBergmann\\Comparator\\ScalarComparator'),
+ array(TRUE, FALSE, 'SebastianBergmann\\Comparator\\ScalarComparator'),
+ array(FALSE, TRUE, 'SebastianBergmann\\Comparator\\ScalarComparator'),
+ array('', '', 'SebastianBergmann\\Comparator\\ScalarComparator'),
+ array('0', '0', 'SebastianBergmann\\Comparator\\ScalarComparator'),
+ array('0', 0, 'SebastianBergmann\\Comparator\\NumericComparator'),
+ array(0, '0', 'SebastianBergmann\\Comparator\\NumericComparator'),
+ array(0, 0, 'SebastianBergmann\\Comparator\\NumericComparator'),
+ array(1.0, 0, 'SebastianBergmann\\Comparator\\DoubleComparator'),
+ array(0, 1.0, 'SebastianBergmann\\Comparator\\DoubleComparator'),
+ array(1.0, 1.0, 'SebastianBergmann\\Comparator\\DoubleComparator'),
+ array(array(1), array(1), 'SebastianBergmann\\Comparator\\ArrayComparator'),
+ array($tmpfile, $tmpfile, 'SebastianBergmann\\Comparator\\ResourceComparator'),
+ array(new \stdClass, new \stdClass, 'SebastianBergmann\\Comparator\\ObjectComparator'),
+ array(new \DateTime, new \DateTime, 'SebastianBergmann\\Comparator\\DateTimeComparator'),
+ array(new \SplObjectStorage, new \SplObjectStorage, 'SebastianBergmann\\Comparator\\SplObjectStorageComparator'),
+ array(new \Exception, new \Exception, 'SebastianBergmann\\Comparator\\ExceptionComparator'),
+ array(new \DOMDocument, new \DOMDocument, 'SebastianBergmann\\Comparator\\DOMNodeComparator'),
+ // mixed types
+ array($tmpfile, array(1), 'SebastianBergmann\\Comparator\\TypeComparator'),
+ array(array(1), $tmpfile, 'SebastianBergmann\\Comparator\\TypeComparator'),
+ array($tmpfile, '1', 'SebastianBergmann\\Comparator\\TypeComparator'),
+ array('1', $tmpfile, 'SebastianBergmann\\Comparator\\TypeComparator'),
+ array($tmpfile, new \stdClass, 'SebastianBergmann\\Comparator\\TypeComparator'),
+ array(new \stdClass, $tmpfile, 'SebastianBergmann\\Comparator\\TypeComparator'),
+ array(new \stdClass, array(1), 'SebastianBergmann\\Comparator\\TypeComparator'),
+ array(array(1), new \stdClass, 'SebastianBergmann\\Comparator\\TypeComparator'),
+ array(new \stdClass, '1', 'SebastianBergmann\\Comparator\\TypeComparator'),
+ array('1', new \stdClass, 'SebastianBergmann\\Comparator\\TypeComparator'),
+ array(new ClassWithToString, '1', 'SebastianBergmann\\Comparator\\ScalarComparator'),
+ array('1', new ClassWithToString, 'SebastianBergmann\\Comparator\\ScalarComparator'),
+ array(1.0, new \stdClass, 'SebastianBergmann\\Comparator\\TypeComparator'),
+ array(new \stdClass, 1.0, 'SebastianBergmann\\Comparator\\TypeComparator'),
+ array(1.0, array(1), 'SebastianBergmann\\Comparator\\TypeComparator'),
+ array(array(1), 1.0, 'SebastianBergmann\\Comparator\\TypeComparator'),
+ );
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ * @covers ::getComparatorFor
+ * @covers ::__construct
+ */
+ public function testGetComparatorFor($a, $b, $expected)
+ {
+ $factory = new Factory;
+ $actual = $factory->getComparatorFor($a, $b);
+ $this->assertInstanceOf($expected, $actual);
+ }
+
+ /**
+ * @covers ::register
+ */
+ public function testRegister()
+ {
+ $comparator = new TestClassComparator;
+
+ $factory = new Factory;
+ $factory->register($comparator);
+
+ $a = new TestClass;
+ $b = new TestClass;
+ $expected = 'SebastianBergmann\\Comparator\\TestClassComparator';
+ $actual = $factory->getComparatorFor($a, $b);
+
+ $factory->unregister($comparator);
+ $this->assertInstanceOf($expected, $actual);
+ }
+
+ /**
+ * @covers ::unregister
+ */
+ public function testUnregister()
+ {
+ $comparator = new TestClassComparator;
+
+ $factory = new Factory;
+ $factory->register($comparator);
+ $factory->unregister($comparator);
+
+ $a = new TestClass;
+ $b = new TestClass;
+ $expected = 'SebastianBergmann\\Comparator\\ObjectComparator';
+ $actual = $factory->getComparatorFor($a, $b);
+
+ $this->assertInstanceOf($expected, $actual);
+ }
+}
diff --git a/vendor/sebastian/comparator/tests/MockObjectComparatorTest.php b/vendor/sebastian/comparator/tests/MockObjectComparatorTest.php
new file mode 100644
index 0000000..7910ad7
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/MockObjectComparatorTest.php
@@ -0,0 +1,166 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * @coversDefaultClass SebastianBergmann\Comparator\MockObjectComparator
+ *
+ */
+class MockObjectComparatorTest extends \PHPUnit_Framework_TestCase
+{
+ private $comparator;
+
+ protected function setUp()
+ {
+ $this->comparator = new MockObjectComparator;
+ $this->comparator->setFactory(new Factory);
+ }
+
+ public function acceptsSucceedsProvider()
+ {
+ $testmock = $this->getMock('SebastianBergmann\\Comparator\\TestClass');
+ $stdmock = $this->getMock('stdClass');
+
+ return array(
+ array($testmock, $testmock),
+ array($stdmock, $stdmock),
+ array($stdmock, $testmock)
+ );
+ }
+
+ public function acceptsFailsProvider()
+ {
+ $stdmock = $this->getMock('stdClass');
+
+ return array(
+ array($stdmock, null),
+ array(null, $stdmock),
+ array(null, null)
+ );
+ }
+
+ public function assertEqualsSucceedsProvider()
+ {
+ // cyclic dependencies
+ $book1 = $this->getMock('SebastianBergmann\\Comparator\\Book', null);
+ $book1->author = $this->getMock('SebastianBergmann\\Comparator\\Author', null, array('Terry Pratchett'));
+ $book1->author->books[] = $book1;
+ $book2 = $this->getMock('SebastianBergmann\\Comparator\\Book', null);
+ $book2->author = $this->getMock('SebastianBergmann\\Comparator\\Author', null, array('Terry Pratchett'));
+ $book2->author->books[] = $book2;
+
+ $object1 = $this->getMock('SebastianBergmann\\Comparator\\SampleClass', null, array(4, 8, 15));
+ $object2 = $this->getMock('SebastianBergmann\\Comparator\\SampleClass', null, array(4, 8, 15));
+
+ return array(
+ array($object1, $object1),
+ array($object1, $object2),
+ array($book1, $book1),
+ array($book1, $book2),
+ array(
+ $this->getMock('SebastianBergmann\\Comparator\\Struct', null, array(2.3)),
+ $this->getMock('SebastianBergmann\\Comparator\\Struct', null, array(2.5)),
+ 0.5
+ )
+ );
+ }
+
+ public function assertEqualsFailsProvider()
+ {
+ $typeMessage = 'is not instance of expected class';
+ $equalMessage = 'Failed asserting that two objects are equal.';
+
+ // cyclic dependencies
+ $book1 = $this->getMock('SebastianBergmann\\Comparator\\Book', null);
+ $book1->author = $this->getMock('SebastianBergmann\\Comparator\\Author', null, array('Terry Pratchett'));
+ $book1->author->books[] = $book1;
+ $book2 = $this->getMock('SebastianBergmann\\Comparator\\Book', null);
+ $book2->author = $this->getMock('SebastianBergmann\\Comparator\\Author', null, array('Terry Pratch'));
+ $book2->author->books[] = $book2;
+
+ $book3 = $this->getMock('SebastianBergmann\\Comparator\\Book', null);
+ $book3->author = 'Terry Pratchett';
+ $book4 = $this->getMock('stdClass');
+ $book4->author = 'Terry Pratchett';
+
+ $object1 = $this->getMock('SebastianBergmann\\Comparator\\SampleClass', null, array(4, 8, 15));
+ $object2 = $this->getMock('SebastianBergmann\\Comparator\\SampleClass', null, array(16, 23, 42));
+
+ return array(
+ array(
+ $this->getMock('SebastianBergmann\\Comparator\\SampleClass', null, array(4, 8, 15)),
+ $this->getMock('SebastianBergmann\\Comparator\\SampleClass', null, array(16, 23, 42)),
+ $equalMessage
+ ),
+ array($object1, $object2, $equalMessage),
+ array($book1, $book2, $equalMessage),
+ array($book3, $book4, $typeMessage),
+ array(
+ $this->getMock('SebastianBergmann\\Comparator\\Struct', null, array(2.3)),
+ $this->getMock('SebastianBergmann\\Comparator\\Struct', null, array(4.2)),
+ $equalMessage,
+ 0.5
+ )
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsSucceedsProvider
+ */
+ public function testAcceptsSucceeds($expected, $actual)
+ {
+ $this->assertTrue(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsFailsProvider
+ */
+ public function testAcceptsFails($expected, $actual)
+ {
+ $this->assertFalse(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsSucceedsProvider
+ */
+ public function testAssertEqualsSucceeds($expected, $actual, $delta = 0.0)
+ {
+ $exception = null;
+
+ try {
+ $this->comparator->assertEquals($expected, $actual, $delta);
+ }
+
+ catch (ComparisonFailure $exception) {
+ }
+
+ $this->assertNull($exception, 'Unexpected ComparisonFailure');
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsFailsProvider
+ */
+ public function testAssertEqualsFails($expected, $actual, $message, $delta = 0.0)
+ {
+ $this->setExpectedException(
+ 'SebastianBergmann\\Comparator\\ComparisonFailure', $message
+ );
+ $this->comparator->assertEquals($expected, $actual, $delta);
+ }
+}
diff --git a/vendor/sebastian/comparator/tests/NumericComparatorTest.php b/vendor/sebastian/comparator/tests/NumericComparatorTest.php
new file mode 100644
index 0000000..fec7d00
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/NumericComparatorTest.php
@@ -0,0 +1,122 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * @coversDefaultClass SebastianBergmann\Comparator\NumericComparator
+ *
+ */
+class NumericComparatorTest extends \PHPUnit_Framework_TestCase
+{
+ private $comparator;
+
+ protected function setUp()
+ {
+ $this->comparator = new NumericComparator;
+ }
+
+ public function acceptsSucceedsProvider()
+ {
+ return array(
+ array(5, 10),
+ array(8, '0'),
+ array('10', 0),
+ array(0x74c3b00c, 42),
+ array(0755, 0777)
+ );
+ }
+
+ public function acceptsFailsProvider()
+ {
+ return array(
+ array('5', '10'),
+ array(8, 5.0),
+ array(5.0, 8),
+ array(10, null),
+ array(false, 12)
+ );
+ }
+
+ public function assertEqualsSucceedsProvider()
+ {
+ return array(
+ array(1337, 1337),
+ array('1337', 1337),
+ array(0x539, 1337),
+ array(02471, 1337),
+ array(1337, 1338, 1),
+ array('1337', 1340, 5),
+ );
+ }
+
+ public function assertEqualsFailsProvider()
+ {
+ return array(
+ array(1337, 1338),
+ array('1338', 1337),
+ array(0x539, 1338),
+ array(1337, 1339, 1),
+ array('1337', 1340, 2),
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsSucceedsProvider
+ */
+ public function testAcceptsSucceeds($expected, $actual)
+ {
+ $this->assertTrue(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsFailsProvider
+ */
+ public function testAcceptsFails($expected, $actual)
+ {
+ $this->assertFalse(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsSucceedsProvider
+ */
+ public function testAssertEqualsSucceeds($expected, $actual, $delta = 0.0)
+ {
+ $exception = null;
+
+ try {
+ $this->comparator->assertEquals($expected, $actual, $delta);
+ }
+
+ catch (ComparisonFailure $exception) {
+ }
+
+ $this->assertNull($exception, 'Unexpected ComparisonFailure');
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsFailsProvider
+ */
+ public function testAssertEqualsFails($expected, $actual, $delta = 0.0)
+ {
+ $this->setExpectedException(
+ 'SebastianBergmann\\Comparator\\ComparisonFailure', 'matches expected'
+ );
+ $this->comparator->assertEquals($expected, $actual, $delta);
+ }
+}
diff --git a/vendor/sebastian/comparator/tests/ObjectComparatorTest.php b/vendor/sebastian/comparator/tests/ObjectComparatorTest.php
new file mode 100644
index 0000000..a958232
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/ObjectComparatorTest.php
@@ -0,0 +1,150 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+use stdClass;
+
+/**
+ * @coversDefaultClass SebastianBergmann\Comparator\ObjectComparator
+ *
+ */
+class ObjectComparatorTest extends \PHPUnit_Framework_TestCase
+{
+ private $comparator;
+
+ protected function setUp()
+ {
+ $this->comparator = new ObjectComparator;
+ $this->comparator->setFactory(new Factory);
+ }
+
+ public function acceptsSucceedsProvider()
+ {
+ return array(
+ array(new TestClass, new TestClass),
+ array(new stdClass, new stdClass),
+ array(new stdClass, new TestClass)
+ );
+ }
+
+ public function acceptsFailsProvider()
+ {
+ return array(
+ array(new stdClass, null),
+ array(null, new stdClass),
+ array(null, null)
+ );
+ }
+
+ public function assertEqualsSucceedsProvider()
+ {
+ // cyclic dependencies
+ $book1 = new Book;
+ $book1->author = new Author('Terry Pratchett');
+ $book1->author->books[] = $book1;
+ $book2 = new Book;
+ $book2->author = new Author('Terry Pratchett');
+ $book2->author->books[] = $book2;
+
+ $object1 = new SampleClass(4, 8, 15);
+ $object2 = new SampleClass(4, 8, 15);
+
+ return array(
+ array($object1, $object1),
+ array($object1, $object2),
+ array($book1, $book1),
+ array($book1, $book2),
+ array(new Struct(2.3), new Struct(2.5), 0.5)
+ );
+ }
+
+ public function assertEqualsFailsProvider()
+ {
+ $typeMessage = 'is not instance of expected class';
+ $equalMessage = 'Failed asserting that two objects are equal.';
+
+ // cyclic dependencies
+ $book1 = new Book;
+ $book1->author = new Author('Terry Pratchett');
+ $book1->author->books[] = $book1;
+ $book2 = new Book;
+ $book2->author = new Author('Terry Pratch');
+ $book2->author->books[] = $book2;
+
+ $book3 = new Book;
+ $book3->author = 'Terry Pratchett';
+ $book4 = new stdClass;
+ $book4->author = 'Terry Pratchett';
+
+ $object1 = new SampleClass( 4, 8, 15);
+ $object2 = new SampleClass(16, 23, 42);
+
+ return array(
+ array(new SampleClass(4, 8, 15), new SampleClass(16, 23, 42), $equalMessage),
+ array($object1, $object2, $equalMessage),
+ array($book1, $book2, $equalMessage),
+ array($book3, $book4, $typeMessage),
+ array(new Struct(2.3), new Struct(4.2), $equalMessage, 0.5)
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsSucceedsProvider
+ */
+ public function testAcceptsSucceeds($expected, $actual)
+ {
+ $this->assertTrue(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsFailsProvider
+ */
+ public function testAcceptsFails($expected, $actual)
+ {
+ $this->assertFalse(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsSucceedsProvider
+ */
+ public function testAssertEqualsSucceeds($expected, $actual, $delta = 0.0)
+ {
+ $exception = null;
+
+ try {
+ $this->comparator->assertEquals($expected, $actual, $delta);
+ }
+
+ catch (ComparisonFailure $exception) {
+ }
+
+ $this->assertNull($exception, 'Unexpected ComparisonFailure');
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsFailsProvider
+ */
+ public function testAssertEqualsFails($expected, $actual, $message, $delta = 0.0)
+ {
+ $this->setExpectedException(
+ 'SebastianBergmann\\Comparator\\ComparisonFailure', $message
+ );
+ $this->comparator->assertEquals($expected, $actual, $delta);
+ }
+}
diff --git a/vendor/sebastian/comparator/tests/ResourceComparatorTest.php b/vendor/sebastian/comparator/tests/ResourceComparatorTest.php
new file mode 100644
index 0000000..a9e9e95
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/ResourceComparatorTest.php
@@ -0,0 +1,120 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * @coversDefaultClass SebastianBergmann\Comparator\ResourceComparator
+ *
+ */
+class ResourceComparatorTest extends \PHPUnit_Framework_TestCase
+{
+ private $comparator;
+
+ protected function setUp()
+ {
+ $this->comparator = new ResourceComparator;
+ }
+
+ public function acceptsSucceedsProvider()
+ {
+ $tmpfile1 = tmpfile();
+ $tmpfile2 = tmpfile();
+
+ return array(
+ array($tmpfile1, $tmpfile1),
+ array($tmpfile2, $tmpfile2),
+ array($tmpfile1, $tmpfile2)
+ );
+ }
+
+ public function acceptsFailsProvider()
+ {
+ $tmpfile1 = tmpfile();
+
+ return array(
+ array($tmpfile1, null),
+ array(null, $tmpfile1),
+ array(null, null)
+ );
+ }
+
+ public function assertEqualsSucceedsProvider()
+ {
+ $tmpfile1 = tmpfile();
+ $tmpfile2 = tmpfile();
+
+ return array(
+ array($tmpfile1, $tmpfile1),
+ array($tmpfile2, $tmpfile2)
+ );
+ }
+
+ public function assertEqualsFailsProvider()
+ {
+ $tmpfile1 = tmpfile();
+ $tmpfile2 = tmpfile();
+
+ return array(
+ array($tmpfile1, $tmpfile2),
+ array($tmpfile2, $tmpfile1)
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsSucceedsProvider
+ */
+ public function testAcceptsSucceeds($expected, $actual)
+ {
+ $this->assertTrue(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsFailsProvider
+ */
+ public function testAcceptsFails($expected, $actual)
+ {
+ $this->assertFalse(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsSucceedsProvider
+ */
+ public function testAssertEqualsSucceeds($expected, $actual)
+ {
+ $exception = null;
+
+ try {
+ $this->comparator->assertEquals($expected, $actual);
+ }
+
+ catch (ComparisonFailure $exception) {
+ }
+
+ $this->assertNull($exception, 'Unexpected ComparisonFailure');
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsFailsProvider
+ */
+ public function testAssertEqualsFails($expected, $actual)
+ {
+ $this->setExpectedException('SebastianBergmann\\Comparator\\ComparisonFailure');
+ $this->comparator->assertEquals($expected, $actual);
+ }
+}
diff --git a/vendor/sebastian/comparator/tests/ScalarComparatorTest.php b/vendor/sebastian/comparator/tests/ScalarComparatorTest.php
new file mode 100644
index 0000000..e5156aa
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/ScalarComparatorTest.php
@@ -0,0 +1,158 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * @coversDefaultClass SebastianBergmann\Comparator\ScalarComparator
+ *
+ */
+class ScalarComparatorTest extends \PHPUnit_Framework_TestCase
+{
+ private $comparator;
+
+ protected function setUp()
+ {
+ $this->comparator = new ScalarComparator;
+ }
+
+ public function acceptsSucceedsProvider()
+ {
+ return array(
+ array("string", "string"),
+ array(new ClassWithToString, "string"),
+ array("string", new ClassWithToString),
+ array("string", null),
+ array(false, "string"),
+ array(false, true),
+ array(null, false),
+ array(null, null),
+ array("10", 10),
+ array("", false),
+ array("1", true),
+ array(1, true),
+ array(0, false),
+ array(0.1, "0.1")
+ );
+ }
+
+ public function acceptsFailsProvider()
+ {
+ return array(
+ array(array(), array()),
+ array("string", array()),
+ array(new ClassWithToString, new ClassWithToString),
+ array(false, new ClassWithToString),
+ array(tmpfile(), tmpfile())
+ );
+ }
+
+ public function assertEqualsSucceedsProvider()
+ {
+ return array(
+ array("string", "string"),
+ array(new ClassWithToString, new ClassWithToString),
+ array("string representation", new ClassWithToString),
+ array(new ClassWithToString, "string representation"),
+ array("string", "STRING", true),
+ array("STRING", "string", true),
+ array("String Representation", new ClassWithToString, true),
+ array(new ClassWithToString, "String Representation", true),
+ array("10", 10),
+ array("", false),
+ array("1", true),
+ array(1, true),
+ array(0, false),
+ array(0.1, "0.1"),
+ array(false, null),
+ array(false, false),
+ array(true, true),
+ array(null, null)
+ );
+ }
+
+ public function assertEqualsFailsProvider()
+ {
+ $stringException = 'Failed asserting that two strings are equal.';
+ $otherException = 'matches expected';
+
+ return array(
+ array("string", "other string", $stringException),
+ array("string", "STRING", $stringException),
+ array("STRING", "string", $stringException),
+ array("string", "other string", $stringException),
+ // https://github.com/sebastianbergmann/phpunit/issues/1023
+ array('9E6666666','9E7777777', $stringException),
+ array(new ClassWithToString, "does not match", $otherException),
+ array("does not match", new ClassWithToString, $otherException),
+ array(0, 'Foobar', $otherException),
+ array('Foobar', 0, $otherException),
+ array("10", 25, $otherException),
+ array("1", false, $otherException),
+ array("", true, $otherException),
+ array(false, true, $otherException),
+ array(true, false, $otherException),
+ array(null, true, $otherException),
+ array(0, true, $otherException)
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsSucceedsProvider
+ */
+ public function testAcceptsSucceeds($expected, $actual)
+ {
+ $this->assertTrue(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsFailsProvider
+ */
+ public function testAcceptsFails($expected, $actual)
+ {
+ $this->assertFalse(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsSucceedsProvider
+ */
+ public function testAssertEqualsSucceeds($expected, $actual, $ignoreCase = false)
+ {
+ $exception = null;
+
+ try {
+ $this->comparator->assertEquals($expected, $actual, 0.0, false, $ignoreCase);
+ }
+
+ catch (ComparisonFailure $exception) {
+ }
+
+ $this->assertNull($exception, 'Unexpected ComparisonFailure');
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsFailsProvider
+ */
+ public function testAssertEqualsFails($expected, $actual, $message)
+ {
+ $this->setExpectedException(
+ 'SebastianBergmann\\Comparator\\ComparisonFailure', $message
+ );
+ $this->comparator->assertEquals($expected, $actual);
+ }
+}
diff --git a/vendor/sebastian/comparator/tests/SplObjectStorageComparatorTest.php b/vendor/sebastian/comparator/tests/SplObjectStorageComparatorTest.php
new file mode 100644
index 0000000..766dd2d
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/SplObjectStorageComparatorTest.php
@@ -0,0 +1,137 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+use SplObjectStorage;
+use stdClass;
+
+/**
+ * @coversDefaultClass SebastianBergmann\Comparator\SplObjectStorageComparator
+ *
+ */
+class SplObjectStorageComparatorTest extends \PHPUnit_Framework_TestCase
+{
+ private $comparator;
+
+ protected function setUp()
+ {
+ $this->comparator = new SplObjectStorageComparator;
+ }
+
+ public function acceptsFailsProvider()
+ {
+ return array(
+ array(new SplObjectStorage, new stdClass),
+ array(new stdClass, new SplObjectStorage),
+ array(new stdClass, new stdClass)
+ );
+ }
+
+ public function assertEqualsSucceedsProvider()
+ {
+ $object1 = new stdClass();
+ $object2 = new stdClass();
+
+ $storage1 = new SplObjectStorage();
+ $storage2 = new SplObjectStorage();
+
+ $storage3 = new SplObjectStorage();
+ $storage3->attach($object1);
+ $storage3->attach($object2);
+
+ $storage4 = new SplObjectStorage();
+ $storage4->attach($object2);
+ $storage4->attach($object1);
+
+ return array(
+ array($storage1, $storage1),
+ array($storage1, $storage2),
+ array($storage3, $storage3),
+ array($storage3, $storage4)
+ );
+ }
+
+ public function assertEqualsFailsProvider()
+ {
+ $object1 = new stdClass;
+ $object2 = new stdClass;
+
+ $storage1 = new SplObjectStorage;
+
+ $storage2 = new SplObjectStorage;
+ $storage2->attach($object1);
+
+ $storage3 = new SplObjectStorage;
+ $storage3->attach($object2);
+ $storage3->attach($object1);
+
+ return array(
+ array($storage1, $storage2),
+ array($storage1, $storage3),
+ array($storage2, $storage3),
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ */
+ public function testAcceptsSucceeds()
+ {
+ $this->assertTrue(
+ $this->comparator->accepts(
+ new SplObjectStorage,
+ new SplObjectStorage
+ )
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsFailsProvider
+ */
+ public function testAcceptsFails($expected, $actual)
+ {
+ $this->assertFalse(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsSucceedsProvider
+ */
+ public function testAssertEqualsSucceeds($expected, $actual)
+ {
+ $exception = null;
+
+ try {
+ $this->comparator->assertEquals($expected, $actual);
+ }
+
+ catch (ComparisonFailure $exception) {
+ }
+
+ $this->assertNull($exception, 'Unexpected ComparisonFailure');
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsFailsProvider
+ */
+ public function testAssertEqualsFails($expected, $actual)
+ {
+ $this->setExpectedException(
+ 'SebastianBergmann\\Comparator\\ComparisonFailure',
+ 'Failed asserting that two objects are equal.'
+ );
+ $this->comparator->assertEquals($expected, $actual);
+ }
+}
diff --git a/vendor/sebastian/comparator/tests/TypeComparatorTest.php b/vendor/sebastian/comparator/tests/TypeComparatorTest.php
new file mode 100644
index 0000000..bb51f8a
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/TypeComparatorTest.php
@@ -0,0 +1,104 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+use stdClass;
+
+/**
+ * @coversDefaultClass SebastianBergmann\Comparator\TypeComparator
+ *
+ */
+class TypeComparatorTest extends \PHPUnit_Framework_TestCase
+{
+ private $comparator;
+
+ protected function setUp()
+ {
+ $this->comparator = new TypeComparator;
+ }
+
+ public function acceptsSucceedsProvider()
+ {
+ return array(
+ array(true, 1),
+ array(false, array(1)),
+ array(null, new stdClass),
+ array(1.0, 5),
+ array("", "")
+ );
+ }
+
+ public function assertEqualsSucceedsProvider()
+ {
+ return array(
+ array(true, true),
+ array(true, false),
+ array(false, false),
+ array(null, null),
+ array(new stdClass, new stdClass),
+ array(0, 0),
+ array(1.0, 2.0),
+ array("hello", "world"),
+ array("", ""),
+ array(array(), array(1,2,3))
+ );
+ }
+
+ public function assertEqualsFailsProvider()
+ {
+ return array(
+ array(true, null),
+ array(null, false),
+ array(1.0, 0),
+ array(new stdClass, array()),
+ array("1", 1)
+ );
+ }
+
+ /**
+ * @covers ::accepts
+ * @dataProvider acceptsSucceedsProvider
+ */
+ public function testAcceptsSucceeds($expected, $actual)
+ {
+ $this->assertTrue(
+ $this->comparator->accepts($expected, $actual)
+ );
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsSucceedsProvider
+ */
+ public function testAssertEqualsSucceeds($expected, $actual)
+ {
+ $exception = null;
+
+ try {
+ $this->comparator->assertEquals($expected, $actual);
+ }
+
+ catch (ComparisonFailure $exception) {
+ }
+
+ $this->assertNull($exception, 'Unexpected ComparisonFailure');
+ }
+
+ /**
+ * @covers ::assertEquals
+ * @dataProvider assertEqualsFailsProvider
+ */
+ public function testAssertEqualsFails($expected, $actual)
+ {
+ $this->setExpectedException('SebastianBergmann\\Comparator\\ComparisonFailure', 'does not match expected type');
+ $this->comparator->assertEquals($expected, $actual);
+ }
+}
diff --git a/vendor/sebastian/comparator/tests/_files/Author.php b/vendor/sebastian/comparator/tests/_files/Author.php
new file mode 100644
index 0000000..ae698c3
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/_files/Author.php
@@ -0,0 +1,28 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * An author.
+ *
+ */
+class Author
+{
+ // the order of properties is important for testing the cycle!
+ public $books = array();
+
+ private $name = '';
+
+ public function __construct($name)
+ {
+ $this->name = $name;
+ }
+}
diff --git a/vendor/sebastian/comparator/tests/_files/Book.php b/vendor/sebastian/comparator/tests/_files/Book.php
new file mode 100644
index 0000000..6171bc3
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/_files/Book.php
@@ -0,0 +1,21 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * A book.
+ *
+ */
+class Book
+{
+ // the order of properties is important for testing the cycle!
+ public $author = null;
+}
diff --git a/vendor/sebastian/comparator/tests/_files/ClassWithToString.php b/vendor/sebastian/comparator/tests/_files/ClassWithToString.php
new file mode 100644
index 0000000..e8e03bc
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/_files/ClassWithToString.php
@@ -0,0 +1,19 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+class ClassWithToString
+{
+ public function __toString()
+ {
+ return 'string representation';
+ }
+}
diff --git a/vendor/sebastian/comparator/tests/_files/SampleClass.php b/vendor/sebastian/comparator/tests/_files/SampleClass.php
new file mode 100644
index 0000000..6079dd3
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/_files/SampleClass.php
@@ -0,0 +1,29 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * A sample class.
+ *
+ */
+class SampleClass
+{
+ public $a;
+ protected $b;
+ protected $c;
+
+ public function __construct($a, $b, $c)
+ {
+ $this->a = $a;
+ $this->b = $b;
+ $this->c = $c;
+ }
+}
diff --git a/vendor/sebastian/comparator/tests/_files/Struct.php b/vendor/sebastian/comparator/tests/_files/Struct.php
new file mode 100644
index 0000000..79ec559
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/_files/Struct.php
@@ -0,0 +1,25 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+/**
+ * A struct.
+ *
+ */
+class Struct
+{
+ public $var;
+
+ public function __construct($var)
+ {
+ $this->var = $var;
+ }
+}
diff --git a/vendor/sebastian/comparator/tests/_files/TestClass.php b/vendor/sebastian/comparator/tests/_files/TestClass.php
new file mode 100644
index 0000000..e4c9b78
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/_files/TestClass.php
@@ -0,0 +1,14 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+class TestClass {
+}
diff --git a/vendor/sebastian/comparator/tests/_files/TestClassComparator.php b/vendor/sebastian/comparator/tests/_files/TestClassComparator.php
new file mode 100644
index 0000000..52aac3f
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/_files/TestClassComparator.php
@@ -0,0 +1,14 @@
+<?php
+/*
+ * This file is part of the Comparator package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Comparator;
+
+class TestClassComparator extends ObjectComparator {
+}
diff --git a/vendor/sebastian/comparator/tests/autoload.php b/vendor/sebastian/comparator/tests/autoload.php
new file mode 100644
index 0000000..f4d9bbc
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/autoload.php
@@ -0,0 +1,38 @@
+<?php
+// @codingStandardsIgnoreFile
+// @codeCoverageIgnoreStart
+// this is an autogenerated file - do not edit
+spl_autoload_register(
+ function($class) {
+ static $classes = null;
+ if ($classes === null) {
+ $classes = array(
+ 'sebastianbergmann\\comparator\\arraycomparatortest' => '/ArrayComparatorTest.php',
+ 'sebastianbergmann\\comparator\\author' => '/_files/Author.php',
+ 'sebastianbergmann\\comparator\\book' => '/_files/Book.php',
+ 'sebastianbergmann\\comparator\\classwithtostring' => '/_files/ClassWithToString.php',
+ 'sebastianbergmann\\comparator\\datetimecomparatortest' => '/DateTimeComparatorTest.php',
+ 'sebastianbergmann\\comparator\\domnodecomparatortest' => '/DOMNodeComparatorTest.php',
+ 'sebastianbergmann\\comparator\\doublecomparatortest' => '/DoubleComparatorTest.php',
+ 'sebastianbergmann\\comparator\\exceptioncomparatortest' => '/ExceptionComparatorTest.php',
+ 'sebastianbergmann\\comparator\\factorytest' => '/FactoryTest.php',
+ 'sebastianbergmann\\comparator\\mockobjectcomparatortest' => '/MockObjectComparatorTest.php',
+ 'sebastianbergmann\\comparator\\numericcomparatortest' => '/NumericComparatorTest.php',
+ 'sebastianbergmann\\comparator\\objectcomparatortest' => '/ObjectComparatorTest.php',
+ 'sebastianbergmann\\comparator\\resourcecomparatortest' => '/ResourceComparatorTest.php',
+ 'sebastianbergmann\\comparator\\sampleclass' => '/_files/SampleClass.php',
+ 'sebastianbergmann\\comparator\\scalarcomparatortest' => '/ScalarComparatorTest.php',
+ 'sebastianbergmann\\comparator\\splobjectstoragecomparatortest' => '/SplObjectStorageComparatorTest.php',
+ 'sebastianbergmann\\comparator\\struct' => '/_files/Struct.php',
+ 'sebastianbergmann\\comparator\\testclass' => '/_files/TestClass.php',
+ 'sebastianbergmann\\comparator\\testclasscomparator' => '/_files/TestClassComparator.php',
+ 'sebastianbergmann\\comparator\\typecomparatortest' => '/TypeComparatorTest.php'
+ );
+ }
+ $cn = strtolower($class);
+ if (isset($classes[$cn])) {
+ require __DIR__ . $classes[$cn];
+ }
+ }
+);
+// @codeCoverageIgnoreEnd
diff --git a/vendor/sebastian/comparator/tests/bootstrap.php b/vendor/sebastian/comparator/tests/bootstrap.php
new file mode 100644
index 0000000..8f1c57c
--- /dev/null
+++ b/vendor/sebastian/comparator/tests/bootstrap.php
@@ -0,0 +1,7 @@
+<?php
+require __DIR__ . '/../vendor/autoload.php';
+require __DIR__ . '/autoload.php';
+
+ini_set('precision', 14);
+ini_set('serialize_precision', 14);
+
diff --git a/vendor/sebastian/diff/.gitignore b/vendor/sebastian/diff/.gitignore
new file mode 100644
index 0000000..36a9658
--- /dev/null
+++ b/vendor/sebastian/diff/.gitignore
@@ -0,0 +1,4 @@
+/.idea
+/composer.lock
+/vendor
+/.php_cs.cache \ No newline at end of file
diff --git a/vendor/sebastian/diff/.php_cs b/vendor/sebastian/diff/.php_cs
new file mode 100644
index 0000000..ef46bea
--- /dev/null
+++ b/vendor/sebastian/diff/.php_cs
@@ -0,0 +1,79 @@
+<?php
+$header = <<<'EOF'
+This file is part of sebastian/diff.
+
+(c) Sebastian Bergmann <sebastian@phpunit.de>
+
+For the full copyright and license information, please view the LICENSE
+file that was distributed with this source code.
+EOF;
+
+return PhpCsFixer\Config::create()
+ ->setRiskyAllowed(true)
+ ->setRules(
+ [
+ 'array_syntax' => ['syntax' => 'long'],
+ 'binary_operator_spaces' => [
+ 'align_double_arrow' => true,
+ 'align_equals' => true
+ ],
+ 'blank_line_after_namespace' => true,
+ 'blank_line_before_return' => true,
+ 'braces' => true,
+ 'cast_spaces' => true,
+ 'concat_space' => ['spacing' => 'one'],
+ 'elseif' => true,
+ 'encoding' => true,
+ 'full_opening_tag' => true,
+ 'function_declaration' => true,
+ 'header_comment' => ['header' => $header, 'separate' => 'none'],
+ 'indentation_type' => true,
+ 'line_ending' => true,
+ 'lowercase_constants' => true,
+ 'lowercase_keywords' => true,
+ 'method_argument_space' => true,
+ 'native_function_invocation' => true,
+ 'no_alias_functions' => true,
+ 'no_blank_lines_after_class_opening' => true,
+ 'no_blank_lines_after_phpdoc' => true,
+ 'no_closing_tag' => true,
+ 'no_empty_phpdoc' => true,
+ 'no_empty_statement' => true,
+ 'no_extra_consecutive_blank_lines' => true,
+ 'no_leading_namespace_whitespace' => true,
+ 'no_singleline_whitespace_before_semicolons' => true,
+ 'no_spaces_after_function_name' => true,
+ 'no_spaces_inside_parenthesis' => true,
+ 'no_trailing_comma_in_list_call' => true,
+ 'no_trailing_whitespace' => true,
+ 'no_unused_imports' => true,
+ 'no_whitespace_in_blank_line' => true,
+ 'phpdoc_align' => true,
+ 'phpdoc_indent' => true,
+ 'phpdoc_no_access' => true,
+ 'phpdoc_no_empty_return' => true,
+ 'phpdoc_no_package' => true,
+ 'phpdoc_scalar' => true,
+ 'phpdoc_separation' => true,
+ 'phpdoc_to_comment' => true,
+ 'phpdoc_trim' => true,
+ 'phpdoc_types' => true,
+ 'phpdoc_var_without_name' => true,
+ 'self_accessor' => true,
+ 'simplified_null_return' => true,
+ 'single_blank_line_at_eof' => true,
+ 'single_import_per_statement' => true,
+ 'single_line_after_imports' => true,
+ 'single_quote' => true,
+ 'ternary_operator_spaces' => true,
+ 'trim_array_spaces' => true,
+ 'visibility_required' => true,
+ ]
+ )
+ ->setFinder(
+ PhpCsFixer\Finder::create()
+ ->files()
+ ->in(__DIR__ . '/src')
+ ->in(__DIR__ . '/tests')
+ ->name('*.php')
+ );
diff --git a/vendor/sebastian/diff/.travis.yml b/vendor/sebastian/diff/.travis.yml
new file mode 100644
index 0000000..fa69ad1
--- /dev/null
+++ b/vendor/sebastian/diff/.travis.yml
@@ -0,0 +1,31 @@
+language: php
+
+php:
+ - 5.3
+ - 5.4
+ - 5.5
+ - 5.6
+ - 7.0
+ - 7.0snapshot
+ - 7.1
+ - 7.1snapshot
+ - master
+
+sudo: false
+
+before_install:
+ - composer self-update
+ - composer clear-cache
+
+install:
+ - travis_retry composer update --no-interaction --no-ansi --no-progress --no-suggest --optimize-autoloader --prefer-stable
+
+script:
+ - ./vendor/bin/phpunit --coverage-clover=coverage.xml
+
+after_success:
+ - bash <(curl -s https://codecov.io/bash)
+
+notifications:
+ email: false
+
diff --git a/vendor/sebastian/diff/LICENSE b/vendor/sebastian/diff/LICENSE
new file mode 100644
index 0000000..e1ddf13
--- /dev/null
+++ b/vendor/sebastian/diff/LICENSE
@@ -0,0 +1,33 @@
+sebastian/diff
+
+Copyright (c) 2002-2017, Sebastian Bergmann <sebastian@phpunit.de>.
+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 0000000..956038b
--- /dev/null
+++ b/vendor/sebastian/diff/README.md
@@ -0,0 +1,126 @@
+# sebastian/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
+
+The `Differ` class can be used to generate a textual representation of the difference between two strings:
+
+```php
+use SebastianBergmann\Diff\Differ;
+
+$differ = new Differ;
+print $differ->diff('foo', 'bar');
+```
+
+The code above yields the output below:
+
+ --- Original
+ +++ New
+ @@ @@
+ -foo
+ +bar
+
+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/build.xml b/vendor/sebastian/diff/build.xml
new file mode 100644
index 0000000..fa7b7e2
--- /dev/null
+++ b/vendor/sebastian/diff/build.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="diff" default="setup">
+ <target name="setup" depends="clean,composer"/>
+
+ <target name="clean" description="Cleanup build artifacts">
+ <delete dir="${basedir}/vendor"/>
+ <delete file="${basedir}/composer.lock"/>
+ </target>
+
+ <target name="composer" depends="clean" description="Install dependencies with Composer">
+ <exec executable="composer" taskname="composer">
+ <arg value="update"/>
+ <arg value="--no-interaction"/>
+ <arg value="--no-progress"/>
+ <arg value="--no-ansi"/>
+ <arg value="--no-suggest"/>
+ <arg value="--optimize-autoloader"/>
+ <arg value="--prefer-stable"/>
+ </exec>
+ </target>
+</project>
+
diff --git a/vendor/sebastian/diff/composer.json b/vendor/sebastian/diff/composer.json
new file mode 100644
index 0000000..8f2bcf3
--- /dev/null
+++ b/vendor/sebastian/diff/composer.json
@@ -0,0 +1,33 @@
+{
+ "name": "sebastian/diff",
+ "description": "Diff implementation",
+ "keywords": ["diff"],
+ "homepage": "https://github.com/sebastianbergmann/diff",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
+ }
+ ],
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/diff/phpunit.xml b/vendor/sebastian/diff/phpunit.xml
new file mode 100644
index 0000000..68febeb
--- /dev/null
+++ b/vendor/sebastian/diff/phpunit.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.0/phpunit.xsd"
+ bootstrap="vendor/autoload.php"
+ forceCoversAnnotation="true"
+ beStrictAboutCoversAnnotation="true"
+ beStrictAboutOutputDuringTests="true"
+ beStrictAboutTodoAnnotatedTests="true"
+ verbose="true">
+ <testsuite>
+ <directory suffix="Test.php">tests</directory>
+ </testsuite>
+
+ <filter>
+ <whitelist processUncoveredFilesFromWhitelist="true">
+ <directory suffix=".php">src</directory>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/vendor/sebastian/diff/src/Chunk.php b/vendor/sebastian/diff/src/Chunk.php
new file mode 100644
index 0000000..1a6ea73
--- /dev/null
+++ b/vendor/sebastian/diff/src/Chunk.php
@@ -0,0 +1,103 @@
+<?php
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Diff;
+
+class Chunk
+{
+ /**
+ * @var int
+ */
+ private $start;
+
+ /**
+ * @var int
+ */
+ private $startRange;
+
+ /**
+ * @var int
+ */
+ private $end;
+
+ /**
+ * @var int
+ */
+ private $endRange;
+
+ /**
+ * @var array
+ */
+ private $lines;
+
+ /**
+ * @param int $start
+ * @param int $startRange
+ * @param int $end
+ * @param int $endRange
+ * @param array $lines
+ */
+ public function __construct($start = 0, $startRange = 1, $end = 0, $endRange = 1, array $lines = array())
+ {
+ $this->start = (int) $start;
+ $this->startRange = (int) $startRange;
+ $this->end = (int) $end;
+ $this->endRange = (int) $endRange;
+ $this->lines = $lines;
+ }
+
+ /**
+ * @return int
+ */
+ public function getStart()
+ {
+ return $this->start;
+ }
+
+ /**
+ * @return int
+ */
+ public function getStartRange()
+ {
+ return $this->startRange;
+ }
+
+ /**
+ * @return int
+ */
+ public function getEnd()
+ {
+ return $this->end;
+ }
+
+ /**
+ * @return int
+ */
+ public function getEndRange()
+ {
+ return $this->endRange;
+ }
+
+ /**
+ * @return array
+ */
+ public function getLines()
+ {
+ return $this->lines;
+ }
+
+ /**
+ * @param array $lines
+ */
+ public function setLines(array $lines)
+ {
+ $this->lines = $lines;
+ }
+}
diff --git a/vendor/sebastian/diff/src/Diff.php b/vendor/sebastian/diff/src/Diff.php
new file mode 100644
index 0000000..d3ab3ef
--- /dev/null
+++ b/vendor/sebastian/diff/src/Diff.php
@@ -0,0 +1,73 @@
+<?php
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Diff;
+
+class Diff
+{
+ /**
+ * @var string
+ */
+ private $from;
+
+ /**
+ * @var string
+ */
+ private $to;
+
+ /**
+ * @var Chunk[]
+ */
+ private $chunks;
+
+ /**
+ * @param string $from
+ * @param string $to
+ * @param Chunk[] $chunks
+ */
+ public function __construct($from, $to, array $chunks = array())
+ {
+ $this->from = $from;
+ $this->to = $to;
+ $this->chunks = $chunks;
+ }
+
+ /**
+ * @return string
+ */
+ public function getFrom()
+ {
+ return $this->from;
+ }
+
+ /**
+ * @return string
+ */
+ public function getTo()
+ {
+ return $this->to;
+ }
+
+ /**
+ * @return Chunk[]
+ */
+ public function getChunks()
+ {
+ return $this->chunks;
+ }
+
+ /**
+ * @param Chunk[] $chunks
+ */
+ public function setChunks(array $chunks)
+ {
+ $this->chunks = $chunks;
+ }
+}
diff --git a/vendor/sebastian/diff/src/Differ.php b/vendor/sebastian/diff/src/Differ.php
new file mode 100644
index 0000000..116c99c
--- /dev/null
+++ b/vendor/sebastian/diff/src/Differ.php
@@ -0,0 +1,399 @@
+<?php
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Diff;
+
+use SebastianBergmann\Diff\LCS\LongestCommonSubsequence;
+use SebastianBergmann\Diff\LCS\TimeEfficientImplementation;
+use SebastianBergmann\Diff\LCS\MemoryEfficientImplementation;
+
+/**
+ * Diff implementation.
+ */
+class Differ
+{
+ /**
+ * @var string
+ */
+ private $header;
+
+ /**
+ * @var bool
+ */
+ private $showNonDiffLines;
+
+ /**
+ * @param string $header
+ * @param bool $showNonDiffLines
+ */
+ public function __construct($header = "--- Original\n+++ New\n", $showNonDiffLines = true)
+ {
+ $this->header = $header;
+ $this->showNonDiffLines = $showNonDiffLines;
+ }
+
+ /**
+ * Returns the diff between two arrays or strings as string.
+ *
+ * @param array|string $from
+ * @param array|string $to
+ * @param LongestCommonSubsequence $lcs
+ *
+ * @return string
+ */
+ public function diff($from, $to, LongestCommonSubsequence $lcs = null)
+ {
+ $from = $this->validateDiffInput($from);
+ $to = $this->validateDiffInput($to);
+ $diff = $this->diffToArray($from, $to, $lcs);
+ $old = $this->checkIfDiffInOld($diff);
+ $start = isset($old[0]) ? $old[0] : 0;
+ $end = \count($diff);
+
+ if ($tmp = \array_search($end, $old)) {
+ $end = $tmp;
+ }
+
+ return $this->getBuffer($diff, $old, $start, $end);
+ }
+
+ /**
+ * Casts variable to string if it is not a string or array.
+ *
+ * @param mixed $input
+ *
+ * @return string
+ */
+ private function validateDiffInput($input)
+ {
+ if (!\is_array($input) && !\is_string($input)) {
+ return (string) $input;
+ }
+
+ return $input;
+ }
+
+ /**
+ * Takes input of the diff array and returns the old array.
+ * Iterates through diff line by line,
+ *
+ * @param array $diff
+ *
+ * @return array
+ */
+ private function checkIfDiffInOld(array $diff)
+ {
+ $inOld = false;
+ $i = 0;
+ $old = array();
+
+ foreach ($diff as $line) {
+ if ($line[1] === 0 /* OLD */) {
+ if ($inOld === false) {
+ $inOld = $i;
+ }
+ } elseif ($inOld !== false) {
+ if (($i - $inOld) > 5) {
+ $old[$inOld] = $i - 1;
+ }
+
+ $inOld = false;
+ }
+
+ ++$i;
+ }
+
+ return $old;
+ }
+
+ /**
+ * Generates buffer in string format, returning the patch.
+ *
+ * @param array $diff
+ * @param array $old
+ * @param int $start
+ * @param int $end
+ *
+ * @return string
+ */
+ private function getBuffer(array $diff, array $old, $start, $end)
+ {
+ $buffer = $this->header;
+
+ if (!isset($old[$start])) {
+ $buffer = $this->getDiffBufferElementNew($diff, $buffer, $start);
+ ++$start;
+ }
+
+ for ($i = $start; $i < $end; $i++) {
+ if (isset($old[$i])) {
+ $i = $old[$i];
+ $buffer = $this->getDiffBufferElementNew($diff, $buffer, $i);
+ } else {
+ $buffer = $this->getDiffBufferElement($diff, $buffer, $i);
+ }
+ }
+
+ return $buffer;
+ }
+
+ /**
+ * Gets individual buffer element.
+ *
+ * @param array $diff
+ * @param string $buffer
+ * @param int $diffIndex
+ *
+ * @return string
+ */
+ private function getDiffBufferElement(array $diff, $buffer, $diffIndex)
+ {
+ if ($diff[$diffIndex][1] === 1 /* ADDED */) {
+ $buffer .= '+' . $diff[$diffIndex][0] . "\n";
+ } elseif ($diff[$diffIndex][1] === 2 /* REMOVED */) {
+ $buffer .= '-' . $diff[$diffIndex][0] . "\n";
+ } elseif ($this->showNonDiffLines === true) {
+ $buffer .= ' ' . $diff[$diffIndex][0] . "\n";
+ }
+
+ return $buffer;
+ }
+
+ /**
+ * Gets individual buffer element with opening.
+ *
+ * @param array $diff
+ * @param string $buffer
+ * @param int $diffIndex
+ *
+ * @return string
+ */
+ private function getDiffBufferElementNew(array $diff, $buffer, $diffIndex)
+ {
+ if ($this->showNonDiffLines === true) {
+ $buffer .= "@@ @@\n";
+ }
+
+ return $this->getDiffBufferElement($diff, $buffer, $diffIndex);
+ }
+
+ /**
+ * 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 LongestCommonSubsequence $lcs
+ *
+ * @return array
+ */
+ public function diffToArray($from, $to, LongestCommonSubsequence $lcs = null)
+ {
+ if (\is_string($from)) {
+ $fromMatches = $this->getNewLineMatches($from);
+ $from = $this->splitStringByLines($from);
+ } elseif (\is_array($from)) {
+ $fromMatches = array();
+ } else {
+ throw new \InvalidArgumentException('"from" must be an array or string.');
+ }
+
+ if (\is_string($to)) {
+ $toMatches = $this->getNewLineMatches($to);
+ $to = $this->splitStringByLines($to);
+ } elseif (\is_array($to)) {
+ $toMatches = array();
+ } else {
+ throw new \InvalidArgumentException('"to" must be an array or string.');
+ }
+
+ list($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 = array();
+
+ if ($this->detectUnmatchedLineEndings($fromMatches, $toMatches)) {
+ $diff[] = array(
+ '#Warning: Strings contain different line endings!',
+ 0
+ );
+ }
+
+ foreach ($start as $token) {
+ $diff[] = array($token, 0 /* OLD */);
+ }
+
+ \reset($from);
+ \reset($to);
+
+ foreach ($common as $token) {
+ while (($fromToken = \reset($from)) !== $token) {
+ $diff[] = array(\array_shift($from), 2 /* REMOVED */);
+ }
+
+ while (($toToken = \reset($to)) !== $token) {
+ $diff[] = array(\array_shift($to), 1 /* ADDED */);
+ }
+
+ $diff[] = array($token, 0 /* OLD */);
+
+ \array_shift($from);
+ \array_shift($to);
+ }
+
+ while (($token = \array_shift($from)) !== null) {
+ $diff[] = array($token, 2 /* REMOVED */);
+ }
+
+ while (($token = \array_shift($to)) !== null) {
+ $diff[] = array($token, 1 /* ADDED */);
+ }
+
+ foreach ($end as $token) {
+ $diff[] = array($token, 0 /* OLD */);
+ }
+
+ return $diff;
+ }
+
+ /**
+ * Get new strings denoting new lines from a given string.
+ *
+ * @param string $string
+ *
+ * @return array
+ */
+ private function getNewLineMatches($string)
+ {
+ \preg_match_all('(\r\n|\r|\n)', $string, $stringMatches);
+
+ return $stringMatches;
+ }
+
+ /**
+ * Checks if input is string, if so it will split it line-by-line.
+ *
+ * @param string $input
+ *
+ * @return array
+ */
+ private function splitStringByLines($input)
+ {
+ return \preg_split('(\r\n|\r|\n)', $input);
+ }
+
+ /**
+ * @param array $from
+ * @param array $to
+ *
+ * @return LongestCommonSubsequence
+ */
+ private function selectLcsImplementation(array $from, array $to)
+ {
+ // 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 MemoryEfficientImplementation;
+ }
+
+ return new TimeEfficientImplementation;
+ }
+
+ /**
+ * Calculates the estimated memory footprint for the DP-based method.
+ *
+ * @param array $from
+ * @param array $to
+ *
+ * @return int|float
+ */
+ private function calculateEstimatedFootprint(array $from, array $to)
+ {
+ $itemSize = PHP_INT_SIZE === 4 ? 76 : 144;
+
+ return $itemSize * \pow(\min(\count($from), \count($to)), 2);
+ }
+
+ /**
+ * Returns true if line ends don't match on fromMatches and toMatches.
+ *
+ * @param array $fromMatches
+ * @param array $toMatches
+ *
+ * @return bool
+ */
+ private function detectUnmatchedLineEndings(array $fromMatches, array $toMatches)
+ {
+ return isset($fromMatches[0], $toMatches[0]) &&
+ \count($fromMatches[0]) === \count($toMatches[0]) &&
+ $fromMatches[0] !== $toMatches[0];
+ }
+
+ /**
+ * @param array $from
+ * @param array $to
+ *
+ * @return array
+ */
+ private static function getArrayDiffParted(array &$from, array &$to)
+ {
+ $start = array();
+ $end = array();
+
+ \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 = array($fromK => $from[$fromK]) + $end;
+ unset($from[$fromK], $to[$toK]);
+ } while (true);
+
+ return array($from, $to, $start, $end);
+ }
+}
diff --git a/vendor/sebastian/diff/src/LCS/LongestCommonSubsequence.php b/vendor/sebastian/diff/src/LCS/LongestCommonSubsequence.php
new file mode 100644
index 0000000..28674ab
--- /dev/null
+++ b/vendor/sebastian/diff/src/LCS/LongestCommonSubsequence.php
@@ -0,0 +1,27 @@
+<?php
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Diff\LCS;
+
+/**
+ * Interface for implementations of longest common subsequence calculation.
+ */
+interface LongestCommonSubsequence
+{
+ /**
+ * Calculates the longest common subsequence of two arrays.
+ *
+ * @param array $from
+ * @param array $to
+ *
+ * @return array
+ */
+ public function calculate(array $from, array $to);
+}
diff --git a/vendor/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php b/vendor/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php
new file mode 100644
index 0000000..c1b3121
--- /dev/null
+++ b/vendor/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php
@@ -0,0 +1,95 @@
+<?php
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Diff\LCS;
+
+/**
+ * Memory-efficient implementation of longest common subsequence calculation.
+ */
+class MemoryEfficientImplementation implements LongestCommonSubsequence
+{
+ /**
+ * Calculates the longest common subsequence of two arrays.
+ *
+ * @param array $from
+ * @param array $to
+ *
+ * @return array
+ */
+ public function calculate(array $from, array $to)
+ {
+ $cFrom = \count($from);
+ $cTo = \count($to);
+
+ if ($cFrom === 0) {
+ return array();
+ }
+
+ if ($cFrom === 1) {
+ if (\in_array($from[0], $to, true)) {
+ return array($from[0]);
+ }
+
+ return array();
+ }
+
+ $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)
+ );
+ }
+
+ /**
+ * @param array $from
+ * @param array $to
+ *
+ * @return array
+ */
+ private function length(array $from, array $to)
+ {
+ $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/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php b/vendor/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php
new file mode 100644
index 0000000..f31db3e
--- /dev/null
+++ b/vendor/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php
@@ -0,0 +1,74 @@
+<?php
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Diff\LCS;
+
+/**
+ * Time-efficient implementation of longest common subsequence calculation.
+ */
+class TimeEfficientImplementation implements LongestCommonSubsequence
+{
+ /**
+ * Calculates the longest common subsequence of two arrays.
+ *
+ * @param array $from
+ * @param array $to
+ *
+ * @return array
+ */
+ public function calculate(array $from, array $to)
+ {
+ $common = array();
+ $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/diff/src/Line.php b/vendor/sebastian/diff/src/Line.php
new file mode 100644
index 0000000..89b8683
--- /dev/null
+++ b/vendor/sebastian/diff/src/Line.php
@@ -0,0 +1,54 @@
+<?php
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Diff;
+
+class Line
+{
+ const ADDED = 1;
+ const REMOVED = 2;
+ const UNCHANGED = 3;
+
+ /**
+ * @var int
+ */
+ private $type;
+
+ /**
+ * @var string
+ */
+ private $content;
+
+ /**
+ * @param int $type
+ * @param string $content
+ */
+ public function __construct($type = self::UNCHANGED, $content = '')
+ {
+ $this->type = $type;
+ $this->content = $content;
+ }
+
+ /**
+ * @return string
+ */
+ public function getContent()
+ {
+ return $this->content;
+ }
+
+ /**
+ * @return int
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+}
diff --git a/vendor/sebastian/diff/src/Parser.php b/vendor/sebastian/diff/src/Parser.php
new file mode 100644
index 0000000..312c841
--- /dev/null
+++ b/vendor/sebastian/diff/src/Parser.php
@@ -0,0 +1,110 @@
+<?php
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Diff;
+
+/**
+ * Unified diff parser.
+ */
+class Parser
+{
+ /**
+ * @param string $string
+ *
+ * @return Diff[]
+ */
+ public function parse($string)
+ {
+ $lines = \preg_split('(\r\n|\r|\n)', $string);
+
+ if (!empty($lines) && $lines[\count($lines) - 1] == '') {
+ \array_pop($lines);
+ }
+
+ $lineCount = \count($lines);
+ $diffs = array();
+ $diff = null;
+ $collected = array();
+
+ for ($i = 0; $i < $lineCount; ++$i) {
+ if (\preg_match('(^---\\s+(?P<file>\\S+))', $lines[$i], $fromMatch) &&
+ \preg_match('(^\\+\\+\\+\\s+(?P<file>\\S+))', $lines[$i + 1], $toMatch)) {
+ if ($diff !== null) {
+ $this->parseFileDiff($diff, $collected);
+
+ $diffs[] = $diff;
+ $collected = array();
+ }
+
+ $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;
+ }
+
+ /**
+ * @param Diff $diff
+ * @param array $lines
+ */
+ private function parseFileDiff(Diff $diff, array $lines)
+ {
+ $chunks = array();
+ $chunk = null;
+
+ 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(
+ $match['start'],
+ isset($match['startrange']) ? \max(1, $match['startrange']) : 1,
+ $match['end'],
+ isset($match['endrange']) ? \max(1, $match['endrange']) : 1
+ );
+
+ $chunks[] = $chunk;
+ $diffLines = array();
+
+ 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/tests/ChunkTest.php b/vendor/sebastian/diff/tests/ChunkTest.php
new file mode 100644
index 0000000..d065c13
--- /dev/null
+++ b/vendor/sebastian/diff/tests/ChunkTest.php
@@ -0,0 +1,68 @@
+<?php
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Diff;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers SebastianBergmann\Diff\Chunk
+ */
+class ChunkTest extends TestCase
+{
+ /**
+ * @var Chunk
+ */
+ private $chunk;
+
+ protected function setUp()
+ {
+ $this->chunk = new Chunk;
+ }
+
+ public function testCanBeCreatedWithoutArguments()
+ {
+ $this->assertInstanceOf('SebastianBergmann\Diff\Chunk', $this->chunk);
+ }
+
+ public function testStartCanBeRetrieved()
+ {
+ $this->assertEquals(0, $this->chunk->getStart());
+ }
+
+ public function testStartRangeCanBeRetrieved()
+ {
+ $this->assertEquals(1, $this->chunk->getStartRange());
+ }
+
+ public function testEndCanBeRetrieved()
+ {
+ $this->assertEquals(0, $this->chunk->getEnd());
+ }
+
+ public function testEndRangeCanBeRetrieved()
+ {
+ $this->assertEquals(1, $this->chunk->getEndRange());
+ }
+
+ public function testLinesCanBeRetrieved()
+ {
+ $this->assertEquals(array(), $this->chunk->getLines());
+ }
+
+ public function testLinesCanBeSet()
+ {
+ $this->assertEquals(array(), $this->chunk->getLines());
+
+ $testValue = array('line0', 'line1');
+ $this->chunk->setLines($testValue);
+ $this->assertEquals($testValue, $this->chunk->getLines());
+ }
+}
diff --git a/vendor/sebastian/diff/tests/DiffTest.php b/vendor/sebastian/diff/tests/DiffTest.php
new file mode 100644
index 0000000..e1fa55d
--- /dev/null
+++ b/vendor/sebastian/diff/tests/DiffTest.php
@@ -0,0 +1,55 @@
+<?php
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Diff;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers SebastianBergmann\Diff\Diff
+ *
+ * @uses SebastianBergmann\Diff\Chunk
+ */
+final class DiffTest extends TestCase
+{
+ public function testGettersAfterConstructionWithDefault()
+ {
+ $from = 'line1a';
+ $to = 'line2a';
+ $diff = new Diff($from, $to);
+
+ $this->assertSame($from, $diff->getFrom());
+ $this->assertSame($to, $diff->getTo());
+ $this->assertSame(array(), $diff->getChunks(), 'Expect chunks to be default value "array()".');
+ }
+
+ public function testGettersAfterConstructionWithChunks()
+ {
+ $from = 'line1b';
+ $to = 'line2b';
+ $chunks = array(new Chunk(), new Chunk(2, 3));
+
+ $diff = new Diff($from, $to, $chunks);
+
+ $this->assertSame($from, $diff->getFrom());
+ $this->assertSame($to, $diff->getTo());
+ $this->assertSame($chunks, $diff->getChunks(), 'Expect chunks to be passed value.');
+ }
+
+ public function testSetChunksAfterConstruction()
+ {
+ $diff = new Diff('line1c', 'line2c');
+ $this->assertSame(array(), $diff->getChunks(), 'Expect chunks to be default value "array()".');
+
+ $chunks = array(new Chunk(), new Chunk(2, 3));
+ $diff->setChunks($chunks);
+ $this->assertSame($chunks, $diff->getChunks(), 'Expect chunks to be passed value.');
+ }
+}
diff --git a/vendor/sebastian/diff/tests/DifferTest.php b/vendor/sebastian/diff/tests/DifferTest.php
new file mode 100644
index 0000000..b9403f2
--- /dev/null
+++ b/vendor/sebastian/diff/tests/DifferTest.php
@@ -0,0 +1,415 @@
+<?php
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Diff;
+
+use SebastianBergmann\Diff\LCS\MemoryEfficientImplementation;
+use SebastianBergmann\Diff\LCS\TimeEfficientImplementation;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers SebastianBergmann\Diff\Differ
+ *
+ * @uses SebastianBergmann\Diff\LCS\MemoryEfficientImplementation
+ * @uses SebastianBergmann\Diff\LCS\TimeEfficientImplementation
+ * @uses SebastianBergmann\Diff\Chunk
+ * @uses SebastianBergmann\Diff\Diff
+ * @uses SebastianBergmann\Diff\Line
+ * @uses SebastianBergmann\Diff\Parser
+ */
+class DifferTest extends TestCase
+{
+ const REMOVED = 2;
+ const ADDED = 1;
+ const OLD = 0;
+
+ /**
+ * @var Differ
+ */
+ private $differ;
+
+ protected function setUp()
+ {
+ $this->differ = new Differ;
+ }
+
+ /**
+ * @param array $expected
+ * @param string|array $from
+ * @param string|array $to
+ * @dataProvider arrayProvider
+ */
+ public function testArrayRepresentationOfDiffCanBeRenderedUsingTimeEfficientLcsImplementation(array $expected, $from, $to)
+ {
+ $this->assertEquals($expected, $this->differ->diffToArray($from, $to, new TimeEfficientImplementation));
+ }
+
+ /**
+ * @param string $expected
+ * @param string $from
+ * @param string $to
+ * @dataProvider textProvider
+ */
+ public function testTextRepresentationOfDiffCanBeRenderedUsingTimeEfficientLcsImplementation($expected, $from, $to)
+ {
+ $this->assertEquals($expected, $this->differ->diff($from, $to, new TimeEfficientImplementation));
+ }
+
+ /**
+ * @param array $expected
+ * @param string|array $from
+ * @param string|array $to
+ * @dataProvider arrayProvider
+ */
+ public function testArrayRepresentationOfDiffCanBeRenderedUsingMemoryEfficientLcsImplementation(array $expected, $from, $to)
+ {
+ $this->assertEquals($expected, $this->differ->diffToArray($from, $to, new MemoryEfficientImplementation));
+ }
+
+ /**
+ * @param string $expected
+ * @param string $from
+ * @param string $to
+ * @dataProvider textProvider
+ */
+ public function testTextRepresentationOfDiffCanBeRenderedUsingMemoryEfficientLcsImplementation($expected, $from, $to)
+ {
+ $this->assertEquals($expected, $this->differ->diff($from, $to, new MemoryEfficientImplementation));
+ }
+
+ public function testCustomHeaderCanBeUsed()
+ {
+ $differ = new Differ('CUSTOM HEADER');
+
+ $this->assertEquals(
+ "CUSTOM HEADER@@ @@\n-a\n+b\n",
+ $differ->diff('a', 'b')
+ );
+ }
+
+ public function testTypesOtherThanArrayAndStringCanBePassed()
+ {
+ $this->assertEquals(
+ "--- Original\n+++ New\n@@ @@\n-1\n+2\n",
+ $this->differ->diff(1, 2)
+ );
+ }
+
+ /**
+ * @param string $diff
+ * @param Diff[] $expected
+ * @dataProvider diffProvider
+ */
+ public function testParser($diff, array $expected)
+ {
+ $parser = new Parser;
+ $result = $parser->parse($diff);
+
+ $this->assertEquals($expected, $result);
+ }
+
+ public function arrayProvider()
+ {
+ return array(
+ array(
+ array(
+ array('a', self::REMOVED),
+ array('b', self::ADDED)
+ ),
+ 'a',
+ 'b'
+ ),
+ array(
+ array(
+ array('ba', self::REMOVED),
+ array('bc', self::ADDED)
+ ),
+ 'ba',
+ 'bc'
+ ),
+ array(
+ array(
+ array('ab', self::REMOVED),
+ array('cb', self::ADDED)
+ ),
+ 'ab',
+ 'cb'
+ ),
+ array(
+ array(
+ array('abc', self::REMOVED),
+ array('adc', self::ADDED)
+ ),
+ 'abc',
+ 'adc'
+ ),
+ array(
+ array(
+ array('ab', self::REMOVED),
+ array('abc', self::ADDED)
+ ),
+ 'ab',
+ 'abc'
+ ),
+ array(
+ array(
+ array('bc', self::REMOVED),
+ array('abc', self::ADDED)
+ ),
+ 'bc',
+ 'abc'
+ ),
+ array(
+ array(
+ array('abc', self::REMOVED),
+ array('abbc', self::ADDED)
+ ),
+ 'abc',
+ 'abbc'
+ ),
+ array(
+ array(
+ array('abcdde', self::REMOVED),
+ array('abcde', self::ADDED)
+ ),
+ 'abcdde',
+ 'abcde'
+ ),
+ 'same start' => array(
+ array(
+ array(17, self::OLD),
+ array('b', self::REMOVED),
+ array('d', self::ADDED),
+ ),
+ array(30 => 17, 'a' => 'b'),
+ array(30 => 17, 'c' => 'd'),
+ ),
+ 'same end' => array(
+ array(
+ array(1, self::REMOVED),
+ array(2, self::ADDED),
+ array('b', self::OLD),
+ ),
+ array(1 => 1, 'a' => 'b'),
+ array(1 => 2, 'a' => 'b'),
+ ),
+ 'same start (2), same end (1)' => array(
+ array(
+ array(17, self::OLD),
+ array(2, self::OLD),
+ array(4, self::REMOVED),
+ array('a', self::ADDED),
+ array(5, self::ADDED),
+ array('x', self::OLD),
+ ),
+ array(30 => 17, 1 => 2, 2 => 4, 'z' => 'x'),
+ array(30 => 17, 1 => 2, 3 => 'a', 2 => 5, 'z' => 'x'),
+ ),
+ 'same' => array(
+ array(
+ array('x', self::OLD),
+ ),
+ array('z' => 'x'),
+ array('z' => 'x'),
+ ),
+ 'diff' => array(
+ array(
+ array('y', self::REMOVED),
+ array('x', self::ADDED),
+ ),
+ array('x' => 'y'),
+ array('z' => 'x'),
+ ),
+ 'diff 2' => array(
+ array(
+ array('y', self::REMOVED),
+ array('b', self::REMOVED),
+ array('x', self::ADDED),
+ array('d', self::ADDED),
+ ),
+ array('x' => 'y', 'a' => 'b'),
+ array('z' => 'x', 'c' => 'd'),
+ ),
+ 'test line diff detection' => array(
+ array(
+ array(
+ '#Warning: Strings contain different line endings!',
+ self::OLD,
+ ),
+ array(
+ '<?php',
+ self::OLD,
+ ),
+ array(
+ '',
+ self::OLD,
+ ),
+ ),
+ "<?php\r\n",
+ "<?php\n"
+ )
+ );
+ }
+
+ public function textProvider()
+ {
+ return array(
+ array(
+ "--- Original\n+++ New\n@@ @@\n-a\n+b\n",
+ 'a',
+ 'b'
+ ),
+ array(
+ "--- Original\n+++ New\n@@ @@\n-ba\n+bc\n",
+ 'ba',
+ 'bc'
+ ),
+ array(
+ "--- Original\n+++ New\n@@ @@\n-ab\n+cb\n",
+ 'ab',
+ 'cb'
+ ),
+ array(
+ "--- Original\n+++ New\n@@ @@\n-abc\n+adc\n",
+ 'abc',
+ 'adc'
+ ),
+ array(
+ "--- Original\n+++ New\n@@ @@\n-ab\n+abc\n",
+ 'ab',
+ 'abc'
+ ),
+ array(
+ "--- Original\n+++ New\n@@ @@\n-bc\n+abc\n",
+ 'bc',
+ 'abc'
+ ),
+ array(
+ "--- Original\n+++ New\n@@ @@\n-abc\n+abbc\n",
+ 'abc',
+ 'abbc'
+ ),
+ array(
+ "--- Original\n+++ New\n@@ @@\n-abcdde\n+abcde\n",
+ 'abcdde',
+ 'abcde'
+ ),
+ array(
+ "--- Original\n+++ New\n@@ @@\n-A\n+A1\n B\n",
+ "A\nB",
+ "A1\nB",
+ ),
+ array(
+ <<<EOF
+--- Original
++++ New
+@@ @@
+ a
+-b
++p
+@@ @@
+ i
+-j
++w
+ k
+
+EOF
+ ,
+ "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk",
+ "a\np\nc\nd\ne\nf\ng\nh\ni\nw\nk",
+ ),
+ array(
+ <<<EOF
+--- Original
++++ New
+@@ @@
+ a
+-b
++p
+@@ @@
+ i
+-j
++w
+ k
+
+EOF
+ ,
+ "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk",
+ "a\np\nc\nd\ne\nf\ng\nh\ni\nw\nk",
+ ),
+ );
+ }
+
+ public function diffProvider()
+ {
+ $serialized_arr = <<<EOL
+a:1:{i:0;O:27:"SebastianBergmann\Diff\Diff":3:{s:33:"
+EOL;
+
+ return array(
+ array(
+ "--- old.txt 2014-11-04 08:51:02.661868729 +0300\n+++ new.txt 2014-11-04 08:51:02.665868730 +0300\n@@ -1,3 +1,4 @@\n+2222111\n 1111111\n 1111111\n 1111111\n@@ -5,10 +6,8 @@\n 1111111\n 1111111\n 1111111\n +1121211\n 1111111\n -1111111\n -1111111\n -2222222\n 2222222\n 2222222\n 2222222\n@@ -17,5 +16,6 @@\n 2222222\n 2222222\n 2222222\n +2122212\n 2222222\n 2222222\n",
+ \unserialize($serialized_arr)
+ )
+ );
+ }
+
+ /**
+ * @param string $expected
+ * @param string $from
+ * @param string $to
+ * @dataProvider textForNoNonDiffLinesProvider
+ */
+ public function testDiffDoNotShowNonDiffLines($expected, $from, $to)
+ {
+ $differ = new Differ('', false);
+ $this->assertSame($expected, $differ->diff($from, $to));
+ }
+
+ public function textForNoNonDiffLinesProvider()
+ {
+ return array(
+ array(
+ '', 'a', 'a'
+ ),
+ array(
+ "-A\n+C\n",
+ "A\n\n\nB",
+ "C\n\n\nB",
+ ),
+ );
+ }
+
+ /**
+ * @requires PHPUnit 5.7
+ */
+ public function testDiffToArrayInvalidFromType()
+ {
+ $differ = new Differ;
+
+ $this->expectException('\InvalidArgumentException');
+ $this->expectExceptionMessageRegExp('#^"from" must be an array or string\.$#');
+
+ $differ->diffToArray(null, '');
+ }
+
+ /**
+ * @requires PHPUnit 5.7
+ */
+ public function testDiffInvalidToType()
+ {
+ $differ = new Differ;
+
+ $this->expectException('\InvalidArgumentException');
+ $this->expectExceptionMessageRegExp('#^"to" must be an array or string\.$#');
+
+ $differ->diffToArray('', new \stdClass);
+ }
+}
diff --git a/vendor/sebastian/diff/tests/LCS/LongestCommonSubsequenceTest.php b/vendor/sebastian/diff/tests/LCS/LongestCommonSubsequenceTest.php
new file mode 100644
index 0000000..b4b4084
--- /dev/null
+++ b/vendor/sebastian/diff/tests/LCS/LongestCommonSubsequenceTest.php
@@ -0,0 +1,198 @@
+<?php
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Diff\LCS;
+
+use PHPUnit\Framework\TestCase;
+
+abstract class LongestCommonSubsequenceTest extends TestCase
+{
+ /**
+ * @var LongestCommonSubsequence
+ */
+ private $implementation;
+
+ /**
+ * @var string
+ */
+ private $memoryLimit;
+
+ /**
+ * @var int[]
+ */
+ private $stress_sizes = array(1, 2, 3, 100, 500, 1000, 2000);
+
+ protected function setUp()
+ {
+ $this->memoryLimit = \ini_get('memory_limit');
+ \ini_set('memory_limit', '256M');
+
+ $this->implementation = $this->createImplementation();
+ }
+
+ /**
+ * @return LongestCommonSubsequence
+ */
+ abstract protected function createImplementation();
+
+ protected function tearDown()
+ {
+ \ini_set('memory_limit', $this->memoryLimit);
+ }
+
+ public function testBothEmpty()
+ {
+ $from = array();
+ $to = array();
+ $common = $this->implementation->calculate($from, $to);
+
+ $this->assertEquals(array(), $common);
+ }
+
+ public function testIsStrictComparison()
+ {
+ $from = array(
+ false, 0, 0.0, '', null, array(),
+ true, 1, 1.0, 'foo', array('foo', 'bar'), array('foo' => 'bar')
+ );
+ $to = $from;
+ $common = $this->implementation->calculate($from, $to);
+
+ $this->assertEquals($from, $common);
+
+ $to = array(
+ false, false, false, false, false, false,
+ true, true, true, true, true, true
+ );
+
+ $expected = array(
+ false,
+ true,
+ );
+
+ $common = $this->implementation->calculate($from, $to);
+
+ $this->assertEquals($expected, $common);
+ }
+
+ public function testEqualSequences()
+ {
+ foreach ($this->stress_sizes as $size) {
+ $range = \range(1, $size);
+ $from = $range;
+ $to = $range;
+ $common = $this->implementation->calculate($from, $to);
+
+ $this->assertEquals($range, $common);
+ }
+ }
+
+ public function testDistinctSequences()
+ {
+ $from = array('A');
+ $to = array('B');
+ $common = $this->implementation->calculate($from, $to);
+ $this->assertEquals(array(), $common);
+
+ $from = array('A', 'B', 'C');
+ $to = array('D', 'E', 'F');
+ $common = $this->implementation->calculate($from, $to);
+ $this->assertEquals(array(), $common);
+
+ foreach ($this->stress_sizes as $size) {
+ $from = \range(1, $size);
+ $to = \range($size + 1, $size * 2);
+ $common = $this->implementation->calculate($from, $to);
+ $this->assertEquals(array(), $common);
+ }
+ }
+
+ public function testCommonSubsequence()
+ {
+ $from = array('A', 'C', 'E', 'F', 'G');
+ $to = array('A', 'B', 'D', 'E', 'H');
+ $expected = array('A', 'E');
+ $common = $this->implementation->calculate($from, $to);
+ $this->assertEquals($expected, $common);
+
+ $from = array('A', 'C', 'E', 'F', 'G');
+ $to = array('B', 'C', 'D', 'E', 'F', 'H');
+ $expected = array('C', 'E', 'F');
+ $common = $this->implementation->calculate($from, $to);
+ $this->assertEquals($expected, $common);
+
+ foreach ($this->stress_sizes as $size) {
+ $from = $size < 2 ? array(1) : \range(1, $size + 1, 2);
+ $to = $size < 3 ? array(1) : \range(1, $size + 1, 3);
+ $expected = $size < 6 ? array(1) : \range(1, $size + 1, 6);
+ $common = $this->implementation->calculate($from, $to);
+
+ $this->assertEquals($expected, $common);
+ }
+ }
+
+ public function testSingleElementSubsequenceAtStart()
+ {
+ foreach ($this->stress_sizes as $size) {
+ $from = \range(1, $size);
+ $to = \array_slice($from, 0, 1);
+ $common = $this->implementation->calculate($from, $to);
+
+ $this->assertEquals($to, $common);
+ }
+ }
+
+ public function testSingleElementSubsequenceAtMiddle()
+ {
+ foreach ($this->stress_sizes as $size) {
+ $from = \range(1, $size);
+ $to = \array_slice($from, (int) $size / 2, 1);
+ $common = $this->implementation->calculate($from, $to);
+
+ $this->assertEquals($to, $common);
+ }
+ }
+
+ public function testSingleElementSubsequenceAtEnd()
+ {
+ foreach ($this->stress_sizes as $size) {
+ $from = \range(1, $size);
+ $to = \array_slice($from, $size - 1, 1);
+ $common = $this->implementation->calculate($from, $to);
+
+ $this->assertEquals($to, $common);
+ }
+ }
+
+ public function testReversedSequences()
+ {
+ $from = array('A', 'B');
+ $to = array('B', 'A');
+ $expected = array('A');
+ $common = $this->implementation->calculate($from, $to);
+ $this->assertEquals($expected, $common);
+
+ foreach ($this->stress_sizes as $size) {
+ $from = \range(1, $size);
+ $to = \array_reverse($from);
+ $common = $this->implementation->calculate($from, $to);
+
+ $this->assertEquals(array(1), $common);
+ }
+ }
+
+ public function testStrictTypeCalculate()
+ {
+ $diff = $this->implementation->calculate(array('5'), array('05'));
+
+ $this->assertInternalType('array', $diff);
+ $this->assertCount(0, $diff);
+ }
+}
diff --git a/vendor/sebastian/diff/tests/LCS/MemoryEfficientImplementationTest.php b/vendor/sebastian/diff/tests/LCS/MemoryEfficientImplementationTest.php
new file mode 100644
index 0000000..b0e57a4
--- /dev/null
+++ b/vendor/sebastian/diff/tests/LCS/MemoryEfficientImplementationTest.php
@@ -0,0 +1,22 @@
+<?php
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Diff\LCS;
+
+/**
+ * @covers SebastianBergmann\Diff\LCS\MemoryEfficientImplementation
+ */
+class MemoryEfficientImplementationTest extends LongestCommonSubsequenceTest
+{
+ protected function createImplementation()
+ {
+ return new MemoryEfficientImplementation;
+ }
+}
diff --git a/vendor/sebastian/diff/tests/LCS/TimeEfficientImplementationTest.php b/vendor/sebastian/diff/tests/LCS/TimeEfficientImplementationTest.php
new file mode 100644
index 0000000..a3ecb57
--- /dev/null
+++ b/vendor/sebastian/diff/tests/LCS/TimeEfficientImplementationTest.php
@@ -0,0 +1,22 @@
+<?php
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Diff\LCS;
+
+/**
+ * @covers SebastianBergmann\Diff\LCS\TimeEfficientImplementation
+ */
+class TimeEfficientImplementationTest extends LongestCommonSubsequenceTest
+{
+ protected function createImplementation()
+ {
+ return new TimeEfficientImplementation;
+ }
+}
diff --git a/vendor/sebastian/diff/tests/LineTest.php b/vendor/sebastian/diff/tests/LineTest.php
new file mode 100644
index 0000000..6fd8c16
--- /dev/null
+++ b/vendor/sebastian/diff/tests/LineTest.php
@@ -0,0 +1,44 @@
+<?php
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Diff;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers SebastianBergmann\Diff\Line
+ */
+class LineTest extends TestCase
+{
+ /**
+ * @var Line
+ */
+ private $line;
+
+ protected function setUp()
+ {
+ $this->line = new Line;
+ }
+
+ public function testCanBeCreatedWithoutArguments()
+ {
+ $this->assertInstanceOf('SebastianBergmann\Diff\Line', $this->line);
+ }
+
+ public function testTypeCanBeRetrieved()
+ {
+ $this->assertEquals(Line::UNCHANGED, $this->line->getType());
+ }
+
+ public function testContentCanBeRetrieved()
+ {
+ $this->assertEquals('', $this->line->getContent());
+ }
+}
diff --git a/vendor/sebastian/diff/tests/ParserTest.php b/vendor/sebastian/diff/tests/ParserTest.php
new file mode 100644
index 0000000..0963d83
--- /dev/null
+++ b/vendor/sebastian/diff/tests/ParserTest.php
@@ -0,0 +1,151 @@
+<?php
+/*
+ * This file is part of sebastian/diff.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Diff;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers SebastianBergmann\Diff\Parser
+ *
+ * @uses SebastianBergmann\Diff\Chunk
+ * @uses SebastianBergmann\Diff\Diff
+ * @uses SebastianBergmann\Diff\Line
+ */
+class ParserTest extends TestCase
+{
+ /**
+ * @var Parser
+ */
+ private $parser;
+
+ protected function setUp()
+ {
+ $this->parser = new Parser;
+ }
+
+ public function testParse()
+ {
+ $content = \file_get_contents(__DIR__ . '/fixtures/patch.txt');
+
+ $diffs = $this->parser->parse($content);
+
+ $this->assertInternalType('array', $diffs);
+ $this->assertContainsOnlyInstancesOf('SebastianBergmann\Diff\Diff', $diffs);
+ $this->assertCount(1, $diffs);
+
+ $chunks = $diffs[0]->getChunks();
+ $this->assertInternalType('array', $chunks);
+ $this->assertContainsOnlyInstancesOf('SebastianBergmann\Diff\Chunk', $chunks);
+
+ $this->assertCount(1, $chunks);
+
+ $this->assertEquals(20, $chunks[0]->getStart());
+
+ $this->assertCount(4, $chunks[0]->getLines());
+ }
+
+ public function testParseWithMultipleChunks()
+ {
+ $content = \file_get_contents(__DIR__ . '/fixtures/patch2.txt');
+
+ $diffs = $this->parser->parse($content);
+
+ $this->assertCount(1, $diffs);
+
+ $chunks = $diffs[0]->getChunks();
+ $this->assertCount(3, $chunks);
+
+ $this->assertEquals(20, $chunks[0]->getStart());
+ $this->assertEquals(320, $chunks[1]->getStart());
+ $this->assertEquals(600, $chunks[2]->getStart());
+
+ $this->assertCount(5, $chunks[0]->getLines());
+ $this->assertCount(5, $chunks[1]->getLines());
+ $this->assertCount(4, $chunks[2]->getLines());
+ }
+
+ public function testParseWithRemovedLines()
+ {
+ $content = <<<A
+diff --git a/Test.txt b/Test.txt
+index abcdefg..abcdefh 100644
+--- a/Test.txt
++++ b/Test.txt
+@@ -49,9 +49,8 @@
+ A
+-B
+A;
+ $diffs = $this->parser->parse($content);
+ $this->assertInternalType('array', $diffs);
+ $this->assertContainsOnlyInstancesOf('SebastianBergmann\Diff\Diff', $diffs);
+ $this->assertCount(1, $diffs);
+
+ $chunks = $diffs[0]->getChunks();
+
+ $this->assertInternalType('array', $chunks);
+ $this->assertContainsOnlyInstancesOf('SebastianBergmann\Diff\Chunk', $chunks);
+ $this->assertCount(1, $chunks);
+
+ $chunk = $chunks[0];
+ $this->assertSame(49, $chunk->getStart());
+ $this->assertSame(49, $chunk->getEnd());
+ $this->assertSame(9, $chunk->getStartRange());
+ $this->assertSame(8, $chunk->getEndRange());
+
+ $lines = $chunk->getLines();
+ $this->assertInternalType('array', $lines);
+ $this->assertContainsOnlyInstancesOf('SebastianBergmann\Diff\Line', $lines);
+ $this->assertCount(2, $lines);
+
+ /** @var Line $line */
+ $line = $lines[0];
+ $this->assertSame('A', $line->getContent());
+ $this->assertSame(Line::UNCHANGED, $line->getType());
+
+ $line = $lines[1];
+ $this->assertSame('B', $line->getContent());
+ $this->assertSame(Line::REMOVED, $line->getType());
+ }
+
+ public function testParseDiffForMulitpleFiles()
+ {
+ $content = <<<A
+diff --git a/Test.txt b/Test.txt
+index abcdefg..abcdefh 100644
+--- a/Test.txt
++++ b/Test.txt
+@@ -1,3 +1,2 @@
+ A
+-B
+
+diff --git a/Test123.txt b/Test123.txt
+index abcdefg..abcdefh 100644
+--- a/Test2.txt
++++ b/Test2.txt
+@@ -1,2 +1,3 @@
+ A
++B
+A;
+ $diffs = $this->parser->parse($content);
+ $this->assertCount(2, $diffs);
+
+ /** @var Diff $diff */
+ $diff = $diffs[0];
+ $this->assertSame('a/Test.txt', $diff->getFrom());
+ $this->assertSame('b/Test.txt', $diff->getTo());
+ $this->assertCount(1, $diff->getChunks());
+
+ $diff = $diffs[1];
+ $this->assertSame('a/Test2.txt', $diff->getFrom());
+ $this->assertSame('b/Test2.txt', $diff->getTo());
+ $this->assertCount(1, $diff->getChunks());
+ }
+}
diff --git a/vendor/sebastian/diff/tests/fixtures/patch.txt b/vendor/sebastian/diff/tests/fixtures/patch.txt
new file mode 100644
index 0000000..144b61d
--- /dev/null
+++ b/vendor/sebastian/diff/tests/fixtures/patch.txt
@@ -0,0 +1,9 @@
+diff --git a/Foo.php b/Foo.php
+index abcdefg..abcdefh 100644
+--- a/Foo.php
++++ b/Foo.php
+@@ -20,4 +20,5 @@ class Foo
+ const ONE = 1;
+ const TWO = 2;
++ const THREE = 3;
+ const FOUR = 4;
diff --git a/vendor/sebastian/diff/tests/fixtures/patch2.txt b/vendor/sebastian/diff/tests/fixtures/patch2.txt
new file mode 100644
index 0000000..41fbc95
--- /dev/null
+++ b/vendor/sebastian/diff/tests/fixtures/patch2.txt
@@ -0,0 +1,21 @@
+diff --git a/Foo.php b/Foo.php
+index abcdefg..abcdefh 100644
+--- a/Foo.php
++++ b/Foo.php
+@@ -20,4 +20,5 @@ class Foo
+ const ONE = 1;
+ const TWO = 2;
++ const THREE = 3;
+ const FOUR = 4;
+
+@@ -320,4 +320,5 @@ class Foo
+ const A = 'A';
+ const B = 'B';
++ const C = 'C';
+ const D = 'D';
+
+@@ -600,4 +600,5 @@ class Foo
+ public function doSomething() {
+
++ return 'foo';
+ }
diff --git a/vendor/sebastian/environment/.gitignore b/vendor/sebastian/environment/.gitignore
new file mode 100644
index 0000000..441848b
--- /dev/null
+++ b/vendor/sebastian/environment/.gitignore
@@ -0,0 +1,4 @@
+/.idea
+/vendor
+/composer.lock
+/composer.phar
diff --git a/vendor/sebastian/environment/.travis.yml b/vendor/sebastian/environment/.travis.yml
new file mode 100644
index 0000000..8dc204b
--- /dev/null
+++ b/vendor/sebastian/environment/.travis.yml
@@ -0,0 +1,16 @@
+language: php
+
+sudo: false
+
+before_install:
+ - composer self-update
+
+install:
+ - travis_retry composer install --no-interaction --prefer-source
+
+php:
+ - 5.6
+ - hhvm
+
+notifications:
+ email: false
diff --git a/vendor/sebastian/environment/LICENSE b/vendor/sebastian/environment/LICENSE
new file mode 100644
index 0000000..08539af
--- /dev/null
+++ b/vendor/sebastian/environment/LICENSE
@@ -0,0 +1,33 @@
+Environment
+
+Copyright (c) 2014-2015, Sebastian Bergmann <sebastian@phpunit.de>.
+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 0000000..c0f3a6d
--- /dev/null
+++ b/vendor/sebastian/environment/README.md
@@ -0,0 +1,72 @@
+# Environment
+
+This component provides functionality that helps writing PHP code that has runtime-specific (PHP / HHVM) execution paths.
+
+[![Latest Stable Version](https://poser.pugx.org/sebastian/environment/v/stable.png)](https://packagist.org/packages/sebastian/environment)
+[![Build Status](https://travis-ci.org/sebastianbergmann/environment.png?branch=master)](https://travis-ci.org/sebastianbergmann/environment)
+
+## 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
+
+## Usage
+
+```php
+<?php
+use SebastianBergmann\Environment\Runtime;
+
+$runtime = new Runtime;
+
+var_dump($runtime->getNameWithVersion());
+var_dump($runtime->getName());
+var_dump($runtime->getVersion());
+var_dump($runtime->getBinary());
+var_dump($runtime->isHHVM());
+var_dump($runtime->isPHP());
+var_dump($runtime->hasXdebug());
+var_dump($runtime->canCollectCodeCoverage());
+```
+
+### Output on PHP
+
+ $ php --version
+ PHP 5.5.8 (cli) (built: Jan 9 2014 08:33:30)
+ Copyright (c) 1997-2013 The PHP Group
+ Zend Engine v2.5.0, Copyright (c) 1998-2013 Zend Technologies
+ with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans
+
+
+ $ php example.php
+ string(9) "PHP 5.5.8"
+ string(3) "PHP"
+ string(5) "5.5.8"
+ string(14) "'/usr/bin/php'"
+ bool(false)
+ bool(true)
+ bool(true)
+ bool(true)
+
+### Output on HHVM
+
+ $ hhvm --version
+ HipHop VM 2.4.0-dev (rel)
+ Compiler: heads/master-0-ga98e57cabee7e7f0d14493ab17d5c7ab0157eb98
+ Repo schema: 8d6e69287c41c1f09bb4d327421720d1922cfc67
+
+
+ $ hhvm example.php
+ string(14) "HHVM 2.4.0-dev"
+ string(4) "HHVM"
+ string(9) "2.4.0-dev"
+ string(42) "'/usr/local/src/hhvm/hphp/hhvm/hhvm' --php"
+ bool(true)
+ bool(false)
+ bool(false)
+ bool(true)
+
diff --git a/vendor/sebastian/environment/build.xml b/vendor/sebastian/environment/build.xml
new file mode 100644
index 0000000..92fb1c5
--- /dev/null
+++ b/vendor/sebastian/environment/build.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="environment">
+ <target name="clean" description="Cleanup build artifacts">
+ <delete dir="${basedir}/vendor"/>
+ <delete file="${basedir}/composer.lock"/>
+ </target>
+
+ <target name="composer" depends="clean" description="Install dependencies with Composer">
+ <tstamp>
+ <format property="thirty.days.ago" pattern="MM/dd/yyyy hh:mm aa" offset="-30" unit="day"/>
+ </tstamp>
+ <delete>
+ <fileset dir="${basedir}">
+ <include name="composer.phar" />
+ <date datetime="${thirty.days.ago}" when="before"/>
+ </fileset>
+ </delete>
+
+ <get src="https://getcomposer.org/composer.phar" dest="${basedir}/composer.phar" skipexisting="true"/>
+
+ <exec executable="php">
+ <arg value="composer.phar"/>
+ <arg value="install"/>
+ </exec>
+ </target>
+</project>
diff --git a/vendor/sebastian/environment/composer.json b/vendor/sebastian/environment/composer.json
new file mode 100644
index 0000000..30fe435
--- /dev/null
+++ b/vendor/sebastian/environment/composer.json
@@ -0,0 +1,30 @@
+{
+ "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": "sebastian@phpunit.de"
+ }
+ ],
+ "prefer-stable": true,
+ "require": {
+ "php": "^5.6 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.0"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/environment/phpunit.xml b/vendor/sebastian/environment/phpunit.xml
new file mode 100644
index 0000000..f3b710c
--- /dev/null
+++ b/vendor/sebastian/environment/phpunit.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/5.4/phpunit.xsd"
+ bootstrap="vendor/autoload.php"
+ backupGlobals="false"
+ beStrictAboutCoversAnnotation="true"
+ beStrictAboutOutputDuringTests="true"
+ beStrictAboutTestsThatDoNotTestAnything="true"
+ beStrictAboutTodoAnnotatedTests="true"
+ verbose="true">
+ <testsuite>
+ <directory suffix="Test.php">tests</directory>
+ </testsuite>
+
+ <filter>
+ <whitelist processUncoveredFilesFromWhitelist="true">
+ <directory suffix=".php">src</directory>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/vendor/sebastian/environment/src/Console.php b/vendor/sebastian/environment/src/Console.php
new file mode 100644
index 0000000..85d807a
--- /dev/null
+++ b/vendor/sebastian/environment/src/Console.php
@@ -0,0 +1,113 @@
+<?php
+/*
+ * This file is part of the Environment package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Environment;
+
+/**
+ */
+class Console
+{
+ const STDIN = 0;
+ const STDOUT = 1;
+ const STDERR = 2;
+
+ /**
+ * Returns true if STDOUT supports colorization.
+ *
+ * This code has been copied and adapted from
+ * Symfony\Component\Console\Output\OutputStream.
+ *
+ * @return bool
+ */
+ public function hasColorSupport()
+ {
+ if (DIRECTORY_SEPARATOR == '\\') {
+ return false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI') || 'xterm' === getenv('TERM');
+ }
+
+ if (!defined('STDOUT')) {
+ return false;
+ }
+
+ return $this->isInteractive(STDOUT);
+ }
+
+ /**
+ * Returns the number of columns of the terminal.
+ *
+ * @return int
+ */
+ public function getNumberOfColumns()
+ {
+ if (DIRECTORY_SEPARATOR == '\\') {
+ $columns = 80;
+
+ if (preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim(getenv('ANSICON')), $matches)) {
+ $columns = $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 = $matches[2];
+ }
+ }
+ }
+
+ return $columns - 1;
+ }
+
+ if (!$this->isInteractive(self::STDIN)) {
+ return 80;
+ }
+
+ 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;
+ }
+
+ /**
+ * Returns if the file descriptor is an interactive terminal or not.
+ *
+ * @param int|resource $fileDescriptor
+ *
+ * @return bool
+ */
+ public function isInteractive($fileDescriptor = self::STDOUT)
+ {
+ return function_exists('posix_isatty') && @posix_isatty($fileDescriptor);
+ }
+}
diff --git a/vendor/sebastian/environment/src/Runtime.php b/vendor/sebastian/environment/src/Runtime.php
new file mode 100644
index 0000000..719b7b9
--- /dev/null
+++ b/vendor/sebastian/environment/src/Runtime.php
@@ -0,0 +1,194 @@
+<?php
+/*
+ * This file is part of the Environment package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Environment;
+
+/**
+ * Utility class for HHVM/PHP environment handling.
+ */
+class Runtime
+{
+ /**
+ * @var string
+ */
+ private static $binary;
+
+ /**
+ * Returns true when Xdebug is supported or
+ * the runtime used is PHPDBG (PHP >= 7.0).
+ *
+ * @return bool
+ */
+ public function canCollectCodeCoverage()
+ {
+ return $this->hasXdebug() || $this->hasPHPDBGCodeCoverage();
+ }
+
+ /**
+ * Returns the path to the binary of the current runtime.
+ * Appends ' --php' to the path when the runtime is HHVM.
+ *
+ * @return string
+ */
+ public function getBinary()
+ {
+ // HHVM
+ if (self::$binary === null && $this->isHHVM()) {
+ if ((self::$binary = getenv('PHP_BINARY')) === false) {
+ self::$binary = PHP_BINARY;
+ }
+
+ self::$binary = escapeshellarg(self::$binary) . ' --php';
+ }
+
+ // PHP >= 5.4.0
+ if (self::$binary === null && defined('PHP_BINARY')) {
+ if (PHP_BINARY !== '') {
+ self::$binary = escapeshellarg(PHP_BINARY);
+ }
+ }
+
+ // PHP < 5.4.0
+ if (self::$binary === null) {
+ if (PHP_SAPI == 'cli' && isset($_SERVER['_'])) {
+ if (strpos($_SERVER['_'], 'phpunit') !== false) {
+ $file = file($_SERVER['_']);
+
+ if (strpos($file[0], ' ') !== false) {
+ $tmp = explode(' ', $file[0]);
+ self::$binary = escapeshellarg(trim($tmp[1]));
+ } else {
+ self::$binary = escapeshellarg(ltrim(trim($file[0]), '#!'));
+ }
+ } elseif (strpos(basename($_SERVER['_']), 'php') !== false) {
+ self::$binary = escapeshellarg($_SERVER['_']);
+ }
+ }
+ }
+
+ if (self::$binary === null) {
+ $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;
+ }
+ }
+ }
+
+ if (self::$binary === null) {
+ self::$binary = 'php';
+ }
+
+ return self::$binary;
+ }
+
+ /**
+ * @return string
+ */
+ public function getNameWithVersion()
+ {
+ return $this->getName() . ' ' . $this->getVersion();
+ }
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ if ($this->isHHVM()) {
+ return 'HHVM';
+ } elseif ($this->isPHPDBG()) {
+ return 'PHPDBG';
+ } else {
+ return 'PHP';
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function getVendorUrl()
+ {
+ if ($this->isHHVM()) {
+ return 'http://hhvm.com/';
+ } else {
+ return 'https://secure.php.net/';
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function getVersion()
+ {
+ if ($this->isHHVM()) {
+ return HHVM_VERSION;
+ } else {
+ return PHP_VERSION;
+ }
+ }
+
+ /**
+ * Returns true when the runtime used is PHP and Xdebug is loaded.
+ *
+ * @return bool
+ */
+ public function hasXdebug()
+ {
+ return ($this->isPHP() || $this->isHHVM()) && extension_loaded('xdebug');
+ }
+
+ /**
+ * Returns true when the runtime used is HHVM.
+ *
+ * @return bool
+ */
+ public function isHHVM()
+ {
+ return defined('HHVM_VERSION');
+ }
+
+ /**
+ * Returns true when the runtime used is PHP without the PHPDBG SAPI.
+ *
+ * @return bool
+ */
+ public function isPHP()
+ {
+ return !$this->isHHVM() && !$this->isPHPDBG();
+ }
+
+ /**
+ * Returns true when the runtime used is PHP with the PHPDBG SAPI.
+ *
+ * @return bool
+ */
+ public function isPHPDBG()
+ {
+ 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).
+ *
+ * @return bool
+ */
+ public function hasPHPDBGCodeCoverage()
+ {
+ return $this->isPHPDBG() && function_exists('phpdbg_start_oplog');
+ }
+}
diff --git a/vendor/sebastian/environment/tests/ConsoleTest.php b/vendor/sebastian/environment/tests/ConsoleTest.php
new file mode 100644
index 0000000..5ce900a
--- /dev/null
+++ b/vendor/sebastian/environment/tests/ConsoleTest.php
@@ -0,0 +1,62 @@
+<?php
+/*
+ * This file is part of the Environment package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Environment;
+
+use PHPUnit_Framework_TestCase;
+
+class ConsoleTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @var \SebastianBergmann\Environment\Console
+ */
+ private $console;
+
+ protected function setUp()
+ {
+ $this->console = new Console;
+ }
+
+ /**
+ * @covers \SebastianBergmann\Environment\Console::isInteractive
+ */
+ public function testCanDetectIfStdoutIsInteractiveByDefault()
+ {
+ $this->assertInternalType('boolean', $this->console->isInteractive());
+ }
+
+ /**
+ * @covers \SebastianBergmann\Environment\Console::isInteractive
+ */
+ public function testCanDetectIfFileDescriptorIsInteractive()
+ {
+ $this->assertInternalType('boolean', $this->console->isInteractive(STDOUT));
+ }
+
+ /**
+ * @covers \SebastianBergmann\Environment\Console::hasColorSupport
+ *
+ * @uses \SebastianBergmann\Environment\Console::isInteractive
+ */
+ public function testCanDetectColorSupport()
+ {
+ $this->assertInternalType('boolean', $this->console->hasColorSupport());
+ }
+
+ /**
+ * @covers \SebastianBergmann\Environment\Console::getNumberOfColumns
+ *
+ * @uses \SebastianBergmann\Environment\Console::isInteractive
+ */
+ public function testCanDetectNumberOfColumns()
+ {
+ $this->assertInternalType('integer', $this->console->getNumberOfColumns());
+ }
+}
diff --git a/vendor/sebastian/environment/tests/RuntimeTest.php b/vendor/sebastian/environment/tests/RuntimeTest.php
new file mode 100644
index 0000000..fbe9aef
--- /dev/null
+++ b/vendor/sebastian/environment/tests/RuntimeTest.php
@@ -0,0 +1,120 @@
+<?php
+/*
+ * This file is part of the Environment package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Environment;
+
+use PHPUnit_Framework_TestCase;
+
+class RuntimeTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @var \SebastianBergmann\Environment\Runtime
+ */
+ private $env;
+
+ protected function setUp()
+ {
+ $this->env = new Runtime;
+ }
+
+ /**
+ * @covers \SebastianBergmann\Environment\Runtime::canCollectCodeCoverage
+ *
+ * @uses \SebastianBergmann\Environment\Runtime::hasXdebug
+ * @uses \SebastianBergmann\Environment\Runtime::isHHVM
+ * @uses \SebastianBergmann\Environment\Runtime::isPHP
+ */
+ public function testAbilityToCollectCodeCoverageCanBeAssessed()
+ {
+ $this->assertInternalType('boolean', $this->env->canCollectCodeCoverage());
+ }
+
+ /**
+ * @covers \SebastianBergmann\Environment\Runtime::getBinary
+ *
+ * @uses \SebastianBergmann\Environment\Runtime::isHHVM
+ */
+ public function testBinaryCanBeRetrieved()
+ {
+ $this->assertInternalType('string', $this->env->getBinary());
+ }
+
+ /**
+ * @covers \SebastianBergmann\Environment\Runtime::isHHVM
+ */
+ public function testCanBeDetected()
+ {
+ $this->assertInternalType('boolean', $this->env->isHHVM());
+ }
+
+ /**
+ * @covers \SebastianBergmann\Environment\Runtime::isPHP
+ *
+ * @uses \SebastianBergmann\Environment\Runtime::isHHVM
+ */
+ public function testCanBeDetected2()
+ {
+ $this->assertInternalType('boolean', $this->env->isPHP());
+ }
+
+ /**
+ * @covers \SebastianBergmann\Environment\Runtime::hasXdebug
+ *
+ * @uses \SebastianBergmann\Environment\Runtime::isHHVM
+ * @uses \SebastianBergmann\Environment\Runtime::isPHP
+ */
+ public function testXdebugCanBeDetected()
+ {
+ $this->assertInternalType('boolean', $this->env->hasXdebug());
+ }
+
+ /**
+ * @covers \SebastianBergmann\Environment\Runtime::getNameWithVersion
+ *
+ * @uses \SebastianBergmann\Environment\Runtime::getName
+ * @uses \SebastianBergmann\Environment\Runtime::getVersion
+ * @uses \SebastianBergmann\Environment\Runtime::isHHVM
+ * @uses \SebastianBergmann\Environment\Runtime::isPHP
+ */
+ public function testNameAndVersionCanBeRetrieved()
+ {
+ $this->assertInternalType('string', $this->env->getNameWithVersion());
+ }
+
+ /**
+ * @covers \SebastianBergmann\Environment\Runtime::getName
+ *
+ * @uses \SebastianBergmann\Environment\Runtime::isHHVM
+ */
+ public function testNameCanBeRetrieved()
+ {
+ $this->assertInternalType('string', $this->env->getName());
+ }
+
+ /**
+ * @covers \SebastianBergmann\Environment\Runtime::getVersion
+ *
+ * @uses \SebastianBergmann\Environment\Runtime::isHHVM
+ */
+ public function testVersionCanBeRetrieved()
+ {
+ $this->assertInternalType('string', $this->env->getVersion());
+ }
+
+ /**
+ * @covers \SebastianBergmann\Environment\Runtime::getVendorUrl
+ *
+ * @uses \SebastianBergmann\Environment\Runtime::isHHVM
+ */
+ public function testVendorUrlCanBeRetrieved()
+ {
+ $this->assertInternalType('string', $this->env->getVendorUrl());
+ }
+}
diff --git a/vendor/sebastian/exporter/.gitignore b/vendor/sebastian/exporter/.gitignore
new file mode 100644
index 0000000..3beb10f
--- /dev/null
+++ b/vendor/sebastian/exporter/.gitignore
@@ -0,0 +1,9 @@
+.idea
+phpunit.xml
+composer.lock
+composer.phar
+vendor/
+cache.properties
+build/LICENSE
+build/README.md
+build/*.tgz
diff --git a/vendor/sebastian/exporter/.travis.yml b/vendor/sebastian/exporter/.travis.yml
new file mode 100644
index 0000000..657519b
--- /dev/null
+++ b/vendor/sebastian/exporter/.travis.yml
@@ -0,0 +1,23 @@
+language: php
+
+before_script:
+ - composer self-update
+ - composer install --no-interaction --prefer-source --dev
+
+php:
+ - 5.3.3
+ - 5.3
+ - 5.4
+ - 5.5
+ - 5.6
+ - hhvm
+
+notifications:
+ email: false
+ webhooks:
+ urls:
+ - https://webhooks.gitter.im/e/6668f52f3dd4e3f81960
+ on_success: always
+ on_failure: always
+ on_start: false
+
diff --git a/vendor/sebastian/exporter/LICENSE b/vendor/sebastian/exporter/LICENSE
new file mode 100644
index 0000000..55a13d4
--- /dev/null
+++ b/vendor/sebastian/exporter/LICENSE
@@ -0,0 +1,33 @@
+Exporter
+
+Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
+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 0000000..7bbef50
--- /dev/null
+++ b/vendor/sebastian/exporter/README.md
@@ -0,0 +1,172 @@
+Exporter
+========
+
+[![Build Status](https://secure.travis-ci.org/sebastianbergmann/exporter.png?branch=master)](https://travis-ci.org/sebastianbergmann/exporter)
+
+This component provides the functionality to export PHP variables for visualization.
+
+## 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
+ 'trace' => Array &0 ()
+ '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
+);
+```
+
+## 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
+
diff --git a/vendor/sebastian/exporter/build.xml b/vendor/sebastian/exporter/build.xml
new file mode 100644
index 0000000..e66a71a
--- /dev/null
+++ b/vendor/sebastian/exporter/build.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="exporter">
+ <target name="clean" description="Cleanup build artifacts">
+ <delete dir="${basedir}/vendor"/>
+ <delete file="${basedir}/composer.lock"/>
+ </target>
+
+ <target name="composer" depends="clean" description="Install dependencies with Composer">
+ <tstamp>
+ <format property="thirty.days.ago" pattern="MM/dd/yyyy hh:mm aa" offset="-30" unit="day"/>
+ </tstamp>
+ <delete>
+ <fileset dir="${basedir}">
+ <include name="composer.phar" />
+ <date datetime="${thirty.days.ago}" when="before"/>
+ </fileset>
+ </delete>
+
+ <get src="https://getcomposer.org/composer.phar" dest="${basedir}/composer.phar" skipexisting="true"/>
+
+ <exec executable="php">
+ <arg value="composer.phar"/>
+ <arg value="install"/>
+ </exec>
+ </target>
+</project>
+
diff --git a/vendor/sebastian/exporter/composer.json b/vendor/sebastian/exporter/composer.json
new file mode 100644
index 0000000..d0840c3
--- /dev/null
+++ b/vendor/sebastian/exporter/composer.json
@@ -0,0 +1,48 @@
+{
+ "name": "sebastian/exporter",
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "keywords": ["exporter","export"],
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3",
+ "sebastian/recursion-context": "~2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4",
+ "ext-mbstring": "*"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ }
+}
+
diff --git a/vendor/sebastian/exporter/phpunit.xml.dist b/vendor/sebastian/exporter/phpunit.xml.dist
new file mode 100644
index 0000000..8d85af6
--- /dev/null
+++ b/vendor/sebastian/exporter/phpunit.xml.dist
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit backupGlobals="false"
+ bootstrap="vendor/autoload.php"
+ beStrictAboutTestsThatDoNotTestAnything="true"
+ beStrictAboutOutputDuringTests="true"
+ beStrictAboutTodoAnnotatedTests="true"
+ checkForUnintentionallyCoveredCode="true"
+ forceCoversAnnotation="true"
+ verbose="true">
+ <testsuites>
+ <testsuite name="exporter">
+ <directory>tests</directory>
+ </testsuite>
+ </testsuites>
+ <filter>
+ <whitelist addUncoveredFilesFromWhitelist="true" processUncoveredFilesFromWhitelist="true">
+ <directory>src</directory>
+ </whitelist>
+ </filter>
+</phpunit>
+
diff --git a/vendor/sebastian/exporter/src/Exporter.php b/vendor/sebastian/exporter/src/Exporter.php
new file mode 100644
index 0000000..08e6ef1
--- /dev/null
+++ b/vendor/sebastian/exporter/src/Exporter.php
@@ -0,0 +1,303 @@
+<?php
+/*
+ * This file is part of the Exporter package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Exporter;
+
+use SebastianBergmann\RecursionContext\Context;
+
+/**
+ * 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 mixed $value
+ * @param int $indentation The indentation level of the 2nd+ line
+ * @return string
+ */
+ public function export($value, $indentation = 0)
+ {
+ return $this->recursiveExport($value, $indentation);
+ }
+
+ /**
+ * @param mixed $data
+ * @param Context $context
+ * @return string
+ */
+ public function shortenedRecursiveExport(&$data, Context $context = null)
+ {
+ $result = array();
+ $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 '...'.
+ *
+ * @param mixed $value
+ * @return string
+ * @see SebastianBergmann\Exporter\Exporter::export
+ */
+ public function shortenedExport($value)
+ {
+ if (is_string($value)) {
+ $string = $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 str_replace("\n", '\n', $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.
+ *
+ * @param mixed $value
+ * @return array
+ */
+ public function toArray($value)
+ {
+ if (!is_object($value)) {
+ return (array) $value;
+ }
+
+ $array = array();
+
+ foreach ((array) $value as $key => $val) {
+ // 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(.+)$/', $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) {
+ // However, the fast method does work in HHVM, and exposes the
+ // internal implementation. Hide it again.
+ if (property_exists('\SplObjectStorage', '__storage')) {
+ unset($array['__storage']);
+ } elseif (property_exists('\SplObjectStorage', 'storage')) {
+ unset($array['storage']);
+ }
+
+ if (property_exists('\SplObjectStorage', '__key')) {
+ unset($array['__key']);
+ }
+
+ foreach ($value as $key => $val) {
+ $array[spl_object_hash($val)] = array(
+ '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) && floatval(intval($value)) === $value) {
+ return "$value.0";
+ }
+
+ 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(array("\r\n", "\n\r", "\r"), array("\n", "\n", "\n"), $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/exporter/tests/ExporterTest.php b/vendor/sebastian/exporter/tests/ExporterTest.php
new file mode 100644
index 0000000..b0546f1
--- /dev/null
+++ b/vendor/sebastian/exporter/tests/ExporterTest.php
@@ -0,0 +1,358 @@
+<?php
+/*
+ * This file is part of the Exporter package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\Exporter;
+
+/**
+ * @covers SebastianBergmann\Exporter\Exporter
+ */
+class ExporterTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var Exporter
+ */
+ private $exporter;
+
+ protected function setUp()
+ {
+ $this->exporter = new Exporter;
+ }
+
+ public function exportProvider()
+ {
+ $obj2 = new \stdClass;
+ $obj2->foo = 'bar';
+
+ $obj3 = (object)array(1,2,"Test\r\n",4,5,6,7,8);
+
+ $obj = new \stdClass;
+ //@codingStandardsIgnoreStart
+ $obj->null = null;
+ //@codingStandardsIgnoreEnd
+ $obj->boolean = true;
+ $obj->integer = 1;
+ $obj->double = 1.2;
+ $obj->string = '1';
+ $obj->text = "this\nis\na\nvery\nvery\nvery\nvery\nvery\nvery\rlong\n\rtext";
+ $obj->object = $obj2;
+ $obj->objectagain = $obj2;
+ $obj->array = array('foo' => 'bar');
+ $obj->self = $obj;
+
+ $storage = new \SplObjectStorage;
+ $storage->attach($obj2);
+ $storage->foo = $obj2;
+
+ return array(
+ array(null, 'null'),
+ array(true, 'true'),
+ array(false, 'false'),
+ array(1, '1'),
+ array(1.0, '1.0'),
+ array(1.2, '1.2'),
+ array(fopen('php://memory', 'r'), 'resource(%d) of type (stream)'),
+ array('1', "'1'"),
+ array(array(array(1,2,3), array(3,4,5)),
+ <<<EOF
+Array &0 (
+ 0 => Array &1 (
+ 0 => 1
+ 1 => 2
+ 2 => 3
+ )
+ 1 => Array &2 (
+ 0 => 3
+ 1 => 4
+ 2 => 5
+ )
+)
+EOF
+ ),
+ // \n\r and \r is converted to \n
+ array("this\nis\na\nvery\nvery\nvery\nvery\nvery\nvery\rlong\n\rtext",
+ <<<EOF
+'this
+is
+a
+very
+very
+very
+very
+very
+very
+long
+text'
+EOF
+ ),
+ array(new \stdClass, 'stdClass Object &%x ()'),
+ array($obj,
+ <<<EOF
+stdClass Object &%x (
+ 'null' => null
+ 'boolean' => true
+ 'integer' => 1
+ 'double' => 1.2
+ 'string' => '1'
+ 'text' => 'this
+is
+a
+very
+very
+very
+very
+very
+very
+long
+text'
+ 'object' => stdClass Object &%x (
+ 'foo' => 'bar'
+ )
+ 'objectagain' => stdClass Object &%x
+ 'array' => Array &%d (
+ 'foo' => 'bar'
+ )
+ 'self' => stdClass Object &%x
+)
+EOF
+ ),
+ array(array(), 'Array &%d ()'),
+ array($storage,
+ <<<EOF
+SplObjectStorage Object &%x (
+ 'foo' => stdClass Object &%x (
+ 'foo' => 'bar'
+ )
+ '%x' => Array &0 (
+ 'obj' => stdClass Object &%x
+ 'inf' => null
+ )
+)
+EOF
+ ),
+ array($obj3,
+ <<<EOF
+stdClass Object &%x (
+ 0 => 1
+ 1 => 2
+ 2 => 'Test\n'
+ 3 => 4
+ 4 => 5
+ 5 => 6
+ 6 => 7
+ 7 => 8
+)
+EOF
+ ),
+ array(
+ chr(0) . chr(1) . chr(2) . chr(3) . chr(4) . chr(5),
+ 'Binary String: 0x000102030405'
+ ),
+ array(
+ implode('', array_map('chr', range(0x0e, 0x1f))),
+ 'Binary String: 0x0e0f101112131415161718191a1b1c1d1e1f'
+ ),
+ array(
+ chr(0x00) . chr(0x09),
+ 'Binary String: 0x0009'
+ ),
+ array(
+ '',
+ "''"
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider exportProvider
+ */
+ public function testExport($value, $expected)
+ {
+ $this->assertStringMatchesFormat(
+ $expected,
+ $this->trimNewline($this->exporter->export($value))
+ );
+ }
+
+ public function testExport2()
+ {
+ if (PHP_VERSION === '5.3.3') {
+ $this->markTestSkipped('Skipped due to "Nesting level too deep - recursive dependency?" fatal error');
+ }
+
+ $obj = new \stdClass;
+ $obj->foo = 'bar';
+
+ $array = array(
+ 0 => 0,
+ 'null' => null,
+ 'boolean' => true,
+ 'integer' => 1,
+ 'double' => 1.2,
+ 'string' => '1',
+ 'text' => "this\nis\na\nvery\nvery\nvery\nvery\nvery\nvery\rlong\n\rtext",
+ 'object' => $obj,
+ 'objectagain' => $obj,
+ 'array' => array('foo' => 'bar'),
+ );
+
+ $array['self'] = &$array;
+
+ $expected = <<<EOF
+Array &%d (
+ 0 => 0
+ 'null' => null
+ 'boolean' => true
+ 'integer' => 1
+ 'double' => 1.2
+ 'string' => '1'
+ 'text' => 'this
+is
+a
+very
+very
+very
+very
+very
+very
+long
+text'
+ 'object' => stdClass Object &%x (
+ 'foo' => 'bar'
+ )
+ 'objectagain' => stdClass Object &%x
+ 'array' => Array &%d (
+ 'foo' => 'bar'
+ )
+ 'self' => Array &%d (
+ 0 => 0
+ 'null' => null
+ 'boolean' => true
+ 'integer' => 1
+ 'double' => 1.2
+ 'string' => '1'
+ 'text' => 'this
+is
+a
+very
+very
+very
+very
+very
+very
+long
+text'
+ 'object' => stdClass Object &%x
+ 'objectagain' => stdClass Object &%x
+ 'array' => Array &%d (
+ 'foo' => 'bar'
+ )
+ 'self' => Array &%d
+ )
+)
+EOF;
+
+ $this->assertStringMatchesFormat(
+ $expected,
+ $this->trimNewline($this->exporter->export($array))
+ );
+ }
+
+ public function shortenedExportProvider()
+ {
+ $obj = new \stdClass;
+ $obj->foo = 'bar';
+
+ $array = array(
+ 'foo' => 'bar',
+ );
+
+ return array(
+ array(null, 'null'),
+ array(true, 'true'),
+ array(1, '1'),
+ array(1.0, '1.0'),
+ array(1.2, '1.2'),
+ array('1', "'1'"),
+ // \n\r and \r is converted to \n
+ array("this\nis\na\nvery\nvery\nvery\nvery\nvery\nvery\rlong\n\rtext", "'this\\nis\\na\\nvery\\nvery\\nvery\\nvery...g\\ntext'"),
+ array(new \stdClass, 'stdClass Object ()'),
+ array($obj, 'stdClass Object (...)'),
+ array(array(), 'Array ()'),
+ array($array, 'Array (...)'),
+ );
+ }
+
+ /**
+ * @dataProvider shortenedExportProvider
+ */
+ public function testShortenedExport($value, $expected)
+ {
+ $this->assertSame(
+ $expected,
+ $this->trimNewline($this->exporter->shortenedExport($value))
+ );
+ }
+
+ /**
+ * @requires extension mbstring
+ */
+ public function testShortenedExportForMultibyteCharacters()
+ {
+ $oldMbLanguage = mb_language();
+ mb_language('Japanese');
+ $oldMbInternalEncoding = mb_internal_encoding();
+ mb_internal_encoding('UTF-8');
+
+ try {
+ $this->assertSame(
+ "'いろはにほへとちりぬるをわかよたれそつねならむうゐのおくや...しゑひもせす'",
+ $this->trimNewline($this->exporter->shortenedExport('いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす'))
+ );
+ } catch (\Exception $e) {
+ mb_internal_encoding($oldMbInternalEncoding);
+ mb_language($oldMbLanguage);
+ throw $e;
+ }
+
+ mb_internal_encoding($oldMbInternalEncoding);
+ mb_language($oldMbLanguage);
+ }
+
+ public function provideNonBinaryMultibyteStrings()
+ {
+ return array(
+ array(implode('', array_map('chr', range(0x09, 0x0d))), 5),
+ array(implode('', array_map('chr', range(0x20, 0x7f))), 96),
+ array(implode('', array_map('chr', range(0x80, 0xff))), 128),
+ );
+ }
+
+
+ /**
+ * @dataProvider provideNonBinaryMultibyteStrings
+ */
+ public function testNonBinaryStringExport($value, $expectedLength)
+ {
+ $this->assertRegExp(
+ "~'.{{$expectedLength}}'\$~s",
+ $this->exporter->export($value)
+ );
+ }
+
+ public function testNonObjectCanBeReturnedAsArray()
+ {
+ $this->assertEquals(array(true), $this->exporter->toArray(true));
+ }
+
+ private function trimNewline($string)
+ {
+ return preg_replace('/[ ]*\n/', "\n", $string);
+ }
+}
diff --git a/vendor/sebastian/global-state/.gitignore b/vendor/sebastian/global-state/.gitignore
new file mode 100644
index 0000000..464180e
--- /dev/null
+++ b/vendor/sebastian/global-state/.gitignore
@@ -0,0 +1,6 @@
+.idea
+composer.lock
+composer.phar
+vendor/
+cache.properties
+phpunit.xml
diff --git a/vendor/sebastian/global-state/.travis.yml b/vendor/sebastian/global-state/.travis.yml
new file mode 100644
index 0000000..0be6154
--- /dev/null
+++ b/vendor/sebastian/global-state/.travis.yml
@@ -0,0 +1,20 @@
+language: php
+
+php:
+ - 5.3.3
+ - 5.3
+ - 5.4
+ - 5.5
+ - 5.6
+ - hhvm
+
+sudo: false
+
+before_script:
+ - composer self-update
+ - composer install --no-interaction --prefer-source --dev
+
+script: ./vendor/bin/phpunit
+
+notifications:
+ email: false
diff --git a/vendor/sebastian/global-state/LICENSE b/vendor/sebastian/global-state/LICENSE
new file mode 100644
index 0000000..a555bcd
--- /dev/null
+++ b/vendor/sebastian/global-state/LICENSE
@@ -0,0 +1,33 @@
+GlobalState
+
+Copyright (c) 2001-2015, Sebastian Bergmann <sebastian@phpunit.de>.
+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 0000000..c5e262b
--- /dev/null
+++ b/vendor/sebastian/global-state/README.md
@@ -0,0 +1,15 @@
+# GlobalState
+
+Snapshotting of global state, factored out of PHPUnit into a stand-alone component.
+
+[![Build Status](https://travis-ci.org/sebastianbergmann/global-state.svg?branch=master)](https://travis-ci.org/sebastianbergmann/global-state)
+
+## Installation
+
+To add this package as a local, per-project dependency to your project, simply add a dependency on `sebastian/global-state` to your project's `composer.json` file. Here is a minimal example of a `composer.json` file that just defines a dependency on GlobalState:
+
+ {
+ "require": {
+ "sebastian/global-state": "1.0.*"
+ }
+ }
diff --git a/vendor/sebastian/global-state/build.xml b/vendor/sebastian/global-state/build.xml
new file mode 100644
index 0000000..63c5445
--- /dev/null
+++ b/vendor/sebastian/global-state/build.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="global-state">
+ <target name="clean" description="Cleanup build artifacts">
+ <delete dir="${basedir}/vendor"/>
+ <delete file="${basedir}/composer.lock"/>
+ </target>
+
+ <target name="composer" depends="clean" description="Install dependencies with Composer">
+ <tstamp>
+ <format property="thirty.days.ago" pattern="MM/dd/yyyy hh:mm aa" offset="-30" unit="day"/>
+ </tstamp>
+ <delete>
+ <fileset dir="${basedir}">
+ <include name="composer.phar" />
+ <date datetime="${thirty.days.ago}" when="before"/>
+ </fileset>
+ </delete>
+
+ <get src="https://getcomposer.org/composer.phar" dest="${basedir}/composer.phar" skipexisting="true"/>
+
+ <exec executable="php">
+ <arg value="composer.phar"/>
+ <arg value="install"/>
+ </exec>
+ </target>
+
+ <target name="phpunit" description="Run unit tests with PHPUnit">
+ <exec executable="${basedir}/vendor/bin/phpunit" failonerror="true">
+ <arg value="--configuration"/>
+ <arg path="${basedir}/build/phpunit.xml"/>
+ </exec>
+ </target>
+</project>
diff --git a/vendor/sebastian/global-state/composer.json b/vendor/sebastian/global-state/composer.json
new file mode 100644
index 0000000..7e8849b
--- /dev/null
+++ b/vendor/sebastian/global-state/composer.json
@@ -0,0 +1,37 @@
+{
+ "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": "sebastian@phpunit.de"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.2"
+ },
+ "suggest": {
+ "ext-uopz": "*"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "autoload-dev": {
+ "classmap": [
+ "tests/_fixture/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/global-state/phpunit.xml.dist b/vendor/sebastian/global-state/phpunit.xml.dist
new file mode 100644
index 0000000..d607918
--- /dev/null
+++ b/vendor/sebastian/global-state/phpunit.xml.dist
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.2/phpunit.xsd"
+ bootstrap="vendor/autoload.php"
+ backupGlobals="false"
+ verbose="true">
+ <testsuite name="GlobalState">
+ <directory suffix="Test.php">tests</directory>
+ </testsuite>
+
+ <filter>
+ <whitelist processUncoveredFilesFromWhitelist="true">
+ <directory suffix=".php">src</directory>
+ </whitelist>
+ </filter>
+
+ <php>
+ <const name="GLOBALSTATE_TESTSUITE" value="true"/>
+ <ini name="date.timezone" value="Etc/UTC"/>
+ </php>
+</phpunit>
diff --git a/vendor/sebastian/global-state/src/Blacklist.php b/vendor/sebastian/global-state/src/Blacklist.php
new file mode 100644
index 0000000..5d54091
--- /dev/null
+++ b/vendor/sebastian/global-state/src/Blacklist.php
@@ -0,0 +1,149 @@
+<?php
+/*
+ * This file is part of the GlobalState package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\GlobalState;
+
+use ReflectionClass;
+
+/**
+ * A blacklist for global state elements that should not be snapshotted.
+ */
+class Blacklist
+{
+ /**
+ * @var array
+ */
+ private $globalVariables = array();
+
+ /**
+ * @var array
+ */
+ private $classes = array();
+
+ /**
+ * @var array
+ */
+ private $classNamePrefixes = array();
+
+ /**
+ * @var array
+ */
+ private $parentClasses = array();
+
+ /**
+ * @var array
+ */
+ private $interfaces = array();
+
+ /**
+ * @var array
+ */
+ private $staticAttributes = array();
+
+ /**
+ * @param string $variableName
+ */
+ public function addGlobalVariable($variableName)
+ {
+ $this->globalVariables[$variableName] = true;
+ }
+
+ /**
+ * @param string $className
+ */
+ public function addClass($className)
+ {
+ $this->classes[] = $className;
+ }
+
+ /**
+ * @param string $className
+ */
+ public function addSubclassesOf($className)
+ {
+ $this->parentClasses[] = $className;
+ }
+
+ /**
+ * @param string $interfaceName
+ */
+ public function addImplementorsOf($interfaceName)
+ {
+ $this->interfaces[] = $interfaceName;
+ }
+
+ /**
+ * @param string $classNamePrefix
+ */
+ public function addClassNamePrefix($classNamePrefix)
+ {
+ $this->classNamePrefixes[] = $classNamePrefix;
+ }
+
+ /**
+ * @param string $className
+ * @param string $attributeName
+ */
+ public function addStaticAttribute($className, $attributeName)
+ {
+ if (!isset($this->staticAttributes[$className])) {
+ $this->staticAttributes[$className] = array();
+ }
+
+ $this->staticAttributes[$className][$attributeName] = true;
+ }
+
+ /**
+ * @param string $variableName
+ * @return bool
+ */
+ public function isGlobalVariableBlacklisted($variableName)
+ {
+ return isset($this->globalVariables[$variableName]);
+ }
+
+ /**
+ * @param string $className
+ * @param string $attributeName
+ * @return bool
+ */
+ public function isStaticAttributeBlacklisted($className, $attributeName)
+ {
+ if (in_array($className, $this->classes)) {
+ 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/CodeExporter.php b/vendor/sebastian/global-state/src/CodeExporter.php
new file mode 100644
index 0000000..d595c22
--- /dev/null
+++ b/vendor/sebastian/global-state/src/CodeExporter.php
@@ -0,0 +1,93 @@
+<?php
+/*
+ * This file is part of the GlobalState package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\GlobalState;
+
+/**
+ * Exports parts of a Snapshot as PHP code.
+ */
+class CodeExporter
+{
+ /**
+ * @param Snapshot $snapshot
+ * @return string
+ */
+ public function constants(Snapshot $snapshot)
+ {
+ $result = '';
+
+ foreach ($snapshot->constants() as $name => $value) {
+ $result .= sprintf(
+ 'if (!defined(\'%s\')) define(\'%s\', %s);' . "\n",
+ $name,
+ $name,
+ $this->exportVariable($value)
+ );
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param Snapshot $snapshot
+ * @return string
+ */
+ public function iniSettings(Snapshot $snapshot)
+ {
+ $result = '';
+
+ foreach ($snapshot->iniSettings() as $key => $value) {
+ $result .= sprintf(
+ '@ini_set(%s, %s);' . "\n",
+ $this->exportVariable($key),
+ $this->exportVariable($value)
+ );
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param mixed $variable
+ * @return string
+ */
+ private function exportVariable($variable)
+ {
+ if (is_scalar($variable) || is_null($variable) ||
+ (is_array($variable) && $this->arrayOnlyContainsScalars($variable))) {
+ return var_export($variable, true);
+ }
+
+ return 'unserialize(' . var_export(serialize($variable), true) . ')';
+ }
+
+ /**
+ * @param array $array
+ * @return bool
+ */
+ private function arrayOnlyContainsScalars(array $array)
+ {
+ $result = true;
+
+ foreach ($array as $element) {
+ if (is_array($element)) {
+ $result = self::arrayOnlyContainsScalars($element);
+ } elseif (!is_scalar($element) && !is_null($element)) {
+ $result = false;
+ }
+
+ if ($result === false) {
+ break;
+ }
+ }
+
+ return $result;
+ }
+}
diff --git a/vendor/sebastian/global-state/src/Exception.php b/vendor/sebastian/global-state/src/Exception.php
new file mode 100644
index 0000000..1e00212
--- /dev/null
+++ b/vendor/sebastian/global-state/src/Exception.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of the GlobalState package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\GlobalState;
+
+/**
+ */
+interface Exception
+{
+}
diff --git a/vendor/sebastian/global-state/src/Restorer.php b/vendor/sebastian/global-state/src/Restorer.php
new file mode 100644
index 0000000..78e0ba8
--- /dev/null
+++ b/vendor/sebastian/global-state/src/Restorer.php
@@ -0,0 +1,141 @@
+<?php
+/*
+ * This file is part of the GlobalState package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\GlobalState;
+
+use ReflectionProperty;
+
+/**
+ * Restorer of snapshots of global state.
+ */
+class Restorer
+{
+ /**
+ * Deletes function definitions that are not defined in a snapshot.
+ *
+ * @param Snapshot $snapshot
+ * @throws RuntimeException when the uopz_delete() function is not available
+ * @see https://github.com/krakjoe/uopz
+ */
+ public function restoreFunctions(Snapshot $snapshot)
+ {
+ 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.
+ *
+ * @param Snapshot $snapshot
+ */
+ public function restoreGlobalVariables(Snapshot $snapshot)
+ {
+ $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) &&
+ !$snapshot->blacklist()->isGlobalVariableBlacklisted($key)) {
+ if (isset($globalVariables[$key])) {
+ $GLOBALS[$key] = $globalVariables[$key];
+ } else {
+ unset($GLOBALS[$key]);
+ }
+ }
+ }
+ }
+
+ /**
+ * Restores all static attributes in user-defined classes from this snapshot.
+ *
+ * @param Snapshot $snapshot
+ */
+ public function restoreStaticAttributes(Snapshot $snapshot)
+ {
+ $current = new Snapshot($snapshot->blacklist(), 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->blacklist()->isStaticAttributeBlacklisted($className, $name)) {
+ continue;
+ }
+
+ if (!isset($defaults[$name])) {
+ continue;
+ }
+
+ $attribute->setAccessible(true);
+ $attribute->setValue($defaults[$name]);
+ }
+ }
+ }
+
+ /**
+ * Restores a super-global variable array from this snapshot.
+ *
+ * @param Snapshot $snapshot
+ * @param $superGlobalArray
+ */
+ private function restoreSuperGlobalArray(Snapshot $snapshot, $superGlobalArray)
+ {
+ $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/RuntimeException.php b/vendor/sebastian/global-state/src/RuntimeException.php
new file mode 100644
index 0000000..c0bf7bd
--- /dev/null
+++ b/vendor/sebastian/global-state/src/RuntimeException.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of the GlobalState package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\GlobalState;
+
+/**
+ */
+class RuntimeException extends \RuntimeException implements Exception
+{
+}
diff --git a/vendor/sebastian/global-state/src/Snapshot.php b/vendor/sebastian/global-state/src/Snapshot.php
new file mode 100644
index 0000000..3c8aaa9
--- /dev/null
+++ b/vendor/sebastian/global-state/src/Snapshot.php
@@ -0,0 +1,423 @@
+<?php
+/*
+ * This file is part of the GlobalState package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\GlobalState;
+
+use ReflectionClass;
+use Serializable;
+
+/**
+ * A snapshot of global state.
+ */
+class Snapshot
+{
+ /**
+ * @var Blacklist
+ */
+ private $blacklist;
+
+ /**
+ * @var array
+ */
+ private $globalVariables = array();
+
+ /**
+ * @var array
+ */
+ private $superGlobalArrays = array();
+
+ /**
+ * @var array
+ */
+ private $superGlobalVariables = array();
+
+ /**
+ * @var array
+ */
+ private $staticAttributes = array();
+
+ /**
+ * @var array
+ */
+ private $iniSettings = array();
+
+ /**
+ * @var array
+ */
+ private $includedFiles = array();
+
+ /**
+ * @var array
+ */
+ private $constants = array();
+
+ /**
+ * @var array
+ */
+ private $functions = array();
+
+ /**
+ * @var array
+ */
+ private $interfaces = array();
+
+ /**
+ * @var array
+ */
+ private $classes = array();
+
+ /**
+ * @var array
+ */
+ private $traits = array();
+
+ /**
+ * Creates a snapshot of the current global state.
+ *
+ * @param Blacklist $blacklist
+ * @param bool $includeGlobalVariables
+ * @param bool $includeStaticAttributes
+ * @param bool $includeConstants
+ * @param bool $includeFunctions
+ * @param bool $includeClasses
+ * @param bool $includeInterfaces
+ * @param bool $includeTraits
+ * @param bool $includeIniSettings
+ * @param bool $includeIncludedFiles
+ */
+ public function __construct(Blacklist $blacklist = null, $includeGlobalVariables = true, $includeStaticAttributes = true, $includeConstants = true, $includeFunctions = true, $includeClasses = true, $includeInterfaces = true, $includeTraits = true, $includeIniSettings = true, $includeIncludedFiles = true)
+ {
+ if ($blacklist === null) {
+ $blacklist = new Blacklist;
+ }
+
+ $this->blacklist = $blacklist;
+
+ 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 (function_exists('get_declared_traits')) {
+ $this->traits = get_declared_traits();
+ }
+ }
+
+ /**
+ * @return Blacklist
+ */
+ public function blacklist()
+ {
+ return $this->blacklist;
+ }
+
+ /**
+ * @return array
+ */
+ public function globalVariables()
+ {
+ return $this->globalVariables;
+ }
+
+ /**
+ * @return array
+ */
+ public function superGlobalVariables()
+ {
+ return $this->superGlobalVariables;
+ }
+
+ /**
+ * Returns a list of all super-global variable arrays.
+ *
+ * @return array
+ */
+ public function superGlobalArrays()
+ {
+ return $this->superGlobalArrays;
+ }
+
+ /**
+ * @return array
+ */
+ public function staticAttributes()
+ {
+ return $this->staticAttributes;
+ }
+
+ /**
+ * @return array
+ */
+ public function iniSettings()
+ {
+ return $this->iniSettings;
+ }
+
+ /**
+ * @return array
+ */
+ public function includedFiles()
+ {
+ return $this->includedFiles;
+ }
+
+ /**
+ * @return array
+ */
+ public function constants()
+ {
+ return $this->constants;
+ }
+
+ /**
+ * @return array
+ */
+ public function functions()
+ {
+ return $this->functions;
+ }
+
+ /**
+ * @return array
+ */
+ public function interfaces()
+ {
+ return $this->interfaces;
+ }
+
+ /**
+ * @return array
+ */
+ public function classes()
+ {
+ return $this->classes;
+ }
+
+ /**
+ * @return array
+ */
+ public function traits()
+ {
+ return $this->traits;
+ }
+
+ /**
+ * Creates a snapshot user-defined constants.
+ */
+ private function snapshotConstants()
+ {
+ $constants = get_defined_constants(true);
+
+ if (isset($constants['user'])) {
+ $this->constants = $constants['user'];
+ }
+ }
+
+ /**
+ * Creates a snapshot user-defined functions.
+ */
+ private function snapshotFunctions()
+ {
+ $functions = get_defined_functions();
+
+ $this->functions = $functions['user'];
+ }
+
+ /**
+ * Creates a snapshot user-defined classes.
+ */
+ private function snapshotClasses()
+ {
+ 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()
+ {
+ 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()
+ {
+ $superGlobalArrays = $this->superGlobalArrays();
+
+ foreach ($superGlobalArrays as $superGlobalArray) {
+ $this->snapshotSuperGlobalArray($superGlobalArray);
+ }
+
+ foreach (array_keys($GLOBALS) as $key) {
+ if ($key != 'GLOBALS' &&
+ !in_array($key, $superGlobalArrays) &&
+ $this->canBeSerialized($GLOBALS[$key]) &&
+ !$this->blacklist->isGlobalVariableBlacklisted($key)) {
+ $this->globalVariables[$key] = unserialize(serialize($GLOBALS[$key]));
+ }
+ }
+ }
+
+ /**
+ * Creates a snapshot a super-global variable array.
+ *
+ * @param $superGlobalArray
+ */
+ private function snapshotSuperGlobalArray($superGlobalArray)
+ {
+ $this->superGlobalVariables[$superGlobalArray] = array();
+
+ if (isset($GLOBALS[$superGlobalArray]) && is_array($GLOBALS[$superGlobalArray])) {
+ foreach ($GLOBALS[$superGlobalArray] as $key => $value) {
+ $this->superGlobalVariables[$superGlobalArray][$key] = unserialize(serialize($value));
+ }
+ }
+ }
+
+ /**
+ * Creates a snapshot of all static attributes in user-defined classes.
+ */
+ private function snapshotStaticAttributes()
+ {
+ foreach ($this->classes as $className) {
+ $class = new ReflectionClass($className);
+ $snapshot = array();
+
+ foreach ($class->getProperties() as $attribute) {
+ if ($attribute->isStatic()) {
+ $name = $attribute->getName();
+
+ if ($this->blacklist->isStaticAttributeBlacklisted($className, $name)) {
+ continue;
+ }
+
+ $attribute->setAccessible(true);
+ $value = $attribute->getValue();
+
+ if ($this->canBeSerialized($value)) {
+ $snapshot[$name] = unserialize(serialize($value));
+ }
+ }
+ }
+
+ if (!empty($snapshot)) {
+ $this->staticAttributes[$className] = $snapshot;
+ }
+ }
+ }
+
+ /**
+ * Returns a list of all super-global variable arrays.
+ *
+ * @return array
+ */
+ private function setupSuperGlobalArrays()
+ {
+ $this->superGlobalArrays = array(
+ '_ENV',
+ '_POST',
+ '_GET',
+ '_COOKIE',
+ '_SERVER',
+ '_FILES',
+ '_REQUEST'
+ );
+
+ if (ini_get('register_long_arrays') == '1') {
+ $this->superGlobalArrays = array_merge(
+ $this->superGlobalArrays,
+ array(
+ 'HTTP_ENV_VARS',
+ 'HTTP_POST_VARS',
+ 'HTTP_GET_VARS',
+ 'HTTP_COOKIE_VARS',
+ 'HTTP_SERVER_VARS',
+ 'HTTP_POST_FILES'
+ )
+ );
+ }
+ }
+
+ /**
+ * @param mixed $variable
+ * @return bool
+ * @todo Implement this properly
+ */
+ private function canBeSerialized($variable)
+ {
+ if (!is_object($variable)) {
+ return !is_resource($variable);
+ }
+
+ if ($variable instanceof \stdClass) {
+ return true;
+ }
+
+ $class = new ReflectionClass($variable);
+
+ do {
+ if ($class->isInternal()) {
+ return $variable instanceof Serializable;
+ }
+ } while ($class = $class->getParentClass());
+
+ return true;
+ }
+}
diff --git a/vendor/sebastian/global-state/tests/BlacklistTest.php b/vendor/sebastian/global-state/tests/BlacklistTest.php
new file mode 100644
index 0000000..5d59796
--- /dev/null
+++ b/vendor/sebastian/global-state/tests/BlacklistTest.php
@@ -0,0 +1,113 @@
+<?php
+/*
+ * This file is part of the GlobalState package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\GlobalState;
+
+use PHPUnit_Framework_TestCase;
+
+/**
+ */
+class BlacklistTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @var \SebastianBergmann\GlobalState\Blacklist
+ */
+ private $blacklist;
+
+ protected function setUp()
+ {
+ $this->blacklist = new Blacklist;
+ }
+
+ public function testGlobalVariableThatIsNotBlacklistedIsNotTreatedAsBlacklisted()
+ {
+ $this->assertFalse($this->blacklist->isGlobalVariableBlacklisted('variable'));
+ }
+
+ public function testGlobalVariableCanBeBlacklisted()
+ {
+ $this->blacklist->addGlobalVariable('variable');
+
+ $this->assertTrue($this->blacklist->isGlobalVariableBlacklisted('variable'));
+ }
+
+ public function testStaticAttributeThatIsNotBlacklistedIsNotTreatedAsBlacklisted()
+ {
+ $this->assertFalse(
+ $this->blacklist->isStaticAttributeBlacklisted(
+ 'SebastianBergmann\GlobalState\TestFixture\BlacklistedClass',
+ 'attribute'
+ )
+ );
+ }
+
+ public function testClassCanBeBlacklisted()
+ {
+ $this->blacklist->addClass('SebastianBergmann\GlobalState\TestFixture\BlacklistedClass');
+
+ $this->assertTrue(
+ $this->blacklist->isStaticAttributeBlacklisted(
+ 'SebastianBergmann\GlobalState\TestFixture\BlacklistedClass',
+ 'attribute'
+ )
+ );
+ }
+
+ public function testSubclassesCanBeBlacklisted()
+ {
+ $this->blacklist->addSubclassesOf('SebastianBergmann\GlobalState\TestFixture\BlacklistedClass');
+
+ $this->assertTrue(
+ $this->blacklist->isStaticAttributeBlacklisted(
+ 'SebastianBergmann\GlobalState\TestFixture\BlacklistedChildClass',
+ 'attribute'
+ )
+ );
+ }
+
+ public function testImplementorsCanBeBlacklisted()
+ {
+ $this->blacklist->addImplementorsOf('SebastianBergmann\GlobalState\TestFixture\BlacklistedInterface');
+
+ $this->assertTrue(
+ $this->blacklist->isStaticAttributeBlacklisted(
+ 'SebastianBergmann\GlobalState\TestFixture\BlacklistedImplementor',
+ 'attribute'
+ )
+ );
+ }
+
+ public function testClassNamePrefixesCanBeBlacklisted()
+ {
+ $this->blacklist->addClassNamePrefix('SebastianBergmann\GlobalState');
+
+ $this->assertTrue(
+ $this->blacklist->isStaticAttributeBlacklisted(
+ 'SebastianBergmann\GlobalState\TestFixture\BlacklistedClass',
+ 'attribute'
+ )
+ );
+ }
+
+ public function testStaticAttributeCanBeBlacklisted()
+ {
+ $this->blacklist->addStaticAttribute(
+ 'SebastianBergmann\GlobalState\TestFixture\BlacklistedClass',
+ 'attribute'
+ );
+
+ $this->assertTrue(
+ $this->blacklist->isStaticAttributeBlacklisted(
+ 'SebastianBergmann\GlobalState\TestFixture\BlacklistedClass',
+ 'attribute'
+ )
+ );
+ }
+}
diff --git a/vendor/sebastian/global-state/tests/SnapshotTest.php b/vendor/sebastian/global-state/tests/SnapshotTest.php
new file mode 100644
index 0000000..1e97488
--- /dev/null
+++ b/vendor/sebastian/global-state/tests/SnapshotTest.php
@@ -0,0 +1,119 @@
+<?php
+/*
+ * This file is part of the GlobalState package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\GlobalState;
+
+use ArrayObject;
+use PHPUnit_Framework_TestCase;
+use SebastianBergmann\GlobalState\TestFixture\SnapshotClass;
+
+/**
+ */
+class SnapshotTest extends PHPUnit_Framework_TestCase
+{
+ public function testStaticAttributes()
+ {
+ $blacklist = $this->getBlacklist();
+ $blacklist->method('isStaticAttributeBlacklisted')->willReturnCallback(function ($class) {
+ return $class !== 'SebastianBergmann\GlobalState\TestFixture\SnapshotClass';
+ });
+
+ SnapshotClass::init();
+
+ $snapshot = new Snapshot($blacklist, false, true, false, false, false, false, false, false, false);
+ $expected = array('SebastianBergmann\GlobalState\TestFixture\SnapshotClass' => array(
+ 'string' => 'snapshot',
+ 'arrayObject' => new ArrayObject(array(1, 2, 3)),
+ 'stdClass' => new \stdClass(),
+ ));
+
+ $this->assertEquals($expected, $snapshot->staticAttributes());
+ }
+
+ public function testConstants()
+ {
+ $snapshot = new Snapshot($this->getBlacklist(), false, false, true, false, false, false, false, false, false);
+ $this->assertArrayHasKey('GLOBALSTATE_TESTSUITE', $snapshot->constants());
+ }
+
+ public function testFunctions()
+ {
+ require_once __DIR__.'/_fixture/SnapshotFunctions.php';
+
+ $snapshot = new Snapshot($this->getBlacklist(), false, false, false, true, false, false, false, false, false);
+ $functions = $snapshot->functions();
+
+ $this->assertThat(
+ $functions,
+ $this->logicalOr(
+ // Zend
+ $this->contains('sebastianbergmann\globalstate\testfixture\snapshotfunction'),
+ // HHVM
+ $this->contains('SebastianBergmann\GlobalState\TestFixture\snapshotFunction')
+ )
+ );
+
+ $this->assertNotContains('assert', $functions);
+ }
+
+ public function testClasses()
+ {
+ $snapshot = new Snapshot($this->getBlacklist(), false, false, false, false, true, false, false, false, false);
+ $classes = $snapshot->classes();
+
+ $this->assertContains('PHPUnit_Framework_TestCase', $classes);
+ $this->assertNotContains('Exception', $classes);
+ }
+
+ public function testInterfaces()
+ {
+ $snapshot = new Snapshot($this->getBlacklist(), false, false, false, false, false, true, false, false, false);
+ $interfaces = $snapshot->interfaces();
+
+ $this->assertContains('PHPUnit_Framework_Test', $interfaces);
+ $this->assertNotContains('Countable', $interfaces);
+ }
+
+ /**
+ * @requires PHP 5.4
+ */
+ public function testTraits()
+ {
+ spl_autoload_call('SebastianBergmann\GlobalState\TestFixture\SnapshotTrait');
+
+ $snapshot = new Snapshot($this->getBlacklist(), false, false, false, false, false, false, true, false, false);
+ $this->assertContains('SebastianBergmann\GlobalState\TestFixture\SnapshotTrait', $snapshot->traits());
+ }
+
+ public function testIniSettings()
+ {
+ $snapshot = new Snapshot($this->getBlacklist(), false, false, false, false, false, false, false, true, false);
+ $iniSettings = $snapshot->iniSettings();
+
+ $this->assertArrayHasKey('date.timezone', $iniSettings);
+ $this->assertEquals('Etc/UTC', $iniSettings['date.timezone']);
+ }
+
+ public function testIncludedFiles()
+ {
+ $snapshot = new Snapshot($this->getBlacklist(), false, false, false, false, false, false, false, false, true);
+ $this->assertContains(__FILE__, $snapshot->includedFiles());
+ }
+
+ /**
+ * @return \SebastianBergmann\GlobalState\Blacklist
+ */
+ private function getBlacklist()
+ {
+ return $this->getMockBuilder('SebastianBergmann\GlobalState\Blacklist')
+ ->disableOriginalConstructor()
+ ->getMock();
+ }
+}
diff --git a/vendor/sebastian/global-state/tests/_fixture/BlacklistedChildClass.php b/vendor/sebastian/global-state/tests/_fixture/BlacklistedChildClass.php
new file mode 100644
index 0000000..e852b49
--- /dev/null
+++ b/vendor/sebastian/global-state/tests/_fixture/BlacklistedChildClass.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of the GlobalState package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\GlobalState\TestFixture;
+
+/**
+ */
+class BlacklistedChildClass extends BlacklistedClass
+{
+}
diff --git a/vendor/sebastian/global-state/tests/_fixture/BlacklistedClass.php b/vendor/sebastian/global-state/tests/_fixture/BlacklistedClass.php
new file mode 100644
index 0000000..284876d
--- /dev/null
+++ b/vendor/sebastian/global-state/tests/_fixture/BlacklistedClass.php
@@ -0,0 +1,18 @@
+<?php
+/*
+ * This file is part of the GlobalState package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\GlobalState\TestFixture;
+
+/**
+ */
+class BlacklistedClass
+{
+ private static $attribute;
+}
diff --git a/vendor/sebastian/global-state/tests/_fixture/BlacklistedImplementor.php b/vendor/sebastian/global-state/tests/_fixture/BlacklistedImplementor.php
new file mode 100644
index 0000000..d7b46a9
--- /dev/null
+++ b/vendor/sebastian/global-state/tests/_fixture/BlacklistedImplementor.php
@@ -0,0 +1,18 @@
+<?php
+/*
+ * This file is part of the GlobalState package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\GlobalState\TestFixture;
+
+/**
+ */
+class BlacklistedImplementor implements BlacklistedInterface
+{
+ private static $attribute;
+}
diff --git a/vendor/sebastian/global-state/tests/_fixture/BlacklistedInterface.php b/vendor/sebastian/global-state/tests/_fixture/BlacklistedInterface.php
new file mode 100644
index 0000000..8c3ed67
--- /dev/null
+++ b/vendor/sebastian/global-state/tests/_fixture/BlacklistedInterface.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of the GlobalState package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\GlobalState\TestFixture;
+
+/**
+ */
+interface BlacklistedInterface
+{
+}
diff --git a/vendor/sebastian/global-state/tests/_fixture/SnapshotClass.php b/vendor/sebastian/global-state/tests/_fixture/SnapshotClass.php
new file mode 100644
index 0000000..9735818
--- /dev/null
+++ b/vendor/sebastian/global-state/tests/_fixture/SnapshotClass.php
@@ -0,0 +1,37 @@
+<?php
+/*
+ * This file is part of the GlobalState package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\GlobalState\TestFixture;
+
+use DomDocument;
+use ArrayObject;
+
+/**
+ */
+class SnapshotClass
+{
+ private static $string = 'snapshot';
+ private static $dom;
+ private static $closure;
+ private static $arrayObject;
+ private static $snapshotDomDocument;
+ private static $resource;
+ private static $stdClass;
+
+ public static function init()
+ {
+ self::$dom = new DomDocument();
+ self::$closure = function () {};
+ self::$arrayObject = new ArrayObject(array(1, 2, 3));
+ self::$snapshotDomDocument = new SnapshotDomDocument();
+ self::$resource = fopen('php://memory', 'r');
+ self::$stdClass = new \stdClass();
+ }
+}
diff --git a/vendor/sebastian/global-state/tests/_fixture/SnapshotDomDocument.php b/vendor/sebastian/global-state/tests/_fixture/SnapshotDomDocument.php
new file mode 100644
index 0000000..bcf554d
--- /dev/null
+++ b/vendor/sebastian/global-state/tests/_fixture/SnapshotDomDocument.php
@@ -0,0 +1,19 @@
+<?php
+/*
+ * This file is part of the GlobalState package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\GlobalState\TestFixture;
+
+use DomDocument;
+
+/**
+ */
+class SnapshotDomDocument extends DomDocument
+{
+}
diff --git a/vendor/sebastian/global-state/tests/_fixture/SnapshotFunctions.php b/vendor/sebastian/global-state/tests/_fixture/SnapshotFunctions.php
new file mode 100644
index 0000000..51d1c74
--- /dev/null
+++ b/vendor/sebastian/global-state/tests/_fixture/SnapshotFunctions.php
@@ -0,0 +1,15 @@
+<?php
+/*
+ * This file is part of the GlobalState package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\GlobalState\TestFixture;
+
+function snapshotFunction()
+{
+}
diff --git a/vendor/sebastian/global-state/tests/_fixture/SnapshotTrait.php b/vendor/sebastian/global-state/tests/_fixture/SnapshotTrait.php
new file mode 100644
index 0000000..14e81e9
--- /dev/null
+++ b/vendor/sebastian/global-state/tests/_fixture/SnapshotTrait.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of the GlobalState package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\GlobalState\TestFixture;
+
+/**
+ */
+trait SnapshotTrait
+{
+}
diff --git a/vendor/sebastian/object-enumerator/.gitignore b/vendor/sebastian/object-enumerator/.gitignore
new file mode 100644
index 0000000..5d748a8
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/.gitignore
@@ -0,0 +1,8 @@
+.idea
+composer.lock
+composer.phar
+vendor/
+cache.properties
+build/LICENSE
+build/README.md
+build/*.tgz
diff --git a/vendor/sebastian/object-enumerator/.php_cs b/vendor/sebastian/object-enumerator/.php_cs
new file mode 100644
index 0000000..b7393bd
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/.php_cs
@@ -0,0 +1,67 @@
+<?php
+$finder = Symfony\CS\Finder\DefaultFinder::create()
+ ->files()
+ ->in('src')
+ ->in('tests')
+ ->name('*.php');
+
+return Symfony\CS\Config\Config::create()
+ ->level(\Symfony\CS\FixerInterface::NONE_LEVEL)
+ ->fixers(
+ array(
+ 'align_double_arrow',
+ 'align_equals',
+ 'braces',
+ 'concat_with_spaces',
+ 'duplicate_semicolon',
+ 'elseif',
+ 'empty_return',
+ 'encoding',
+ 'eof_ending',
+ 'extra_empty_lines',
+ 'function_call_space',
+ 'function_declaration',
+ 'indentation',
+ 'join_function',
+ 'line_after_namespace',
+ 'linefeed',
+ 'list_commas',
+ 'lowercase_constants',
+ 'lowercase_keywords',
+ 'method_argument_space',
+ 'multiple_use',
+ 'namespace_no_leading_whitespace',
+ 'no_blank_lines_after_class_opening',
+ 'no_empty_lines_after_phpdocs',
+ 'parenthesis',
+ 'php_closing_tag',
+ 'phpdoc_indent',
+ 'phpdoc_no_access',
+ 'phpdoc_no_empty_return',
+ 'phpdoc_no_package',
+ 'phpdoc_params',
+ 'phpdoc_scalar',
+ 'phpdoc_separation',
+ 'phpdoc_to_comment',
+ 'phpdoc_trim',
+ 'phpdoc_types',
+ 'phpdoc_var_without_name',
+ 'remove_lines_between_uses',
+ 'return',
+ 'self_accessor',
+ 'short_array_syntax',
+ 'short_tag',
+ 'single_line_after_imports',
+ 'single_quote',
+ 'spaces_before_semicolon',
+ 'spaces_cast',
+ 'ternary_spaces',
+ 'trailing_spaces',
+ 'trim_array_spaces',
+ 'unused_use',
+ 'visibility',
+ 'whitespacy_lines'
+ )
+ )
+ ->finder($finder);
+
diff --git a/vendor/sebastian/object-enumerator/.travis.yml b/vendor/sebastian/object-enumerator/.travis.yml
new file mode 100644
index 0000000..1682d9c
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/.travis.yml
@@ -0,0 +1,23 @@
+language: php
+
+php:
+ - 5.6
+ - 7.0
+ - 7.1
+ - nightly
+
+sudo: false
+
+before_install:
+ - composer self-update
+ - composer clear-cache
+
+install:
+ - travis_retry composer update --no-interaction --no-ansi --no-progress --no-suggest --optimize-autoloader --prefer-stable
+
+script:
+ - ./vendor/bin/phpunit
+
+notifications:
+ email: false
+
diff --git a/vendor/sebastian/object-enumerator/ChangeLog.md b/vendor/sebastian/object-enumerator/ChangeLog.md
new file mode 100644
index 0000000..1f34bb9
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/ChangeLog.md
@@ -0,0 +1,25 @@
+# Change Log
+
+All notable changes to `sebastianbergmann/object-enumerator` are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
+
+## [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
+
+[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 0000000..4e96f75
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/LICENSE
@@ -0,0 +1,33 @@
+Object Enumerator
+
+Copyright (c) 2016, Sebastian Bergmann <sebastian@phpunit.de>.
+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 0000000..be6f2dd
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/README.md
@@ -0,0 +1,14 @@
+# 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/build.xml b/vendor/sebastian/object-enumerator/build.xml
new file mode 100644
index 0000000..b125702
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/build.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="object-enumerator" default="setup">
+ <target name="setup" depends="clean,composer"/>
+
+ <target name="clean" description="Cleanup build artifacts">
+ <delete dir="${basedir}/vendor"/>
+ <delete file="${basedir}/composer.lock"/>
+ </target>
+
+ <target name="composer" depends="clean" description="Install dependencies with Composer">
+ <exec executable="composer" taskname="composer">
+ <env key="COMPOSER_DISABLE_XDEBUG_WARN" value="1"/>
+ <arg value="update"/>
+ <arg value="--no-interaction"/>
+ <arg value="--no-progress"/>
+ <arg value="--no-ansi"/>
+ <arg value="--no-suggest"/>
+ <arg value="--optimize-autoloader"/>
+ <arg value="--prefer-stable"/>
+ </exec>
+ </target>
+</project>
+
diff --git a/vendor/sebastian/object-enumerator/composer.json b/vendor/sebastian/object-enumerator/composer.json
new file mode 100644
index 0000000..a699994
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/composer.json
@@ -0,0 +1,34 @@
+{
+ "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": "sebastian@phpunit.de"
+ }
+ ],
+ "require": {
+ "php": ">=5.6",
+ "sebastian/recursion-context": "~2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~5"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "autoload-dev": {
+ "classmap": [
+ "tests/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/object-enumerator/phpunit.xml b/vendor/sebastian/object-enumerator/phpunit.xml
new file mode 100644
index 0000000..c401ba8
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/phpunit.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/5.7/phpunit.xsd"
+ bootstrap="vendor/autoload.php"
+ backupGlobals="false"
+ beStrictAboutCoversAnnotation="true"
+ beStrictAboutOutputDuringTests="true"
+ beStrictAboutTestsThatDoNotTestAnything="true"
+ beStrictAboutTodoAnnotatedTests="true"
+ verbose="true">
+ <testsuite>
+ <directory suffix="Test.php">tests</directory>
+ </testsuite>
+
+ <filter>
+ <whitelist processUncoveredFilesFromWhitelist="true">
+ <directory suffix=".php">src</directory>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/vendor/sebastian/object-enumerator/src/Enumerator.php b/vendor/sebastian/object-enumerator/src/Enumerator.php
new file mode 100644
index 0000000..dbd4545
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/src/Enumerator.php
@@ -0,0 +1,93 @@
+<?php
+/*
+ * This file is part of Object Enumerator.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\ObjectEnumerator;
+
+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 \ReflectionObject($variable);
+
+ foreach ($reflector->getProperties() as $attribute) {
+ $attribute->setAccessible(true);
+
+ try {
+ $value = $attribute->getValue($variable);
+ } catch (\Throwable $e) {
+ continue;
+ } catch (\Exception $e) {
+ continue;
+ }
+
+ 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 0000000..903b0b1
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/src/Exception.php
@@ -0,0 +1,15 @@
+<?php
+/*
+ * This file is part of Object Enumerator.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\ObjectEnumerator;
+
+interface Exception
+{
+}
diff --git a/vendor/sebastian/object-enumerator/src/InvalidArgumentException.php b/vendor/sebastian/object-enumerator/src/InvalidArgumentException.php
new file mode 100644
index 0000000..5250c1a
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/src/InvalidArgumentException.php
@@ -0,0 +1,15 @@
+<?php
+/*
+ * This file is part of Object Enumerator.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * 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-enumerator/tests/EnumeratorTest.php b/vendor/sebastian/object-enumerator/tests/EnumeratorTest.php
new file mode 100644
index 0000000..d9510da
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/tests/EnumeratorTest.php
@@ -0,0 +1,138 @@
+<?php
+/*
+ * This file is part of Object Enumerator.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\ObjectEnumerator;
+
+use SebastianBergmann\ObjectEnumerator\Fixtures\ExceptionThrower;
+
+/**
+ * @covers SebastianBergmann\ObjectEnumerator\Enumerator
+ */
+class EnumeratorTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var Enumerator
+ */
+ private $enumerator;
+
+ protected function setUp()
+ {
+ $this->enumerator = new Enumerator;
+ }
+
+ public function testEnumeratesSingleObject()
+ {
+ $a = new \stdClass;
+
+ $objects = $this->enumerator->enumerate($a);
+
+ $this->assertCount(1, $objects);
+ $this->assertSame($a, $objects[0]);
+ }
+
+ public function testEnumeratesArrayWithSingleObject()
+ {
+ $a = new \stdClass;
+
+ $objects = $this->enumerator->enumerate([$a]);
+
+ $this->assertCount(1, $objects);
+ $this->assertSame($a, $objects[0]);
+ }
+
+ public function testEnumeratesArrayWithTwoReferencesToTheSameObject()
+ {
+ $a = new \stdClass;
+
+ $objects = $this->enumerator->enumerate([$a, $a]);
+
+ $this->assertCount(1, $objects);
+ $this->assertSame($a, $objects[0]);
+ }
+
+ public function testEnumeratesArrayOfObjects()
+ {
+ $a = new \stdClass;
+ $b = new \stdClass;
+
+ $objects = $this->enumerator->enumerate([$a, $b, null]);
+
+ $this->assertCount(2, $objects);
+ $this->assertSame($a, $objects[0]);
+ $this->assertSame($b, $objects[1]);
+ }
+
+ public function testEnumeratesObjectWithAggregatedObject()
+ {
+ $a = new \stdClass;
+ $b = new \stdClass;
+
+ $a->b = $b;
+ $a->c = null;
+
+ $objects = $this->enumerator->enumerate($a);
+
+ $this->assertCount(2, $objects);
+ $this->assertSame($a, $objects[0]);
+ $this->assertSame($b, $objects[1]);
+ }
+
+ public function testEnumeratesObjectWithAggregatedObjectsInArray()
+ {
+ $a = new \stdClass;
+ $b = new \stdClass;
+
+ $a->b = [$b];
+
+ $objects = $this->enumerator->enumerate($a);
+
+ $this->assertCount(2, $objects);
+ $this->assertSame($a, $objects[0]);
+ $this->assertSame($b, $objects[1]);
+ }
+
+ public function testEnumeratesObjectsWithCyclicReferences()
+ {
+ $a = new \stdClass;
+ $b = new \stdClass;
+
+ $a->b = $b;
+ $b->a = $a;
+
+ $objects = $this->enumerator->enumerate([$a, $b]);
+
+ $this->assertCount(2, $objects);
+ $this->assertSame($a, $objects[0]);
+ $this->assertSame($b, $objects[1]);
+ }
+
+ public function testEnumeratesClassThatThrowsException()
+ {
+ $thrower = new ExceptionThrower();
+
+ $objects = $this->enumerator->enumerate($thrower);
+
+ $this->assertSame($thrower, $objects[0]);
+ }
+
+ public function testExceptionIsRaisedForInvalidArgument()
+ {
+ $this->setExpectedException(InvalidArgumentException::class);
+
+ $this->enumerator->enumerate(null);
+ }
+
+ public function testExceptionIsRaisedForInvalidArgument2()
+ {
+ $this->setExpectedException(InvalidArgumentException::class);
+
+ $this->enumerator->enumerate([], '');
+ }
+}
diff --git a/vendor/sebastian/object-enumerator/tests/Fixtures/ExceptionThrower.php b/vendor/sebastian/object-enumerator/tests/Fixtures/ExceptionThrower.php
new file mode 100644
index 0000000..a75f585
--- /dev/null
+++ b/vendor/sebastian/object-enumerator/tests/Fixtures/ExceptionThrower.php
@@ -0,0 +1,28 @@
+<?php
+/*
+ * This file is part of Object Enumerator.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\ObjectEnumerator\Fixtures;
+
+use RuntimeException;
+
+class ExceptionThrower
+{
+ private $property;
+
+ public function __construct()
+ {
+ unset($this->property);
+ }
+
+ public function __get($property)
+ {
+ throw new RuntimeException;
+ }
+}
diff --git a/vendor/sebastian/recursion-context/.gitignore b/vendor/sebastian/recursion-context/.gitignore
new file mode 100644
index 0000000..3beb10f
--- /dev/null
+++ b/vendor/sebastian/recursion-context/.gitignore
@@ -0,0 +1,9 @@
+.idea
+phpunit.xml
+composer.lock
+composer.phar
+vendor/
+cache.properties
+build/LICENSE
+build/README.md
+build/*.tgz
diff --git a/vendor/sebastian/recursion-context/.travis.yml b/vendor/sebastian/recursion-context/.travis.yml
new file mode 100644
index 0000000..c5952a1
--- /dev/null
+++ b/vendor/sebastian/recursion-context/.travis.yml
@@ -0,0 +1,21 @@
+language: php
+
+php:
+ - 5.3.3
+ - 5.3
+ - 5.4
+ - 5.5
+ - 5.6
+ - hhvm
+
+sudo: false
+
+before_script:
+ - composer self-update
+ - composer install --no-interaction --prefer-source --dev
+
+script: ./vendor/bin/phpunit
+
+notifications:
+ email: false
+ irc: "irc.freenode.org#phpunit"
diff --git a/vendor/sebastian/recursion-context/LICENSE b/vendor/sebastian/recursion-context/LICENSE
new file mode 100644
index 0000000..f8c30c2
--- /dev/null
+++ b/vendor/sebastian/recursion-context/LICENSE
@@ -0,0 +1,33 @@
+Recursion Context
+
+Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
+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 0000000..0b89496
--- /dev/null
+++ b/vendor/sebastian/recursion-context/README.md
@@ -0,0 +1,14 @@
+# 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/build.xml b/vendor/sebastian/recursion-context/build.xml
new file mode 100644
index 0000000..b4fd193
--- /dev/null
+++ b/vendor/sebastian/recursion-context/build.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="recursion-context">
+ <target name="clean" description="Cleanup build artifacts">
+ <delete dir="${basedir}/vendor"/>
+ <delete file="${basedir}/composer.lock"/>
+ </target>
+
+ <target name="composer" depends="clean" description="Install dependencies with Composer">
+ <tstamp>
+ <format property="thirty.days.ago" pattern="MM/dd/yyyy hh:mm aa" offset="-30" unit="day"/>
+ </tstamp>
+ <delete>
+ <fileset dir="${basedir}">
+ <include name="composer.phar" />
+ <date datetime="${thirty.days.ago}" when="before"/>
+ </fileset>
+ </delete>
+
+ <get src="https://getcomposer.org/composer.phar" dest="${basedir}/composer.phar" skipexisting="true"/>
+
+ <exec executable="php">
+ <arg value="composer.phar"/>
+ <arg value="install"/>
+ </exec>
+ </target>
+</project>
+
diff --git a/vendor/sebastian/recursion-context/composer.json b/vendor/sebastian/recursion-context/composer.json
new file mode 100644
index 0000000..c5c5aaf
--- /dev/null
+++ b/vendor/sebastian/recursion-context/composer.json
@@ -0,0 +1,36 @@
+{
+ "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": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/recursion-context/phpunit.xml.dist b/vendor/sebastian/recursion-context/phpunit.xml.dist
new file mode 100644
index 0000000..757e3e6
--- /dev/null
+++ b/vendor/sebastian/recursion-context/phpunit.xml.dist
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit backupGlobals="false"
+ bootstrap="vendor/autoload.php"
+ beStrictAboutTestsThatDoNotTestAnything="true"
+ beStrictAboutOutputDuringTests="true"
+ beStrictAboutTodoAnnotatedTests="true"
+ checkForUnintentionallyCoveredCode="true"
+ forceCoversAnnotation="true"
+ verbose="true">
+<testsuites>
+ <testsuite name="recursion-context">
+ <directory>tests</directory>
+ </testsuite>
+ </testsuites>
+ <filter>
+ <whitelist addUncoveredFilesFromWhitelist="true" processUncoveredFilesFromWhitelist="true">
+ <directory>src</directory>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/vendor/sebastian/recursion-context/src/Context.php b/vendor/sebastian/recursion-context/src/Context.php
new file mode 100644
index 0000000..0b4b8a0
--- /dev/null
+++ b/vendor/sebastian/recursion-context/src/Context.php
@@ -0,0 +1,167 @@
+<?php
+/*
+ * This file is part of the Recursion Context package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\RecursionContext;
+
+/**
+ * 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 = array();
+ $this->objects = new \SplObjectStorage;
+ }
+
+ /**
+ * Adds a value to the context.
+ *
+ * @param array|object $value The value to add.
+ *
+ * @return int|string The ID of the stored value, either as a string or integer.
+ *
+ * @throws InvalidArgumentException Thrown if $value is not an array or object
+ */
+ public function add(&$value)
+ {
+ if (is_array($value)) {
+ return $this->addArray($value);
+ } elseif (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.
+ *
+ * @return int|string|false The string or integer ID of the stored value if it has already been seen, or false if the value is not stored.
+ *
+ * @throws InvalidArgumentException Thrown if $value is not an array or object
+ */
+ public function contains(&$value)
+ {
+ if (is_array($value)) {
+ return $this->containsArray($value);
+ } elseif (is_object($value)) {
+ return $this->containsObject($value);
+ }
+
+ throw new InvalidArgumentException(
+ 'Only arrays and objects are supported'
+ );
+ }
+
+ /**
+ * @param array $array
+ *
+ * @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
+ *
+ * @return string
+ */
+ private function addObject($object)
+ {
+ if (!$this->objects->contains($object)) {
+ $this->objects->attach($object);
+ }
+
+ return spl_object_hash($object);
+ }
+
+ /**
+ * @param array $array
+ *
+ * @return int|false
+ */
+ 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 string|false
+ */
+ private function containsObject($value)
+ {
+ if ($this->objects->contains($value)) {
+ return spl_object_hash($value);
+ }
+
+ return false;
+ }
+
+ public function __destruct()
+ {
+ foreach ($this->arrays as &$array) {
+ if (is_array($array)) {
+ array_pop($array);
+ array_pop($array);
+ }
+ }
+ }
+}
diff --git a/vendor/sebastian/recursion-context/src/Exception.php b/vendor/sebastian/recursion-context/src/Exception.php
new file mode 100644
index 0000000..4a1557b
--- /dev/null
+++ b/vendor/sebastian/recursion-context/src/Exception.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of the Recursion Context package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\RecursionContext;
+
+/**
+ */
+interface Exception
+{
+}
diff --git a/vendor/sebastian/recursion-context/src/InvalidArgumentException.php b/vendor/sebastian/recursion-context/src/InvalidArgumentException.php
new file mode 100644
index 0000000..032c504
--- /dev/null
+++ b/vendor/sebastian/recursion-context/src/InvalidArgumentException.php
@@ -0,0 +1,17 @@
+<?php
+/*
+ * This file is part of the Recursion Context package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * 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/recursion-context/tests/ContextTest.php b/vendor/sebastian/recursion-context/tests/ContextTest.php
new file mode 100644
index 0000000..cee0bcf
--- /dev/null
+++ b/vendor/sebastian/recursion-context/tests/ContextTest.php
@@ -0,0 +1,144 @@
+<?php
+/*
+ * This file is part of the Recursion Context package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\RecursionContext;
+
+use PHPUnit_Framework_TestCase;
+
+/**
+ * @covers SebastianBergmann\RecursionContext\Context
+ */
+class ContextTest extends PHPUnit_Framework_TestCase
+{
+ /**
+ * @var \SebastianBergmann\RecursionContext\Context
+ */
+ private $context;
+
+ protected function setUp()
+ {
+ $this->context = new Context();
+ }
+
+ public function failsProvider()
+ {
+ return array(
+ array(true),
+ array(false),
+ array(null),
+ array('string'),
+ array(1),
+ array(1.5),
+ array(fopen('php://memory', 'r'))
+ );
+ }
+
+ public function valuesProvider()
+ {
+ $obj2 = new \stdClass();
+ $obj2->foo = 'bar';
+
+ $obj3 = (object) array(1,2,"Test\r\n",4,5,6,7,8);
+
+ $obj = new \stdClass();
+ //@codingStandardsIgnoreStart
+ $obj->null = null;
+ //@codingStandardsIgnoreEnd
+ $obj->boolean = true;
+ $obj->integer = 1;
+ $obj->double = 1.2;
+ $obj->string = '1';
+ $obj->text = "this\nis\na\nvery\nvery\nvery\nvery\nvery\nvery\rlong\n\rtext";
+ $obj->object = $obj2;
+ $obj->objectagain = $obj2;
+ $obj->array = array('foo' => 'bar');
+ $obj->array2 = array(1,2,3,4,5,6);
+ $obj->array3 = array($obj, $obj2, $obj3);
+ $obj->self = $obj;
+
+ $storage = new \SplObjectStorage();
+ $storage->attach($obj2);
+ $storage->foo = $obj2;
+
+ return array(
+ array($obj, spl_object_hash($obj)),
+ array($obj2, spl_object_hash($obj2)),
+ array($obj3, spl_object_hash($obj3)),
+ array($storage, spl_object_hash($storage)),
+ array($obj->array, 0),
+ array($obj->array2, 0),
+ array($obj->array3, 0)
+ );
+ }
+
+ /**
+ * @covers SebastianBergmann\RecursionContext\Context::add
+ * @uses SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @dataProvider failsProvider
+ */
+ public function testAddFails($value)
+ {
+ $this->setExpectedException(
+ 'SebastianBergmann\\RecursionContext\\Exception',
+ 'Only arrays and objects are supported'
+ );
+ $this->context->add($value);
+ }
+
+ /**
+ * @covers SebastianBergmann\RecursionContext\Context::contains
+ * @uses SebastianBergmann\RecursionContext\InvalidArgumentException
+ * @dataProvider failsProvider
+ */
+ public function testContainsFails($value)
+ {
+ $this->setExpectedException(
+ 'SebastianBergmann\\RecursionContext\\Exception',
+ 'Only arrays and objects are supported'
+ );
+ $this->context->contains($value);
+ }
+
+ /**
+ * @covers SebastianBergmann\RecursionContext\Context::add
+ * @dataProvider valuesProvider
+ */
+ public function testAdd($value, $key)
+ {
+ $this->assertEquals($key, $this->context->add($value));
+
+ // Test we get the same key on subsequent adds
+ $this->assertEquals($key, $this->context->add($value));
+ }
+
+ /**
+ * @covers SebastianBergmann\RecursionContext\Context::contains
+ * @uses SebastianBergmann\RecursionContext\Context::add
+ * @depends testAdd
+ * @dataProvider valuesProvider
+ */
+ public function testContainsFound($value, $key)
+ {
+ $this->context->add($value);
+ $this->assertEquals($key, $this->context->contains($value));
+
+ // Test we get the same key on subsequent calls
+ $this->assertEquals($key, $this->context->contains($value));
+ }
+
+ /**
+ * @covers SebastianBergmann\RecursionContext\Context::contains
+ * @dataProvider valuesProvider
+ */
+ public function testContainsNotFound($value)
+ {
+ $this->assertFalse($this->context->contains($value));
+ }
+}
diff --git a/vendor/sebastian/resource-operations/.gitignore b/vendor/sebastian/resource-operations/.gitignore
new file mode 100644
index 0000000..d974001
--- /dev/null
+++ b/vendor/sebastian/resource-operations/.gitignore
@@ -0,0 +1,3 @@
+/.idea
+/build/arginfo.php
+
diff --git a/vendor/sebastian/resource-operations/LICENSE b/vendor/sebastian/resource-operations/LICENSE
new file mode 100644
index 0000000..a80fe67
--- /dev/null
+++ b/vendor/sebastian/resource-operations/LICENSE
@@ -0,0 +1,33 @@
+Resource Operations
+
+Copyright (c) 2015, Sebastian Bergmann <sebastian@phpunit.de>.
+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 0000000..c7f5fe2
--- /dev/null
+++ b/vendor/sebastian/resource-operations/README.md
@@ -0,0 +1,16 @@
+# Resource Operations
+
+Provides a list of PHP built-in functions that operate on resources.
+
+## Installation
+
+To add this component as a local, per-project dependency to your project, simply add a dependency on `sebastian/resource-operations` to your project's `composer.json` file. Here is a minimal example of a `composer.json` file that just defines a dependency on this component:
+
+```JSON
+{
+ "require": {
+ "sebastian/resource-operations": "~1.0"
+ }
+}
+```
+
diff --git a/vendor/sebastian/resource-operations/build.xml b/vendor/sebastian/resource-operations/build.xml
new file mode 100644
index 0000000..ba13683
--- /dev/null
+++ b/vendor/sebastian/resource-operations/build.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="resource-operations" default="build">
+ <target name="build" depends="generate" />
+
+ <target name="generate" depends="download-arginfo">
+ <exec executable="${basedir}/build/generate.php" taskname="generate" />
+ </target>
+
+ <target name="download-arginfo">
+ <tstamp>
+ <format property="thirty.days.ago" pattern="MM/dd/yyyy hh:mm aa" offset="-30" unit="day"/>
+ </tstamp>
+
+ <delete>
+ <fileset dir="${basedir}/build">
+ <include name="arginfo.php" />
+ <date datetime="${thirty.days.ago}" when="before"/>
+ </fileset>
+ </delete>
+
+ <get src="https://raw.githubusercontent.com/rlerdorf/phan/master/includes/arginfo.php" dest="${basedir}/build/arginfo.php" skipexisting="true"/>
+ </target>
+</project>
+
diff --git a/vendor/sebastian/resource-operations/build/generate.php b/vendor/sebastian/resource-operations/build/generate.php
new file mode 100755
index 0000000..9570440
--- /dev/null
+++ b/vendor/sebastian/resource-operations/build/generate.php
@@ -0,0 +1,62 @@
+#!/usr/bin/env php
+<?php
+/*
+ * This file is part of resource-operations.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+$functions = require __DIR__ . '/arginfo.php';
+$resourceFunctions = [];
+
+foreach ($functions as $function => $arguments) {
+ foreach ($arguments as $argument) {
+ if ($argument == 'resource') {
+ $resourceFunctions[] = $function;
+ }
+ }
+}
+
+$resourceFunctions = array_unique($resourceFunctions);
+sort($resourceFunctions);
+
+$buffer = <<<EOT
+<?php
+/*
+ * This file is part of resource-operations.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\ResourceOperations;
+
+class ResourceOperations
+{
+ /**
+ * @return string[]
+ */
+ public static function getFunctions()
+ {
+ 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 0000000..da495d6
--- /dev/null
+++ b/vendor/sebastian/resource-operations/composer.json
@@ -0,0 +1,26 @@
+{
+ "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": "sebastian@phpunit.de"
+ }
+ ],
+ "require": {
+ "php": ">=5.6.0"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ }
+}
+
diff --git a/vendor/sebastian/resource-operations/src/ResourceOperations.php b/vendor/sebastian/resource-operations/src/ResourceOperations.php
new file mode 100644
index 0000000..87d000c
--- /dev/null
+++ b/vendor/sebastian/resource-operations/src/ResourceOperations.php
@@ -0,0 +1,670 @@
+<?php
+/*
+ * This file is part of resource-operations.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann\ResourceOperations;
+
+class ResourceOperations
+{
+ /**
+ * @return string[]
+ */
+ public static function getFunctions()
+ {
+ return [
+ 'Directory::close',
+ 'Directory::read',
+ 'Directory::rewind',
+ 'HttpResponse::getRequestBodyStream',
+ 'HttpResponse::getStream',
+ 'MongoGridFSCursor::__construct',
+ 'MongoGridFSFile::getResource',
+ 'MysqlndUhConnection::stmtInit',
+ 'MysqlndUhConnection::storeResult',
+ 'MysqlndUhConnection::useResult',
+ 'PDF_new',
+ 'PDO::pgsqlLOBOpen',
+ 'RarEntry::getStream',
+ 'SQLite3::openBlob',
+ 'XMLWriter::openMemory',
+ 'XMLWriter::openURI',
+ 'ZipArchive::getStream',
+ 'bbcode_create',
+ 'bzopen',
+ 'crack_opendict',
+ 'cubrid_connect',
+ 'cubrid_connect_with_url',
+ 'cubrid_get_query_timeout',
+ '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_pconnect',
+ 'cubrid_pconnect_with_url',
+ 'cubrid_prepare',
+ 'cubrid_query',
+ 'cubrid_set_query_timeout',
+ 'cubrid_unbuffered_query',
+ 'curl_copy_handle',
+ 'curl_getinfo',
+ 'curl_init',
+ 'curl_multi_add_handle',
+ 'curl_multi_close',
+ 'curl_multi_exec',
+ 'curl_multi_getcontent',
+ 'curl_multi_info_read',
+ 'curl_multi_init',
+ 'curl_multi_remove_handle',
+ 'curl_multi_select',
+ 'curl_multi_setopt',
+ 'curl_pause',
+ 'curl_reset',
+ 'curl_setopt',
+ 'curl_setopt_array',
+ 'curl_share_close',
+ 'curl_share_init',
+ 'curl_share_setopt',
+ 'curl_unescape',
+ 'cyrus_connect',
+ 'db2_column_privileges',
+ 'db2_columns',
+ 'db2_connect',
+ 'db2_exec',
+ 'db2_foreign_keys',
+ 'db2_next_result',
+ 'db2_pconnect',
+ 'db2_prepare',
+ 'db2_primary_keys',
+ 'db2_procedure_columns',
+ 'db2_procedures',
+ 'db2_special_columns',
+ 'db2_statistics',
+ 'db2_table_privileges',
+ 'db2_tables',
+ 'dba_fetch',
+ 'dba_fetch 1',
+ 'dba_open',
+ 'dba_popen',
+ 'dbplus_aql',
+ 'dbplus_open',
+ 'dbplus_rcreate',
+ 'dbplus_ropen',
+ 'dbplus_rquery',
+ 'dbplus_sql',
+ 'deflate_init',
+ 'dio_open',
+ '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_free_dict',
+ 'enchant_broker_init',
+ 'enchant_broker_request_dict',
+ 'enchant_broker_request_pwl_dict',
+ 'event_base_new',
+ 'event_base_reinit',
+ 'event_buffer_new',
+ 'event_new',
+ 'event_priority_set',
+ 'event_timer_set',
+ 'expect_popen',
+ 'fam_monitor_collection',
+ 'fam_monitor_directory',
+ 'fam_monitor_file',
+ 'fam_open',
+ '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_connect',
+ 'fbsql_db_query',
+ 'fbsql_list_dbs',
+ 'fbsql_list_fields',
+ 'fbsql_list_tables',
+ 'fbsql_pconnect',
+ 'fbsql_query',
+ 'fdf_create',
+ 'fdf_open',
+ 'fdf_open_string',
+ 'finfo::buffer',
+ 'finfo_buffer',
+ 'finfo_close',
+ 'finfo_file',
+ 'finfo_open',
+ 'finfo_set_flags',
+ 'fopen',
+ 'fsockopen',
+ 'ftp_alloc',
+ 'ftp_cdup',
+ 'ftp_chdir',
+ 'ftp_chmod',
+ 'ftp_close',
+ 'ftp_connect',
+ 'ftp_delete',
+ 'ftp_exec',
+ 'ftp_fget',
+ 'ftp_fput',
+ 'ftp_get',
+ 'ftp_get_option',
+ 'ftp_login',
+ 'ftp_mdtm',
+ 'ftp_mkdir',
+ 'ftp_nb_continue',
+ 'ftp_nb_fget',
+ 'ftp_nb_fput',
+ 'ftp_nb_get',
+ 'ftp_nb_put',
+ 'ftp_nlist',
+ 'ftp_pasv',
+ 'ftp_put',
+ 'ftp_pwd',
+ 'ftp_raw',
+ 'ftp_rawlist',
+ 'ftp_rename',
+ 'ftp_rmdir',
+ 'ftp_set_option',
+ 'ftp_site',
+ 'ftp_size',
+ 'ftp_ssl_connect',
+ 'ftp_systype',
+ 'gnupg_init',
+ 'gupnp_context_new',
+ 'gupnp_control_point_new',
+ 'gupnp_device_info_get_service',
+ 'gupnp_root_device_new',
+ 'gzopen',
+ 'hash_copy',
+ 'hash_final',
+ 'hash_init',
+ 'hash_update',
+ 'hash_update_file',
+ 'hash_update_stream',
+ 'http_get_request_body_stream',
+ 'ibase_blob_create',
+ 'ibase_blob_open',
+ 'ibase_blob_open 1',
+ 'ibase_connect',
+ 'ibase_pconnect',
+ 'ibase_prepare',
+ 'ibase_service_attach',
+ 'ibase_set_event_handler',
+ 'ibase_set_event_handler 1',
+ 'ibase_trans',
+ 'ifx_connect',
+ 'ifx_pconnect',
+ 'ifx_prepare',
+ 'ifx_query',
+ 'imageaffine',
+ 'imageconvolution',
+ 'imagecreate',
+ 'imagecreatefromgd',
+ 'imagecreatefromgd2',
+ 'imagecreatefromgd2part',
+ 'imagecreatefromgif',
+ 'imagecreatefromjpeg',
+ 'imagecreatefrompng',
+ 'imagecreatefromstring',
+ 'imagecreatefromwbmp',
+ 'imagecreatefromwebp',
+ 'imagecreatefromxbm',
+ 'imagecreatefromxpm',
+ 'imagecreatetruecolor',
+ 'imagegrabscreen',
+ 'imagegrabwindow',
+ 'imagepalettetotruecolor',
+ 'imagepsloadfont',
+ 'imagerotate',
+ 'imagescale',
+ 'imap_open',
+ 'inflate_init',
+ 'ingres_connect',
+ 'ingres_pconnect',
+ 'inotify_init',
+ 'kadm5_init_with_password',
+ 'ldap_connect',
+ 'ldap_first_entry',
+ 'ldap_first_reference',
+ 'ldap_list',
+ 'ldap_next_entry',
+ 'ldap_next_reference',
+ 'ldap_read',
+ 'ldap_search',
+ 'm_initconn',
+ 'mailparse_msg_create',
+ 'mailparse_msg_get_part',
+ 'mailparse_msg_parse_file',
+ 'maxdb::use_result',
+ 'maxdb_connect',
+ 'maxdb_embedded_connect',
+ 'maxdb_init',
+ 'maxdb_stmt::result_metadata',
+ 'maxdb_stmt_result_metadata',
+ 'maxdb_use_result',
+ 'mcrypt_module_open',
+ 'msg_get_queue',
+ 'msql_connect',
+ 'msql_db_query',
+ 'msql_list_dbs',
+ 'msql_list_fields',
+ 'msql_list_tables',
+ 'msql_pconnect',
+ 'msql_query',
+ 'mssql_connect',
+ 'mssql_init',
+ 'mssql_pconnect',
+ 'mysql_connect',
+ 'mysql_db_query',
+ 'mysql_list_dbs',
+ 'mysql_list_fields',
+ 'mysql_list_processes',
+ 'mysql_list_tables',
+ 'mysql_pconnect',
+ 'mysql_query',
+ 'mysql_unbuffered_query',
+ 'mysqlnd_uh_convert_to_mysqlnd',
+ 'ncurses_new_panel',
+ 'ncurses_newpad',
+ 'ncurses_newwin',
+ 'ncurses_panel_above',
+ 'ncurses_panel_below',
+ 'ncurses_panel_window',
+ 'newt_button',
+ 'newt_button_bar',
+ 'newt_checkbox',
+ 'newt_checkbox_tree',
+ 'newt_checkbox_tree_multi',
+ 'newt_compact_button',
+ 'newt_create_grid',
+ 'newt_entry',
+ 'newt_form',
+ 'newt_form_get_current',
+ 'newt_grid_basic_window',
+ 'newt_grid_h_close_stacked',
+ 'newt_grid_h_stacked',
+ 'newt_grid_simple_window',
+ 'newt_grid_v_close_stacked',
+ 'newt_grid_v_stacked',
+ 'newt_label',
+ 'newt_listbox',
+ 'newt_listitem',
+ 'newt_radio_get_current',
+ 'newt_radiobutton',
+ 'newt_run_form',
+ 'newt_scale',
+ 'newt_textbox',
+ 'newt_textbox_reflowed',
+ 'newt_vertical_scrollbar',
+ 'oci_connect',
+ 'oci_get_implicit_resultset',
+ 'oci_new_connect',
+ 'oci_new_cursor',
+ 'oci_parse',
+ 'oci_pconnect',
+ 'odbc_columnprivileges',
+ 'odbc_columns',
+ 'odbc_connect',
+ 'odbc_exec',
+ 'odbc_foreignkeys',
+ 'odbc_gettypeinfo',
+ 'odbc_pconnect',
+ 'odbc_prepare',
+ 'odbc_primarykeys',
+ 'odbc_procedurecolumns',
+ 'odbc_procedures',
+ 'odbc_specialcolumns',
+ 'odbc_statistics',
+ 'odbc_tableprivileges',
+ 'odbc_tables',
+ 'openal_buffer_create',
+ 'openal_context_create',
+ 'openal_device_open',
+ 'openal_source_create',
+ 'openal_stream',
+ 'openssl_csr_new',
+ 'openssl_csr_sign',
+ 'openssl_pkey_get_private',
+ 'openssl_pkey_get_public',
+ 'openssl_pkey_new',
+ 'openssl_x509_read',
+ 'pfsockopen',
+ 'pg_cancel_query',
+ 'pg_client_encoding',
+ 'pg_close',
+ 'pg_connect',
+ 'pg_connect_poll',
+ 'pg_connection_busy',
+ 'pg_connection_reset',
+ 'pg_connection_status',
+ 'pg_consume_input',
+ 'pg_copy_from',
+ 'pg_copy_to',
+ 'pg_dbname',
+ 'pg_end_copy',
+ 'pg_escape_bytea',
+ 'pg_escape_identifier',
+ 'pg_escape_identifier 1',
+ 'pg_escape_literal',
+ 'pg_escape_string',
+ 'pg_execute',
+ 'pg_execute 1',
+ 'pg_flush',
+ 'pg_free_result',
+ 'pg_get_notify',
+ 'pg_get_pid',
+ 'pg_get_result',
+ 'pg_host',
+ 'pg_last_error',
+ 'pg_last_notice',
+ 'pg_lo_create',
+ 'pg_lo_export',
+ 'pg_lo_import',
+ 'pg_lo_open',
+ 'pg_lo_unlink',
+ 'pg_options',
+ 'pg_parameter_status',
+ 'pg_pconnect',
+ 'pg_ping',
+ 'pg_port',
+ 'pg_prepare',
+ 'pg_prepare 1',
+ 'pg_put_line',
+ 'pg_query',
+ 'pg_query 1',
+ 'pg_query_params',
+ 'pg_query_params 1',
+ 'pg_send_execute',
+ 'pg_send_prepare',
+ 'pg_send_query',
+ 'pg_send_query_params',
+ 'pg_set_client_encoding',
+ 'pg_set_client_encoding 1',
+ 'pg_set_error_verbosity',
+ 'pg_socket',
+ 'pg_trace',
+ 'pg_transaction_status',
+ 'pg_tty',
+ 'pg_untrace',
+ 'pg_version',
+ 'php_user_filter::filter',
+ 'popen',
+ 'proc_open',
+ 'ps_new',
+ 'px_new',
+ 'radius_acct_open',
+ 'radius_auth_open',
+ 'radius_salt_encrypt_attr',
+ 'rpm_open',
+ 'sem_get',
+ 'shm_attach',
+ 'socket_accept',
+ 'socket_create',
+ 'socket_create_listen',
+ 'socket_recvmsg',
+ 'socket_sendmsg',
+ '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_connect',
+ 'ssh2_exec',
+ 'ssh2_fetch_stream',
+ 'ssh2_publickey_init',
+ 'ssh2_sftp',
+ 'ssh2_sftp_chmod',
+ 'ssh2_shell',
+ 'ssh2_tunnel',
+ 'stomp_connect',
+ 'streamWrapper::stream_cast',
+ 'stream_bucket_new',
+ 'stream_context_create',
+ 'stream_context_get_default',
+ 'stream_context_set_default',
+ 'stream_filter_append',
+ 'stream_filter_prepend',
+ 'stream_socket_accept',
+ 'stream_socket_client',
+ 'stream_socket_server',
+ 'svn_fs_apply_text',
+ 'svn_fs_begin_txn2',
+ 'svn_fs_file_contents',
+ 'svn_fs_revision_root',
+ 'svn_fs_txn_root',
+ 'svn_repos_create',
+ 'svn_repos_fs',
+ 'svn_repos_fs_begin_txn_for_commit',
+ 'svn_repos_open',
+ 'sybase_connect',
+ 'sybase_pconnect',
+ 'sybase_unbuffered_query',
+ 'tmpfile',
+ 'udm_alloc_agent',
+ 'udm_alloc_agent_array',
+ 'udm_find',
+ 'unlink',
+ 'w32api_init_dtype',
+ 'wddx_packet_start',
+ 'xml_parser_create',
+ 'xml_parser_create_ns',
+ 'xml_parser_free',
+ 'xml_parser_get_option',
+ 'xml_parser_set_option',
+ 'xmlrpc_server_create',
+ 'xmlwriter_open_memory',
+ 'xmlwriter_open_uri',
+ 'xslt_create',
+ 'zip_open',
+ 'zip_read',
+ ];
+ }
+}
diff --git a/vendor/sebastian/version/.gitattributes b/vendor/sebastian/version/.gitattributes
new file mode 100644
index 0000000..461090b
--- /dev/null
+++ b/vendor/sebastian/version/.gitattributes
@@ -0,0 +1 @@
+*.php diff=php
diff --git a/vendor/sebastian/version/.gitignore b/vendor/sebastian/version/.gitignore
new file mode 100644
index 0000000..a09c56d
--- /dev/null
+++ b/vendor/sebastian/version/.gitignore
@@ -0,0 +1 @@
+/.idea
diff --git a/vendor/sebastian/version/.php_cs b/vendor/sebastian/version/.php_cs
new file mode 100644
index 0000000..8cbc57c
--- /dev/null
+++ b/vendor/sebastian/version/.php_cs
@@ -0,0 +1,66 @@
+<?php
+$finder = Symfony\CS\Finder\DefaultFinder::create()
+ ->files()
+ ->in('src')
+ ->name('*.php');
+
+return Symfony\CS\Config\Config::create()
+ ->level(\Symfony\CS\FixerInterface::NONE_LEVEL)
+ ->fixers(
+ array(
+ 'align_double_arrow',
+ 'align_equals',
+ 'braces',
+ 'concat_with_spaces',
+ 'duplicate_semicolon',
+ 'elseif',
+ 'empty_return',
+ 'encoding',
+ 'eof_ending',
+ 'extra_empty_lines',
+ 'function_call_space',
+ 'function_declaration',
+ 'indentation',
+ 'join_function',
+ 'line_after_namespace',
+ 'linefeed',
+ 'list_commas',
+ 'lowercase_constants',
+ 'lowercase_keywords',
+ 'method_argument_space',
+ 'multiple_use',
+ 'namespace_no_leading_whitespace',
+ 'no_blank_lines_after_class_opening',
+ 'no_empty_lines_after_phpdocs',
+ 'parenthesis',
+ 'php_closing_tag',
+ 'phpdoc_indent',
+ 'phpdoc_no_access',
+ 'phpdoc_no_empty_return',
+ 'phpdoc_no_package',
+ 'phpdoc_params',
+ 'phpdoc_scalar',
+ 'phpdoc_separation',
+ 'phpdoc_to_comment',
+ 'phpdoc_trim',
+ 'phpdoc_types',
+ 'phpdoc_var_without_name',
+ 'remove_lines_between_uses',
+ 'return',
+ 'self_accessor',
+ 'short_array_syntax',
+ 'short_tag',
+ 'single_line_after_imports',
+ 'single_quote',
+ 'spaces_before_semicolon',
+ 'spaces_cast',
+ 'ternary_spaces',
+ 'trailing_spaces',
+ 'trim_array_spaces',
+ 'unused_use',
+ 'visibility',
+ 'whitespacy_lines'
+ )
+ )
+ ->finder($finder);
+
diff --git a/vendor/sebastian/version/LICENSE b/vendor/sebastian/version/LICENSE
new file mode 100644
index 0000000..5b79c41
--- /dev/null
+++ b/vendor/sebastian/version/LICENSE
@@ -0,0 +1,33 @@
+Version
+
+Copyright (c) 2013-2015, Sebastian Bergmann <sebastian@phpunit.de>.
+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 0000000..2864c81
--- /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 0000000..3b87814
--- /dev/null
+++ b/vendor/sebastian/version/composer.json
@@ -0,0 +1,29 @@
+{
+ "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": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/version/issues"
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/sebastian/version/src/Version.php b/vendor/sebastian/version/src/Version.php
new file mode 100644
index 0000000..fc4cfec
--- /dev/null
+++ b/vendor/sebastian/version/src/Version.php
@@ -0,0 +1,109 @@
+<?php
+/*
+ * This file is part of the Version package.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SebastianBergmann;
+
+/**
+ * @since Class available since Release 1.0.0
+ */
+class Version
+{
+ /**
+ * @var string
+ */
+ private $path;
+
+ /**
+ * @var string
+ */
+ private $release;
+
+ /**
+ * @var string
+ */
+ private $version;
+
+ /**
+ * @param string $release
+ * @param string $path
+ */
+ public function __construct($release, $path)
+ {
+ $this->release = $release;
+ $this->path = $path;
+ }
+
+ /**
+ * @return string
+ */
+ public function getVersion()
+ {
+ if ($this->version === null) {
+ if (count(explode('.', $this->release)) == 3) {
+ $this->version = $this->release;
+ } else {
+ $this->version = $this->release . '-dev';
+ }
+
+ $git = $this->getGitInformation($this->path);
+
+ if ($git) {
+ if (count(explode('.', $this->release)) == 3) {
+ $this->version = $git;
+ } else {
+ $git = explode('-', $git);
+
+ $this->version = $this->release . '-' . end($git);
+ }
+ }
+ }
+
+ return $this->version;
+ }
+
+ /**
+ * @param string $path
+ *
+ * @return bool|string
+ */
+ private function getGitInformation($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;
+ }
+}
diff --git a/vendor/symfony/polyfill-ctype/Ctype.php b/vendor/symfony/polyfill-ctype/Ctype.php
new file mode 100644
index 0000000..58414dc
--- /dev/null
+++ b/vendor/symfony/polyfill-ctype/Ctype.php
@@ -0,0 +1,227 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Polyfill\Ctype;
+
+/**
+ * Ctype implementation through regex.
+ *
+ * @internal
+ *
+ * @author Gert de Pagter <BackEndTea@gmail.com>
+ */
+final class Ctype
+{
+ /**
+ * Returns TRUE if every character in text is either a letter or a digit, FALSE otherwise.
+ *
+ * @see https://php.net/ctype-alnum
+ *
+ * @param string|int $text
+ *
+ * @return bool
+ */
+ public static function ctype_alnum($text)
+ {
+ $text = self::convert_int_to_char_for_ctype($text);
+
+ return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z0-9]/', $text);
+ }
+
+ /**
+ * Returns TRUE if every character in text is a letter, FALSE otherwise.
+ *
+ * @see https://php.net/ctype-alpha
+ *
+ * @param string|int $text
+ *
+ * @return bool
+ */
+ public static function ctype_alpha($text)
+ {
+ $text = self::convert_int_to_char_for_ctype($text);
+
+ return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z]/', $text);
+ }
+
+ /**
+ * Returns TRUE if every character in text is a control character from the current locale, FALSE otherwise.
+ *
+ * @see https://php.net/ctype-cntrl
+ *
+ * @param string|int $text
+ *
+ * @return bool
+ */
+ public static function ctype_cntrl($text)
+ {
+ $text = self::convert_int_to_char_for_ctype($text);
+
+ return \is_string($text) && '' !== $text && !preg_match('/[^\x00-\x1f\x7f]/', $text);
+ }
+
+ /**
+ * Returns TRUE if every character in the string text is a decimal digit, FALSE otherwise.
+ *
+ * @see https://php.net/ctype-digit
+ *
+ * @param string|int $text
+ *
+ * @return bool
+ */
+ public static function ctype_digit($text)
+ {
+ $text = self::convert_int_to_char_for_ctype($text);
+
+ return \is_string($text) && '' !== $text && !preg_match('/[^0-9]/', $text);
+ }
+
+ /**
+ * Returns TRUE if every character in text is printable and actually creates visible output (no white space), FALSE otherwise.
+ *
+ * @see https://php.net/ctype-graph
+ *
+ * @param string|int $text
+ *
+ * @return bool
+ */
+ public static function ctype_graph($text)
+ {
+ $text = self::convert_int_to_char_for_ctype($text);
+
+ return \is_string($text) && '' !== $text && !preg_match('/[^!-~]/', $text);
+ }
+
+ /**
+ * Returns TRUE if every character in text is a lowercase letter.
+ *
+ * @see https://php.net/ctype-lower
+ *
+ * @param string|int $text
+ *
+ * @return bool
+ */
+ public static function ctype_lower($text)
+ {
+ $text = self::convert_int_to_char_for_ctype($text);
+
+ return \is_string($text) && '' !== $text && !preg_match('/[^a-z]/', $text);
+ }
+
+ /**
+ * Returns TRUE if every character in text will actually create output (including blanks). Returns FALSE if text contains control characters or characters that do not have any output or control function at all.
+ *
+ * @see https://php.net/ctype-print
+ *
+ * @param string|int $text
+ *
+ * @return bool
+ */
+ public static function ctype_print($text)
+ {
+ $text = self::convert_int_to_char_for_ctype($text);
+
+ return \is_string($text) && '' !== $text && !preg_match('/[^ -~]/', $text);
+ }
+
+ /**
+ * Returns TRUE if every character in text is printable, but neither letter, digit or blank, FALSE otherwise.
+ *
+ * @see https://php.net/ctype-punct
+ *
+ * @param string|int $text
+ *
+ * @return bool
+ */
+ public static function ctype_punct($text)
+ {
+ $text = self::convert_int_to_char_for_ctype($text);
+
+ return \is_string($text) && '' !== $text && !preg_match('/[^!-\/\:-@\[-`\{-~]/', $text);
+ }
+
+ /**
+ * Returns TRUE if every character in text creates some sort of white space, FALSE otherwise. Besides the blank character this also includes tab, vertical tab, line feed, carriage return and form feed characters.
+ *
+ * @see https://php.net/ctype-space
+ *
+ * @param string|int $text
+ *
+ * @return bool
+ */
+ public static function ctype_space($text)
+ {
+ $text = self::convert_int_to_char_for_ctype($text);
+
+ return \is_string($text) && '' !== $text && !preg_match('/[^\s]/', $text);
+ }
+
+ /**
+ * Returns TRUE if every character in text is an uppercase letter.
+ *
+ * @see https://php.net/ctype-upper
+ *
+ * @param string|int $text
+ *
+ * @return bool
+ */
+ public static function ctype_upper($text)
+ {
+ $text = self::convert_int_to_char_for_ctype($text);
+
+ return \is_string($text) && '' !== $text && !preg_match('/[^A-Z]/', $text);
+ }
+
+ /**
+ * Returns TRUE if every character in text is a hexadecimal 'digit', that is a decimal digit or a character from [A-Fa-f] , FALSE otherwise.
+ *
+ * @see https://php.net/ctype-xdigit
+ *
+ * @param string|int $text
+ *
+ * @return bool
+ */
+ public static function ctype_xdigit($text)
+ {
+ $text = self::convert_int_to_char_for_ctype($text);
+
+ return \is_string($text) && '' !== $text && !preg_match('/[^A-Fa-f0-9]/', $text);
+ }
+
+ /**
+ * Converts integers to their char versions according to normal ctype behaviour, if needed.
+ *
+ * If an integer between -128 and 255 inclusive is provided,
+ * it is interpreted as the ASCII value of a single character
+ * (negative values have 256 added in order to allow characters in the Extended ASCII range).
+ * Any other integer is interpreted as a string containing the decimal digits of the integer.
+ *
+ * @param string|int $int
+ *
+ * @return mixed
+ */
+ private static function convert_int_to_char_for_ctype($int)
+ {
+ if (!\is_int($int)) {
+ return $int;
+ }
+
+ if ($int < -128 || $int > 255) {
+ return (string) $int;
+ }
+
+ if ($int < 0) {
+ $int += 256;
+ }
+
+ return \chr($int);
+ }
+}
diff --git a/vendor/symfony/polyfill-ctype/LICENSE b/vendor/symfony/polyfill-ctype/LICENSE
new file mode 100644
index 0000000..ad399a7
--- /dev/null
+++ b/vendor/symfony/polyfill-ctype/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2018 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/symfony/polyfill-ctype/README.md b/vendor/symfony/polyfill-ctype/README.md
new file mode 100644
index 0000000..8add1ab
--- /dev/null
+++ b/vendor/symfony/polyfill-ctype/README.md
@@ -0,0 +1,12 @@
+Symfony Polyfill / Ctype
+========================
+
+This component provides `ctype_*` functions to users who run php versions without the ctype extension.
+
+More information can be found in the
+[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).
+
+License
+=======
+
+This library is released under the [MIT license](LICENSE).
diff --git a/vendor/symfony/polyfill-ctype/bootstrap.php b/vendor/symfony/polyfill-ctype/bootstrap.php
new file mode 100644
index 0000000..14d1d0f
--- /dev/null
+++ b/vendor/symfony/polyfill-ctype/bootstrap.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Ctype as p;
+
+if (!function_exists('ctype_alnum')) {
+ function ctype_alnum($text) { return p\Ctype::ctype_alnum($text); }
+ function ctype_alpha($text) { return p\Ctype::ctype_alpha($text); }
+ function ctype_cntrl($text) { return p\Ctype::ctype_cntrl($text); }
+ function ctype_digit($text) { return p\Ctype::ctype_digit($text); }
+ function ctype_graph($text) { return p\Ctype::ctype_graph($text); }
+ function ctype_lower($text) { return p\Ctype::ctype_lower($text); }
+ function ctype_print($text) { return p\Ctype::ctype_print($text); }
+ function ctype_punct($text) { return p\Ctype::ctype_punct($text); }
+ function ctype_space($text) { return p\Ctype::ctype_space($text); }
+ function ctype_upper($text) { return p\Ctype::ctype_upper($text); }
+ function ctype_xdigit($text) { return p\Ctype::ctype_xdigit($text); }
+}
diff --git a/vendor/symfony/polyfill-ctype/composer.json b/vendor/symfony/polyfill-ctype/composer.json
new file mode 100644
index 0000000..094f8d8
--- /dev/null
+++ b/vendor/symfony/polyfill-ctype/composer.json
@@ -0,0 +1,34 @@
+{
+ "name": "symfony/polyfill-ctype",
+ "type": "library",
+ "description": "Symfony polyfill for ctype functions",
+ "keywords": ["polyfill", "compatibility", "portable", "ctype"],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Polyfill\\Ctype\\": "" },
+ "files": [ "bootstrap.php" ]
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.9-dev"
+ }
+ }
+}
diff --git a/vendor/symfony/yaml/.gitignore b/vendor/symfony/yaml/.gitignore
new file mode 100644
index 0000000..c49a5d8
--- /dev/null
+++ b/vendor/symfony/yaml/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/vendor/symfony/yaml/CHANGELOG.md b/vendor/symfony/yaml/CHANGELOG.md
new file mode 100644
index 0000000..70d392d
--- /dev/null
+++ b/vendor/symfony/yaml/CHANGELOG.md
@@ -0,0 +1,179 @@
+CHANGELOG
+=========
+
+4.0.0
+-----
+
+ * The behavior of the non-specific tag `!` is changed and now forces
+ non-evaluating your values.
+ * complex mappings will throw a `ParseException`
+ * support for the comma as a group separator for floats has been dropped, use
+ the underscore instead
+ * support for the `!!php/object` tag has been dropped, use the `!php/object`
+ tag instead
+ * duplicate mapping keys throw a `ParseException`
+ * non-string mapping keys throw a `ParseException`, use the `Yaml::PARSE_KEYS_AS_STRINGS`
+ flag to cast them to strings
+ * `%` at the beginning of an unquoted string throw a `ParseException`
+ * mappings with a colon (`:`) that is not followed by a whitespace throw a
+ `ParseException`
+ * the `Dumper::setIndentation()` method has been removed
+ * being able to pass boolean options to the `Yaml::parse()`, `Yaml::dump()`,
+ `Parser::parse()`, and `Dumper::dump()` methods to configure the behavior of
+ the parser and dumper is no longer supported, pass bitmask flags instead
+ * the constructor arguments of the `Parser` class have been removed
+ * the `Inline` class is internal and no longer part of the BC promise
+ * removed support for the `!str` tag, use the `!!str` tag instead
+ * added support for tagged scalars.
+
+ ```yml
+ Yaml::parse('!foo bar', Yaml::PARSE_CUSTOM_TAGS);
+ // returns TaggedValue('foo', 'bar');
+ ```
+
+3.4.0
+-----
+
+ * added support for parsing YAML files using the `Yaml::parseFile()` or `Parser::parseFile()` method
+
+ * the `Dumper`, `Parser`, and `Yaml` classes are marked as final
+
+ * Deprecated the `!php/object:` tag which will be replaced by the
+ `!php/object` tag (without the colon) in 4.0.
+
+ * Deprecated the `!php/const:` tag which will be replaced by the
+ `!php/const` tag (without the colon) in 4.0.
+
+ * Support for the `!str` tag is deprecated, use the `!!str` tag instead.
+
+ * Deprecated using the non-specific tag `!` as its behavior will change in 4.0.
+ It will force non-evaluating your values in 4.0. Use plain integers or `!!float` instead.
+
+3.3.0
+-----
+
+ * Starting an unquoted string with a question mark followed by a space is
+ deprecated and will throw a `ParseException` in Symfony 4.0.
+
+ * Deprecated support for implicitly parsing non-string mapping keys as strings.
+ Mapping keys that are no strings will lead to a `ParseException` in Symfony
+ 4.0. Use quotes to opt-in for keys to be parsed as strings.
+
+ Before:
+
+ ```php
+ $yaml = <<<YAML
+ null: null key
+ true: boolean true
+ 2.0: float key
+ YAML;
+
+ Yaml::parse($yaml);
+ ```
+
+ After:
+
+ ```php
+
+ $yaml = <<<YAML
+ "null": null key
+ "true": boolean true
+ "2.0": float key
+ YAML;
+
+ Yaml::parse($yaml);
+ ```
+
+ * Omitted mapping values will be parsed as `null`.
+
+ * Omitting the key of a mapping is deprecated and will throw a `ParseException` in Symfony 4.0.
+
+ * Added support for dumping empty PHP arrays as YAML sequences:
+
+ ```php
+ Yaml::dump([], 0, 0, Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE);
+ ```
+
+3.2.0
+-----
+
+ * Mappings with a colon (`:`) that is not followed by a whitespace are deprecated
+ when the mapping key is not quoted and will lead to a `ParseException` in
+ Symfony 4.0 (e.g. `foo:bar` must be `foo: bar`).
+
+ * Added support for parsing PHP constants:
+
+ ```php
+ Yaml::parse('!php/const:PHP_INT_MAX', Yaml::PARSE_CONSTANT);
+ ```
+
+ * Support for silently ignoring duplicate mapping keys in YAML has been
+ deprecated and will lead to a `ParseException` in Symfony 4.0.
+
+3.1.0
+-----
+
+ * Added support to dump `stdClass` and `ArrayAccess` objects as YAML mappings
+ through the `Yaml::DUMP_OBJECT_AS_MAP` flag.
+
+ * Strings that are not UTF-8 encoded will be dumped as base64 encoded binary
+ data.
+
+ * Added support for dumping multi line strings as literal blocks.
+
+ * Added support for parsing base64 encoded binary data when they are tagged
+ with the `!!binary` tag.
+
+ * Added support for parsing timestamps as `\DateTime` objects:
+
+ ```php
+ Yaml::parse('2001-12-15 21:59:43.10 -5', Yaml::PARSE_DATETIME);
+ ```
+
+ * `\DateTime` and `\DateTimeImmutable` objects are dumped as YAML timestamps.
+
+ * Deprecated usage of `%` at the beginning of an unquoted string.
+
+ * Added support for customizing the YAML parser behavior through an optional bit field:
+
+ ```php
+ Yaml::parse('{ "foo": "bar", "fiz": "cat" }', Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE | Yaml::PARSE_OBJECT | Yaml::PARSE_OBJECT_FOR_MAP);
+ ```
+
+ * Added support for customizing the dumped YAML string through an optional bit field:
+
+ ```php
+ Yaml::dump(array('foo' => new A(), 'bar' => 1), 0, 0, Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE | Yaml::DUMP_OBJECT);
+ ```
+
+3.0.0
+-----
+
+ * Yaml::parse() now throws an exception when a blackslash is not escaped
+ in double-quoted strings
+
+2.8.0
+-----
+
+ * Deprecated usage of a colon in an unquoted mapping value
+ * Deprecated usage of @, \`, | and > at the beginning of an unquoted string
+ * When surrounding strings with double-quotes, you must now escape `\` characters. Not
+ escaping those characters (when surrounded by double-quotes) is deprecated.
+
+ Before:
+
+ ```yml
+ class: "Foo\Var"
+ ```
+
+ After:
+
+ ```yml
+ class: "Foo\\Var"
+ ```
+
+2.1.0
+-----
+
+ * Yaml::parse() does not evaluate loaded files as PHP files by default
+ anymore (call Yaml::enablePhpParsing() to get back the old behavior)
diff --git a/vendor/symfony/yaml/Command/LintCommand.php b/vendor/symfony/yaml/Command/LintCommand.php
new file mode 100644
index 0000000..56bc96f
--- /dev/null
+++ b/vendor/symfony/yaml/Command/LintCommand.php
@@ -0,0 +1,250 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Command;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\RuntimeException;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use Symfony\Component\Yaml\Exception\ParseException;
+use Symfony\Component\Yaml\Parser;
+use Symfony\Component\Yaml\Yaml;
+
+/**
+ * Validates YAML files syntax and outputs encountered errors.
+ *
+ * @author Grégoire Pineau <lyrixx@lyrixx.info>
+ * @author Robin Chalas <robin.chalas@gmail.com>
+ */
+class LintCommand extends Command
+{
+ protected static $defaultName = 'lint:yaml';
+
+ private $parser;
+ private $format;
+ private $displayCorrectFiles;
+ private $directoryIteratorProvider;
+ private $isReadableProvider;
+
+ public function __construct(string $name = null, callable $directoryIteratorProvider = null, callable $isReadableProvider = null)
+ {
+ parent::__construct($name);
+
+ $this->directoryIteratorProvider = $directoryIteratorProvider;
+ $this->isReadableProvider = $isReadableProvider;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function configure()
+ {
+ $this
+ ->setDescription('Lints a file and outputs encountered errors')
+ ->addArgument('filename', null, 'A file or a directory or STDIN')
+ ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt')
+ ->addOption('parse-tags', null, InputOption::VALUE_NONE, 'Parse custom tags')
+ ->setHelp(<<<EOF
+The <info>%command.name%</info> command lints a YAML file and outputs to STDOUT
+the first encountered syntax error.
+
+You can validates YAML contents passed from STDIN:
+
+ <info>cat filename | php %command.full_name%</info>
+
+You can also validate the syntax of a file:
+
+ <info>php %command.full_name% filename</info>
+
+Or of a whole directory:
+
+ <info>php %command.full_name% dirname</info>
+ <info>php %command.full_name% dirname --format=json</info>
+
+EOF
+ )
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $io = new SymfonyStyle($input, $output);
+ $filename = $input->getArgument('filename');
+ $this->format = $input->getOption('format');
+ $this->displayCorrectFiles = $output->isVerbose();
+ $flags = $input->getOption('parse-tags') ? Yaml::PARSE_CUSTOM_TAGS : 0;
+
+ if (!$filename) {
+ if (!$stdin = $this->getStdin()) {
+ throw new RuntimeException('Please provide a filename or pipe file content to STDIN.');
+ }
+
+ return $this->display($io, array($this->validate($stdin, $flags)));
+ }
+
+ if (!$this->isReadable($filename)) {
+ throw new RuntimeException(sprintf('File or directory "%s" is not readable.', $filename));
+ }
+
+ $filesInfo = array();
+ foreach ($this->getFiles($filename) as $file) {
+ $filesInfo[] = $this->validate(file_get_contents($file), $flags, $file);
+ }
+
+ return $this->display($io, $filesInfo);
+ }
+
+ private function validate($content, $flags, $file = null)
+ {
+ $prevErrorHandler = set_error_handler(function ($level, $message, $file, $line) use (&$prevErrorHandler) {
+ if (E_USER_DEPRECATED === $level) {
+ throw new ParseException($message, $this->getParser()->getRealCurrentLineNb() + 1);
+ }
+
+ return $prevErrorHandler ? $prevErrorHandler($level, $message, $file, $line) : false;
+ });
+
+ try {
+ $this->getParser()->parse($content, Yaml::PARSE_CONSTANT | $flags);
+ } catch (ParseException $e) {
+ return array('file' => $file, 'line' => $e->getParsedLine(), 'valid' => false, 'message' => $e->getMessage());
+ } finally {
+ restore_error_handler();
+ }
+
+ return array('file' => $file, 'valid' => true);
+ }
+
+ private function display(SymfonyStyle $io, array $files)
+ {
+ switch ($this->format) {
+ case 'txt':
+ return $this->displayTxt($io, $files);
+ case 'json':
+ return $this->displayJson($io, $files);
+ default:
+ throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format));
+ }
+ }
+
+ private function displayTxt(SymfonyStyle $io, array $filesInfo)
+ {
+ $countFiles = \count($filesInfo);
+ $erroredFiles = 0;
+
+ foreach ($filesInfo as $info) {
+ if ($info['valid'] && $this->displayCorrectFiles) {
+ $io->comment('<info>OK</info>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
+ } elseif (!$info['valid']) {
+ ++$erroredFiles;
+ $io->text('<error> ERROR </error>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
+ $io->text(sprintf('<error> >> %s</error>', $info['message']));
+ }
+ }
+
+ if (0 === $erroredFiles) {
+ $io->success(sprintf('All %d YAML files contain valid syntax.', $countFiles));
+ } else {
+ $io->warning(sprintf('%d YAML files have valid syntax and %d contain errors.', $countFiles - $erroredFiles, $erroredFiles));
+ }
+
+ return min($erroredFiles, 1);
+ }
+
+ private function displayJson(SymfonyStyle $io, array $filesInfo)
+ {
+ $errors = 0;
+
+ array_walk($filesInfo, function (&$v) use (&$errors) {
+ $v['file'] = (string) $v['file'];
+ if (!$v['valid']) {
+ ++$errors;
+ }
+ });
+
+ $io->writeln(json_encode($filesInfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
+
+ return min($errors, 1);
+ }
+
+ private function getFiles($fileOrDirectory)
+ {
+ if (is_file($fileOrDirectory)) {
+ yield new \SplFileInfo($fileOrDirectory);
+
+ return;
+ }
+
+ foreach ($this->getDirectoryIterator($fileOrDirectory) as $file) {
+ if (!\in_array($file->getExtension(), array('yml', 'yaml'))) {
+ continue;
+ }
+
+ yield $file;
+ }
+ }
+
+ private function getStdin()
+ {
+ if (0 !== ftell(STDIN)) {
+ return;
+ }
+
+ $inputs = '';
+ while (!feof(STDIN)) {
+ $inputs .= fread(STDIN, 1024);
+ }
+
+ return $inputs;
+ }
+
+ private function getParser()
+ {
+ if (!$this->parser) {
+ $this->parser = new Parser();
+ }
+
+ return $this->parser;
+ }
+
+ private function getDirectoryIterator($directory)
+ {
+ $default = function ($directory) {
+ return new \RecursiveIteratorIterator(
+ new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
+ \RecursiveIteratorIterator::LEAVES_ONLY
+ );
+ };
+
+ if (null !== $this->directoryIteratorProvider) {
+ return \call_user_func($this->directoryIteratorProvider, $directory, $default);
+ }
+
+ return $default($directory);
+ }
+
+ private function isReadable($fileOrDirectory)
+ {
+ $default = function ($fileOrDirectory) {
+ return is_readable($fileOrDirectory);
+ };
+
+ if (null !== $this->isReadableProvider) {
+ return \call_user_func($this->isReadableProvider, $fileOrDirectory, $default);
+ }
+
+ return $default($fileOrDirectory);
+ }
+}
diff --git a/vendor/symfony/yaml/Dumper.php b/vendor/symfony/yaml/Dumper.php
new file mode 100644
index 0000000..fdd34b6
--- /dev/null
+++ b/vendor/symfony/yaml/Dumper.php
@@ -0,0 +1,97 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+/**
+ * Dumper dumps PHP variables to YAML strings.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @final
+ */
+class Dumper
+{
+ /**
+ * The amount of spaces to use for indentation of nested nodes.
+ *
+ * @var int
+ */
+ protected $indentation;
+
+ public function __construct(int $indentation = 4)
+ {
+ if ($indentation < 1) {
+ throw new \InvalidArgumentException('The indentation must be greater than zero.');
+ }
+
+ $this->indentation = $indentation;
+ }
+
+ /**
+ * Dumps a PHP value to YAML.
+ *
+ * @param mixed $input The PHP value
+ * @param int $inline The level where you switch to inline YAML
+ * @param int $indent The level of indentation (used internally)
+ * @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string
+ *
+ * @return string The YAML representation of the PHP value
+ */
+ public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): string
+ {
+ $output = '';
+ $prefix = $indent ? str_repeat(' ', $indent) : '';
+ $dumpObjectAsInlineMap = true;
+
+ if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($input instanceof \ArrayObject || $input instanceof \stdClass)) {
+ $dumpObjectAsInlineMap = empty((array) $input);
+ }
+
+ if ($inline <= 0 || (!\is_array($input) && $dumpObjectAsInlineMap) || empty($input)) {
+ $output .= $prefix.Inline::dump($input, $flags);
+ } else {
+ $dumpAsMap = Inline::isHash($input);
+
+ foreach ($input as $key => $value) {
+ if ($inline >= 1 && Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value) && false !== strpos($value, "\n") && false === strpos($value, "\r\n")) {
+ // If the first line starts with a space character, the spec requires a blockIndicationIndicator
+ // http://www.yaml.org/spec/1.2/spec.html#id2793979
+ $blockIndentationIndicator = (' ' === substr($value, 0, 1)) ? (string) $this->indentation : '';
+ $output .= sprintf("%s%s%s |%s\n", $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', '', $blockIndentationIndicator);
+
+ foreach (preg_split('/\n|\r\n/', $value) as $row) {
+ $output .= sprintf("%s%s%s\n", $prefix, str_repeat(' ', $this->indentation), $row);
+ }
+
+ continue;
+ }
+
+ $dumpObjectAsInlineMap = true;
+
+ if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \ArrayObject || $value instanceof \stdClass)) {
+ $dumpObjectAsInlineMap = empty((array) $value);
+ }
+
+ $willBeInlined = $inline - 1 <= 0 || !\is_array($value) && $dumpObjectAsInlineMap || empty($value);
+
+ $output .= sprintf('%s%s%s%s',
+ $prefix,
+ $dumpAsMap ? Inline::dump($key, $flags).':' : '-',
+ $willBeInlined ? ' ' : "\n",
+ $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $flags)
+ ).($willBeInlined ? "\n" : '');
+ }
+ }
+
+ return $output;
+ }
+}
diff --git a/vendor/symfony/yaml/Escaper.php b/vendor/symfony/yaml/Escaper.php
new file mode 100644
index 0000000..4b2559e
--- /dev/null
+++ b/vendor/symfony/yaml/Escaper.php
@@ -0,0 +1,101 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+/**
+ * Escaper encapsulates escaping rules for single and double-quoted
+ * YAML strings.
+ *
+ * @author Matthew Lewinski <matthew@lewinski.org>
+ *
+ * @internal
+ */
+class Escaper
+{
+ // Characters that would cause a dumped string to require double quoting.
+ const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9";
+
+ // Mapping arrays for escaping a double quoted string. The backslash is
+ // first to ensure proper escaping because str_replace operates iteratively
+ // on the input arrays. This ordering of the characters avoids the use of strtr,
+ // which performs more slowly.
+ private static $escapees = array('\\', '\\\\', '\\"', '"',
+ "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07",
+ "\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f",
+ "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17",
+ "\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f",
+ "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9",
+ );
+ private static $escaped = array('\\\\', '\\"', '\\\\', '\\"',
+ '\\0', '\\x01', '\\x02', '\\x03', '\\x04', '\\x05', '\\x06', '\\a',
+ '\\b', '\\t', '\\n', '\\v', '\\f', '\\r', '\\x0e', '\\x0f',
+ '\\x10', '\\x11', '\\x12', '\\x13', '\\x14', '\\x15', '\\x16', '\\x17',
+ '\\x18', '\\x19', '\\x1a', '\\e', '\\x1c', '\\x1d', '\\x1e', '\\x1f',
+ '\\N', '\\_', '\\L', '\\P',
+ );
+
+ /**
+ * Determines if a PHP value would require double quoting in YAML.
+ *
+ * @param string $value A PHP value
+ *
+ * @return bool True if the value would require double quotes
+ */
+ public static function requiresDoubleQuoting(string $value): bool
+ {
+ return 0 < preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value);
+ }
+
+ /**
+ * Escapes and surrounds a PHP value with double quotes.
+ *
+ * @param string $value A PHP value
+ *
+ * @return string The quoted, escaped string
+ */
+ public static function escapeWithDoubleQuotes(string $value): string
+ {
+ return sprintf('"%s"', str_replace(self::$escapees, self::$escaped, $value));
+ }
+
+ /**
+ * Determines if a PHP value would require single quoting in YAML.
+ *
+ * @param string $value A PHP value
+ *
+ * @return bool True if the value would require single quotes
+ */
+ public static function requiresSingleQuoting(string $value): bool
+ {
+ // Determines if a PHP value is entirely composed of a value that would
+ // require single quoting in YAML.
+ if (\in_array(strtolower($value), array('null', '~', 'true', 'false', 'y', 'n', 'yes', 'no', 'on', 'off'))) {
+ return true;
+ }
+
+ // Determines if the PHP value contains any single characters that would
+ // cause it to require single quoting in YAML.
+ return 0 < preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value);
+ }
+
+ /**
+ * Escapes and surrounds a PHP value with single quotes.
+ *
+ * @param string $value A PHP value
+ *
+ * @return string The quoted, escaped string
+ */
+ public static function escapeWithSingleQuotes(string $value): string
+ {
+ return sprintf("'%s'", str_replace('\'', '\'\'', $value));
+ }
+}
diff --git a/vendor/symfony/yaml/Exception/DumpException.php b/vendor/symfony/yaml/Exception/DumpException.php
new file mode 100644
index 0000000..cce972f
--- /dev/null
+++ b/vendor/symfony/yaml/Exception/DumpException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Exception;
+
+/**
+ * Exception class thrown when an error occurs during dumping.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class DumpException extends RuntimeException
+{
+}
diff --git a/vendor/symfony/yaml/Exception/ExceptionInterface.php b/vendor/symfony/yaml/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..ad850ee
--- /dev/null
+++ b/vendor/symfony/yaml/Exception/ExceptionInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Exception;
+
+/**
+ * Exception interface for all exceptions thrown by the component.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface ExceptionInterface
+{
+}
diff --git a/vendor/symfony/yaml/Exception/ParseException.php b/vendor/symfony/yaml/Exception/ParseException.php
new file mode 100644
index 0000000..95efe68
--- /dev/null
+++ b/vendor/symfony/yaml/Exception/ParseException.php
@@ -0,0 +1,139 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Exception;
+
+/**
+ * Exception class thrown when an error occurs during parsing.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ParseException extends RuntimeException
+{
+ private $parsedFile;
+ private $parsedLine;
+ private $snippet;
+ private $rawMessage;
+
+ /**
+ * @param string $message The error message
+ * @param int $parsedLine The line where the error occurred
+ * @param string|null $snippet The snippet of code near the problem
+ * @param string|null $parsedFile The file name where the error occurred
+ * @param \Exception|null $previous The previous exception
+ */
+ public function __construct(string $message, int $parsedLine = -1, string $snippet = null, string $parsedFile = null, \Exception $previous = null)
+ {
+ $this->parsedFile = $parsedFile;
+ $this->parsedLine = $parsedLine;
+ $this->snippet = $snippet;
+ $this->rawMessage = $message;
+
+ $this->updateRepr();
+
+ parent::__construct($this->message, 0, $previous);
+ }
+
+ /**
+ * Gets the snippet of code near the error.
+ *
+ * @return string The snippet of code
+ */
+ public function getSnippet()
+ {
+ return $this->snippet;
+ }
+
+ /**
+ * Sets the snippet of code near the error.
+ *
+ * @param string $snippet The code snippet
+ */
+ public function setSnippet($snippet)
+ {
+ $this->snippet = $snippet;
+
+ $this->updateRepr();
+ }
+
+ /**
+ * Gets the filename where the error occurred.
+ *
+ * This method returns null if a string is parsed.
+ *
+ * @return string The filename
+ */
+ public function getParsedFile()
+ {
+ return $this->parsedFile;
+ }
+
+ /**
+ * Sets the filename where the error occurred.
+ *
+ * @param string $parsedFile The filename
+ */
+ public function setParsedFile($parsedFile)
+ {
+ $this->parsedFile = $parsedFile;
+
+ $this->updateRepr();
+ }
+
+ /**
+ * Gets the line where the error occurred.
+ *
+ * @return int The file line
+ */
+ public function getParsedLine()
+ {
+ return $this->parsedLine;
+ }
+
+ /**
+ * Sets the line where the error occurred.
+ *
+ * @param int $parsedLine The file line
+ */
+ public function setParsedLine($parsedLine)
+ {
+ $this->parsedLine = $parsedLine;
+
+ $this->updateRepr();
+ }
+
+ private function updateRepr()
+ {
+ $this->message = $this->rawMessage;
+
+ $dot = false;
+ if ('.' === substr($this->message, -1)) {
+ $this->message = substr($this->message, 0, -1);
+ $dot = true;
+ }
+
+ if (null !== $this->parsedFile) {
+ $this->message .= sprintf(' in %s', json_encode($this->parsedFile, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
+ }
+
+ if ($this->parsedLine >= 0) {
+ $this->message .= sprintf(' at line %d', $this->parsedLine);
+ }
+
+ if ($this->snippet) {
+ $this->message .= sprintf(' (near "%s")', $this->snippet);
+ }
+
+ if ($dot) {
+ $this->message .= '.';
+ }
+ }
+}
diff --git a/vendor/symfony/yaml/Exception/RuntimeException.php b/vendor/symfony/yaml/Exception/RuntimeException.php
new file mode 100644
index 0000000..3f36b73
--- /dev/null
+++ b/vendor/symfony/yaml/Exception/RuntimeException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Exception;
+
+/**
+ * Exception class thrown when an error occurs during parsing.
+ *
+ * @author Romain Neutron <imprec@gmail.com>
+ */
+class RuntimeException extends \RuntimeException implements ExceptionInterface
+{
+}
diff --git a/vendor/symfony/yaml/Inline.php b/vendor/symfony/yaml/Inline.php
new file mode 100644
index 0000000..261d618
--- /dev/null
+++ b/vendor/symfony/yaml/Inline.php
@@ -0,0 +1,744 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+use Symfony\Component\Yaml\Exception\DumpException;
+use Symfony\Component\Yaml\Exception\ParseException;
+use Symfony\Component\Yaml\Tag\TaggedValue;
+
+/**
+ * Inline implements a YAML parser/dumper for the YAML inline syntax.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @internal
+ */
+class Inline
+{
+ const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+)"|\'([^\']*+(?:\'\'[^\']*+)*+)\')';
+
+ public static $parsedLineNumber = -1;
+ public static $parsedFilename;
+
+ private static $exceptionOnInvalidType = false;
+ private static $objectSupport = false;
+ private static $objectForMap = false;
+ private static $constantSupport = false;
+
+ /**
+ * @param int $flags
+ * @param int|null $parsedLineNumber
+ * @param string|null $parsedFilename
+ */
+ public static function initialize($flags, $parsedLineNumber = null, $parsedFilename = null)
+ {
+ self::$exceptionOnInvalidType = (bool) (Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE & $flags);
+ self::$objectSupport = (bool) (Yaml::PARSE_OBJECT & $flags);
+ self::$objectForMap = (bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags);
+ self::$constantSupport = (bool) (Yaml::PARSE_CONSTANT & $flags);
+ self::$parsedFilename = $parsedFilename;
+
+ if (null !== $parsedLineNumber) {
+ self::$parsedLineNumber = $parsedLineNumber;
+ }
+ }
+
+ /**
+ * Converts a YAML string to a PHP value.
+ *
+ * @param string $value A YAML string
+ * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior
+ * @param array $references Mapping of variable names to values
+ *
+ * @return mixed A PHP value
+ *
+ * @throws ParseException
+ */
+ public static function parse(string $value = null, int $flags = 0, array $references = array())
+ {
+ self::initialize($flags);
+
+ $value = trim($value);
+
+ if ('' === $value) {
+ return '';
+ }
+
+ if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) {
+ $mbEncoding = mb_internal_encoding();
+ mb_internal_encoding('ASCII');
+ }
+
+ $i = 0;
+ $tag = self::parseTag($value, $i, $flags);
+ switch ($value[$i]) {
+ case '[':
+ $result = self::parseSequence($value, $flags, $i, $references);
+ ++$i;
+ break;
+ case '{':
+ $result = self::parseMapping($value, $flags, $i, $references);
+ ++$i;
+ break;
+ default:
+ $result = self::parseScalar($value, $flags, null, $i, null === $tag, $references);
+ }
+
+ if (null !== $tag && '' !== $tag) {
+ return new TaggedValue($tag, $result);
+ }
+
+ // some comments are allowed at the end
+ if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) {
+ throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
+ }
+
+ if (isset($mbEncoding)) {
+ mb_internal_encoding($mbEncoding);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Dumps a given PHP variable to a YAML string.
+ *
+ * @param mixed $value The PHP variable to convert
+ * @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string
+ *
+ * @return string The YAML string representing the PHP value
+ *
+ * @throws DumpException When trying to dump PHP resource
+ */
+ public static function dump($value, int $flags = 0): string
+ {
+ switch (true) {
+ case \is_resource($value):
+ if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) {
+ throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value)));
+ }
+
+ return 'null';
+ case $value instanceof \DateTimeInterface:
+ return $value->format('c');
+ case \is_object($value):
+ if ($value instanceof TaggedValue) {
+ return '!'.$value->getTag().' '.self::dump($value->getValue(), $flags);
+ }
+
+ if (Yaml::DUMP_OBJECT & $flags) {
+ return '!php/object '.self::dump(serialize($value));
+ }
+
+ if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \stdClass || $value instanceof \ArrayObject)) {
+ $output = array();
+
+ foreach ($value as $key => $val) {
+ $output[] = sprintf('%s: %s', self::dump($key, $flags), self::dump($val, $flags));
+ }
+
+ return sprintf('{ %s }', implode(', ', $output));
+ }
+
+ if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) {
+ throw new DumpException('Object support when dumping a YAML file has been disabled.');
+ }
+
+ return 'null';
+ case \is_array($value):
+ return self::dumpArray($value, $flags);
+ case null === $value:
+ return 'null';
+ case true === $value:
+ return 'true';
+ case false === $value:
+ return 'false';
+ case ctype_digit($value):
+ return \is_string($value) ? "'$value'" : (int) $value;
+ case is_numeric($value):
+ $locale = setlocale(LC_NUMERIC, 0);
+ if (false !== $locale) {
+ setlocale(LC_NUMERIC, 'C');
+ }
+ if (\is_float($value)) {
+ $repr = (string) $value;
+ if (is_infinite($value)) {
+ $repr = str_ireplace('INF', '.Inf', $repr);
+ } elseif (floor($value) == $value && $repr == $value) {
+ // Preserve float data type since storing a whole number will result in integer value.
+ $repr = '!!float '.$repr;
+ }
+ } else {
+ $repr = \is_string($value) ? "'$value'" : (string) $value;
+ }
+ if (false !== $locale) {
+ setlocale(LC_NUMERIC, $locale);
+ }
+
+ return $repr;
+ case '' == $value:
+ return "''";
+ case self::isBinaryString($value):
+ return '!!binary '.base64_encode($value);
+ case Escaper::requiresDoubleQuoting($value):
+ return Escaper::escapeWithDoubleQuotes($value);
+ case Escaper::requiresSingleQuoting($value):
+ case Parser::preg_match('{^[0-9]+[_0-9]*$}', $value):
+ case Parser::preg_match(self::getHexRegex(), $value):
+ case Parser::preg_match(self::getTimestampRegex(), $value):
+ return Escaper::escapeWithSingleQuotes($value);
+ default:
+ return $value;
+ }
+ }
+
+ /**
+ * Check if given array is hash or just normal indexed array.
+ *
+ * @param array|\ArrayObject|\stdClass $value The PHP array or array-like object to check
+ *
+ * @return bool true if value is hash array, false otherwise
+ */
+ public static function isHash($value): bool
+ {
+ if ($value instanceof \stdClass || $value instanceof \ArrayObject) {
+ return true;
+ }
+
+ $expectedKey = 0;
+
+ foreach ($value as $key => $val) {
+ if ($key !== $expectedKey++) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Dumps a PHP array to a YAML string.
+ *
+ * @param array $value The PHP array to dump
+ * @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string
+ *
+ * @return string The YAML string representing the PHP array
+ */
+ private static function dumpArray(array $value, int $flags): string
+ {
+ // array
+ if (($value || Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE & $flags) && !self::isHash($value)) {
+ $output = array();
+ foreach ($value as $val) {
+ $output[] = self::dump($val, $flags);
+ }
+
+ return sprintf('[%s]', implode(', ', $output));
+ }
+
+ // hash
+ $output = array();
+ foreach ($value as $key => $val) {
+ $output[] = sprintf('%s: %s', self::dump($key, $flags), self::dump($val, $flags));
+ }
+
+ return sprintf('{ %s }', implode(', ', $output));
+ }
+
+ /**
+ * Parses a YAML scalar.
+ *
+ * @return mixed
+ *
+ * @throws ParseException When malformed inline YAML string is parsed
+ */
+ public static function parseScalar(string $scalar, int $flags = 0, array $delimiters = null, int &$i = 0, bool $evaluate = true, array $references = array())
+ {
+ if (\in_array($scalar[$i], array('"', "'"))) {
+ // quoted scalar
+ $output = self::parseQuotedScalar($scalar, $i);
+
+ if (null !== $delimiters) {
+ $tmp = ltrim(substr($scalar, $i), ' ');
+ if ('' === $tmp) {
+ throw new ParseException(sprintf('Unexpected end of line, expected one of "%s".', implode($delimiters)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
+ }
+ if (!\in_array($tmp[0], $delimiters)) {
+ throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
+ }
+ }
+ } else {
+ // "normal" string
+ if (!$delimiters) {
+ $output = substr($scalar, $i);
+ $i += \strlen($output);
+
+ // remove comments
+ if (Parser::preg_match('/[ \t]+#/', $output, $match, PREG_OFFSET_CAPTURE)) {
+ $output = substr($output, 0, $match[0][1]);
+ }
+ } elseif (Parser::preg_match('/^(.*?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) {
+ $output = $match[1];
+ $i += \strlen($output);
+ $output = trim($output);
+ } else {
+ throw new ParseException(sprintf('Malformed inline YAML string: %s.', $scalar), self::$parsedLineNumber + 1, null, self::$parsedFilename);
+ }
+
+ // a non-quoted string cannot start with @ or ` (reserved) nor with a scalar indicator (| or >)
+ if ($output && ('@' === $output[0] || '`' === $output[0] || '|' === $output[0] || '>' === $output[0] || '%' === $output[0])) {
+ throw new ParseException(sprintf('The reserved indicator "%s" cannot start a plain scalar; you need to quote the scalar.', $output[0]), self::$parsedLineNumber + 1, $output, self::$parsedFilename);
+ }
+
+ if ($evaluate) {
+ $output = self::evaluateScalar($output, $flags, $references);
+ }
+ }
+
+ return $output;
+ }
+
+ /**
+ * Parses a YAML quoted scalar.
+ *
+ * @throws ParseException When malformed inline YAML string is parsed
+ */
+ private static function parseQuotedScalar(string $scalar, int &$i): string
+ {
+ if (!Parser::preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) {
+ throw new ParseException(sprintf('Malformed inline YAML string: %s.', substr($scalar, $i)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
+ }
+
+ $output = substr($match[0], 1, \strlen($match[0]) - 2);
+
+ $unescaper = new Unescaper();
+ if ('"' == $scalar[$i]) {
+ $output = $unescaper->unescapeDoubleQuotedString($output);
+ } else {
+ $output = $unescaper->unescapeSingleQuotedString($output);
+ }
+
+ $i += \strlen($match[0]);
+
+ return $output;
+ }
+
+ /**
+ * Parses a YAML sequence.
+ *
+ * @throws ParseException When malformed inline YAML string is parsed
+ */
+ private static function parseSequence(string $sequence, int $flags, int &$i = 0, array $references = array()): array
+ {
+ $output = array();
+ $len = \strlen($sequence);
+ ++$i;
+
+ // [foo, bar, ...]
+ while ($i < $len) {
+ if (']' === $sequence[$i]) {
+ return $output;
+ }
+ if (',' === $sequence[$i] || ' ' === $sequence[$i]) {
+ ++$i;
+
+ continue;
+ }
+
+ $tag = self::parseTag($sequence, $i, $flags);
+ switch ($sequence[$i]) {
+ case '[':
+ // nested sequence
+ $value = self::parseSequence($sequence, $flags, $i, $references);
+ break;
+ case '{':
+ // nested mapping
+ $value = self::parseMapping($sequence, $flags, $i, $references);
+ break;
+ default:
+ $isQuoted = \in_array($sequence[$i], array('"', "'"));
+ $value = self::parseScalar($sequence, $flags, array(',', ']'), $i, null === $tag, $references);
+
+ // the value can be an array if a reference has been resolved to an array var
+ if (\is_string($value) && !$isQuoted && false !== strpos($value, ': ')) {
+ // embedded mapping?
+ try {
+ $pos = 0;
+ $value = self::parseMapping('{'.$value.'}', $flags, $pos, $references);
+ } catch (\InvalidArgumentException $e) {
+ // no, it's not
+ }
+ }
+
+ --$i;
+ }
+
+ if (null !== $tag && '' !== $tag) {
+ $value = new TaggedValue($tag, $value);
+ }
+
+ $output[] = $value;
+
+ ++$i;
+ }
+
+ throw new ParseException(sprintf('Malformed inline YAML string: %s.', $sequence), self::$parsedLineNumber + 1, null, self::$parsedFilename);
+ }
+
+ /**
+ * Parses a YAML mapping.
+ *
+ * @return array|\stdClass
+ *
+ * @throws ParseException When malformed inline YAML string is parsed
+ */
+ private static function parseMapping(string $mapping, int $flags, int &$i = 0, array $references = array())
+ {
+ $output = array();
+ $len = \strlen($mapping);
+ ++$i;
+ $allowOverwrite = false;
+
+ // {foo: bar, bar:foo, ...}
+ while ($i < $len) {
+ switch ($mapping[$i]) {
+ case ' ':
+ case ',':
+ ++$i;
+ continue 2;
+ case '}':
+ if (self::$objectForMap) {
+ return (object) $output;
+ }
+
+ return $output;
+ }
+
+ // key
+ $offsetBeforeKeyParsing = $i;
+ $isKeyQuoted = \in_array($mapping[$i], array('"', "'"), true);
+ $key = self::parseScalar($mapping, $flags, array(':', ' '), $i, false, array());
+
+ if ($offsetBeforeKeyParsing === $i) {
+ throw new ParseException('Missing mapping key.', self::$parsedLineNumber + 1, $mapping);
+ }
+
+ if (false === $i = strpos($mapping, ':', $i)) {
+ break;
+ }
+
+ if (!$isKeyQuoted) {
+ $evaluatedKey = self::evaluateScalar($key, $flags, $references);
+
+ if ('' !== $key && $evaluatedKey !== $key && !\is_string($evaluatedKey) && !\is_int($evaluatedKey)) {
+ throw new ParseException('Implicit casting of incompatible mapping keys to strings is not supported. Quote your evaluable mapping keys instead.', self::$parsedLineNumber + 1, $mapping);
+ }
+ }
+
+ if (!$isKeyQuoted && (!isset($mapping[$i + 1]) || !\in_array($mapping[$i + 1], array(' ', ',', '[', ']', '{', '}'), true))) {
+ throw new ParseException('Colons must be followed by a space or an indication character (i.e. " ", ",", "[", "]", "{", "}").', self::$parsedLineNumber + 1, $mapping);
+ }
+
+ if ('<<' === $key) {
+ $allowOverwrite = true;
+ }
+
+ while ($i < $len) {
+ if (':' === $mapping[$i] || ' ' === $mapping[$i]) {
+ ++$i;
+
+ continue;
+ }
+
+ $tag = self::parseTag($mapping, $i, $flags);
+ switch ($mapping[$i]) {
+ case '[':
+ // nested sequence
+ $value = self::parseSequence($mapping, $flags, $i, $references);
+ // Spec: Keys MUST be unique; first one wins.
+ // Parser cannot abort this mapping earlier, since lines
+ // are processed sequentially.
+ // But overwriting is allowed when a merge node is used in current block.
+ if ('<<' === $key) {
+ foreach ($value as $parsedValue) {
+ $output += $parsedValue;
+ }
+ } elseif ($allowOverwrite || !isset($output[$key])) {
+ if (null !== $tag) {
+ $output[$key] = new TaggedValue($tag, $value);
+ } else {
+ $output[$key] = $value;
+ }
+ } elseif (isset($output[$key])) {
+ throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), self::$parsedLineNumber + 1, $mapping);
+ }
+ break;
+ case '{':
+ // nested mapping
+ $value = self::parseMapping($mapping, $flags, $i, $references);
+ // Spec: Keys MUST be unique; first one wins.
+ // Parser cannot abort this mapping earlier, since lines
+ // are processed sequentially.
+ // But overwriting is allowed when a merge node is used in current block.
+ if ('<<' === $key) {
+ $output += $value;
+ } elseif ($allowOverwrite || !isset($output[$key])) {
+ if (null !== $tag) {
+ $output[$key] = new TaggedValue($tag, $value);
+ } else {
+ $output[$key] = $value;
+ }
+ } elseif (isset($output[$key])) {
+ throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), self::$parsedLineNumber + 1, $mapping);
+ }
+ break;
+ default:
+ $value = self::parseScalar($mapping, $flags, array(',', '}'), $i, null === $tag, $references);
+ // Spec: Keys MUST be unique; first one wins.
+ // Parser cannot abort this mapping earlier, since lines
+ // are processed sequentially.
+ // But overwriting is allowed when a merge node is used in current block.
+ if ('<<' === $key) {
+ $output += $value;
+ } elseif ($allowOverwrite || !isset($output[$key])) {
+ if (null !== $tag) {
+ $output[$key] = new TaggedValue($tag, $value);
+ } else {
+ $output[$key] = $value;
+ }
+ } elseif (isset($output[$key])) {
+ throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), self::$parsedLineNumber + 1, $mapping);
+ }
+ --$i;
+ }
+ ++$i;
+
+ continue 2;
+ }
+ }
+
+ throw new ParseException(sprintf('Malformed inline YAML string: %s.', $mapping), self::$parsedLineNumber + 1, null, self::$parsedFilename);
+ }
+
+ /**
+ * Evaluates scalars and replaces magic values.
+ *
+ * @return mixed The evaluated YAML string
+ *
+ * @throws ParseException when object parsing support was disabled and the parser detected a PHP object or when a reference could not be resolved
+ */
+ private static function evaluateScalar(string $scalar, int $flags, array $references = array())
+ {
+ $scalar = trim($scalar);
+ $scalarLower = strtolower($scalar);
+
+ if (0 === strpos($scalar, '*')) {
+ if (false !== $pos = strpos($scalar, '#')) {
+ $value = substr($scalar, 1, $pos - 2);
+ } else {
+ $value = substr($scalar, 1);
+ }
+
+ // an unquoted *
+ if (false === $value || '' === $value) {
+ throw new ParseException('A reference must contain at least one character.', self::$parsedLineNumber + 1, $value, self::$parsedFilename);
+ }
+
+ if (!array_key_exists($value, $references)) {
+ throw new ParseException(sprintf('Reference "%s" does not exist.', $value), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
+ }
+
+ return $references[$value];
+ }
+
+ switch (true) {
+ case 'null' === $scalarLower:
+ case '' === $scalar:
+ case '~' === $scalar:
+ return;
+ case 'true' === $scalarLower:
+ return true;
+ case 'false' === $scalarLower:
+ return false;
+ case '!' === $scalar[0]:
+ switch (true) {
+ case 0 === strpos($scalar, '!!str '):
+ return (string) substr($scalar, 6);
+ case 0 === strpos($scalar, '! '):
+ return substr($scalar, 2);
+ case 0 === strpos($scalar, '!php/object'):
+ if (self::$objectSupport) {
+ return unserialize(self::parseScalar(substr($scalar, 12)));
+ }
+
+ if (self::$exceptionOnInvalidType) {
+ throw new ParseException('Object support when parsing a YAML file has been disabled.', self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
+ }
+
+ return;
+ case 0 === strpos($scalar, '!php/const'):
+ if (self::$constantSupport) {
+ $i = 0;
+ if (\defined($const = self::parseScalar(substr($scalar, 11), 0, null, $i, false))) {
+ return \constant($const);
+ }
+
+ throw new ParseException(sprintf('The constant "%s" is not defined.', $const), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
+ }
+ if (self::$exceptionOnInvalidType) {
+ throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Have you forgotten to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
+ }
+
+ return;
+ case 0 === strpos($scalar, '!!float '):
+ return (float) substr($scalar, 8);
+ case 0 === strpos($scalar, '!!binary '):
+ return self::evaluateBinaryScalar(substr($scalar, 9));
+ default:
+ throw new ParseException(sprintf('The string "%s" could not be parsed as it uses an unsupported built-in tag.', $scalar), self::$parsedLineNumber, $scalar, self::$parsedFilename);
+ }
+
+ // Optimize for returning strings.
+ // no break
+ case '+' === $scalar[0] || '-' === $scalar[0] || '.' === $scalar[0] || is_numeric($scalar[0]):
+ switch (true) {
+ case Parser::preg_match('{^[+-]?[0-9][0-9_]*$}', $scalar):
+ $scalar = str_replace('_', '', (string) $scalar);
+ // omitting the break / return as integers are handled in the next case
+ // no break
+ case ctype_digit($scalar):
+ $raw = $scalar;
+ $cast = (int) $scalar;
+
+ return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
+ case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)):
+ $raw = $scalar;
+ $cast = (int) $scalar;
+
+ return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw === (string) $cast) ? $cast : $raw);
+ case is_numeric($scalar):
+ case Parser::preg_match(self::getHexRegex(), $scalar):
+ $scalar = str_replace('_', '', $scalar);
+
+ return '0x' === $scalar[0].$scalar[1] ? hexdec($scalar) : (float) $scalar;
+ case '.inf' === $scalarLower:
+ case '.nan' === $scalarLower:
+ return -log(0);
+ case '-.inf' === $scalarLower:
+ return log(0);
+ case Parser::preg_match('/^(-|\+)?[0-9][0-9_]*(\.[0-9_]+)?$/', $scalar):
+ return (float) str_replace('_', '', $scalar);
+ case Parser::preg_match(self::getTimestampRegex(), $scalar):
+ if (Yaml::PARSE_DATETIME & $flags) {
+ // When no timezone is provided in the parsed date, YAML spec says we must assume UTC.
+ return new \DateTime($scalar, new \DateTimeZone('UTC'));
+ }
+
+ $timeZone = date_default_timezone_get();
+ date_default_timezone_set('UTC');
+ $time = strtotime($scalar);
+ date_default_timezone_set($timeZone);
+
+ return $time;
+ }
+ }
+
+ return (string) $scalar;
+ }
+
+ private static function parseTag(string $value, int &$i, int $flags): ?string
+ {
+ if ('!' !== $value[$i]) {
+ return null;
+ }
+
+ $tagLength = strcspn($value, " \t\n[]{},", $i + 1);
+ $tag = substr($value, $i + 1, $tagLength);
+
+ $nextOffset = $i + $tagLength + 1;
+ $nextOffset += strspn($value, ' ', $nextOffset);
+
+ // Is followed by a scalar and is a built-in tag
+ if ($tag && (!isset($value[$nextOffset]) || !\in_array($value[$nextOffset], array('[', '{'), true)) && ('!' === $tag[0] || 'str' === $tag || 'php/const' === $tag || 'php/object' === $tag)) {
+ // Manage in {@link self::evaluateScalar()}
+ return null;
+ }
+
+ $i = $nextOffset;
+
+ // Built-in tags
+ if ($tag && '!' === $tag[0]) {
+ throw new ParseException(sprintf('The built-in tag "!%s" is not implemented.', $tag), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
+ }
+
+ if ('' === $tag || Yaml::PARSE_CUSTOM_TAGS & $flags) {
+ return $tag;
+ }
+
+ throw new ParseException(sprintf('Tags support is not enabled. Enable the `Yaml::PARSE_CUSTOM_TAGS` flag to use "!%s".', $tag), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
+ }
+
+ public static function evaluateBinaryScalar(string $scalar): string
+ {
+ $parsedBinaryData = self::parseScalar(preg_replace('/\s/', '', $scalar));
+
+ if (0 !== (\strlen($parsedBinaryData) % 4)) {
+ throw new ParseException(sprintf('The normalized base64 encoded data (data without whitespace characters) length must be a multiple of four (%d bytes given).', \strlen($parsedBinaryData)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
+ }
+
+ if (!Parser::preg_match('#^[A-Z0-9+/]+={0,2}$#i', $parsedBinaryData)) {
+ throw new ParseException(sprintf('The base64 encoded data (%s) contains invalid characters.', $parsedBinaryData), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
+ }
+
+ return base64_decode($parsedBinaryData, true);
+ }
+
+ private static function isBinaryString(string $value)
+ {
+ return !preg_match('//u', $value) || preg_match('/[^\x00\x07-\x0d\x1B\x20-\xff]/', $value);
+ }
+
+ /**
+ * Gets a regex that matches a YAML date.
+ *
+ * @return string The regular expression
+ *
+ * @see http://www.yaml.org/spec/1.2/spec.html#id2761573
+ */
+ private static function getTimestampRegex(): string
+ {
+ return <<<EOF
+ ~^
+ (?P<year>[0-9][0-9][0-9][0-9])
+ -(?P<month>[0-9][0-9]?)
+ -(?P<day>[0-9][0-9]?)
+ (?:(?:[Tt]|[ \t]+)
+ (?P<hour>[0-9][0-9]?)
+ :(?P<minute>[0-9][0-9])
+ :(?P<second>[0-9][0-9])
+ (?:\.(?P<fraction>[0-9]*))?
+ (?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
+ (?::(?P<tz_minute>[0-9][0-9]))?))?)?
+ $~x
+EOF;
+ }
+
+ /**
+ * Gets a regex that matches a YAML number in hexadecimal notation.
+ *
+ * @return string
+ */
+ private static function getHexRegex(): string
+ {
+ return '~^0x[0-9a-f_]++$~i';
+ }
+}
diff --git a/vendor/symfony/yaml/LICENSE b/vendor/symfony/yaml/LICENSE
new file mode 100644
index 0000000..21d7fb9
--- /dev/null
+++ b/vendor/symfony/yaml/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2018 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/symfony/yaml/Parser.php b/vendor/symfony/yaml/Parser.php
new file mode 100644
index 0000000..35e7443
--- /dev/null
+++ b/vendor/symfony/yaml/Parser.php
@@ -0,0 +1,1095 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+use Symfony\Component\Yaml\Exception\ParseException;
+use Symfony\Component\Yaml\Tag\TaggedValue;
+
+/**
+ * Parser parses YAML strings to convert them to PHP arrays.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @final
+ */
+class Parser
+{
+ const TAG_PATTERN = '(?P<tag>![\w!.\/:-]+)';
+ const BLOCK_SCALAR_HEADER_PATTERN = '(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments> +#.*)?';
+
+ private $filename;
+ private $offset = 0;
+ private $totalNumberOfLines;
+ private $lines = array();
+ private $currentLineNb = -1;
+ private $currentLine = '';
+ private $refs = array();
+ private $skippedLineNumbers = array();
+ private $locallySkippedLineNumbers = array();
+
+ /**
+ * Parses a YAML file into a PHP value.
+ *
+ * @param string $filename The path to the YAML file to be parsed
+ * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior
+ *
+ * @return mixed The YAML converted to a PHP value
+ *
+ * @throws ParseException If the file could not be read or the YAML is not valid
+ */
+ public function parseFile(string $filename, int $flags = 0)
+ {
+ if (!is_file($filename)) {
+ throw new ParseException(sprintf('File "%s" does not exist.', $filename));
+ }
+
+ if (!is_readable($filename)) {
+ throw new ParseException(sprintf('File "%s" cannot be read.', $filename));
+ }
+
+ $this->filename = $filename;
+
+ try {
+ return $this->parse(file_get_contents($filename), $flags);
+ } finally {
+ $this->filename = null;
+ }
+ }
+
+ /**
+ * Parses a YAML string to a PHP value.
+ *
+ * @param string $value A YAML string
+ * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior
+ *
+ * @return mixed A PHP value
+ *
+ * @throws ParseException If the YAML is not valid
+ */
+ public function parse(string $value, int $flags = 0)
+ {
+ if (false === preg_match('//u', $value)) {
+ throw new ParseException('The YAML value does not appear to be valid UTF-8.', -1, null, $this->filename);
+ }
+
+ $this->refs = array();
+
+ $mbEncoding = null;
+ $data = null;
+
+ if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) {
+ $mbEncoding = mb_internal_encoding();
+ mb_internal_encoding('UTF-8');
+ }
+
+ try {
+ $data = $this->doParse($value, $flags);
+ } finally {
+ if (null !== $mbEncoding) {
+ mb_internal_encoding($mbEncoding);
+ }
+ $this->lines = array();
+ $this->currentLine = '';
+ $this->refs = array();
+ $this->skippedLineNumbers = array();
+ $this->locallySkippedLineNumbers = array();
+ }
+
+ return $data;
+ }
+
+ /**
+ * @internal
+ *
+ * @return int
+ */
+ public function getLastLineNumberBeforeDeprecation(): int
+ {
+ return $this->getRealCurrentLineNb();
+ }
+
+ private function doParse(string $value, int $flags)
+ {
+ $this->currentLineNb = -1;
+ $this->currentLine = '';
+ $value = $this->cleanup($value);
+ $this->lines = explode("\n", $value);
+ $this->locallySkippedLineNumbers = array();
+
+ if (null === $this->totalNumberOfLines) {
+ $this->totalNumberOfLines = \count($this->lines);
+ }
+
+ if (!$this->moveToNextLine()) {
+ return null;
+ }
+
+ $data = array();
+ $context = null;
+ $allowOverwrite = false;
+
+ while ($this->isCurrentLineEmpty()) {
+ if (!$this->moveToNextLine()) {
+ return null;
+ }
+ }
+
+ // Resolves the tag and returns if end of the document
+ if (null !== ($tag = $this->getLineTag($this->currentLine, $flags, false)) && !$this->moveToNextLine()) {
+ return new TaggedValue($tag, '');
+ }
+
+ do {
+ if ($this->isCurrentLineEmpty()) {
+ continue;
+ }
+
+ // tab?
+ if ("\t" === $this->currentLine[0]) {
+ throw new ParseException('A YAML file cannot contain tabs as indentation.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
+ }
+
+ Inline::initialize($flags, $this->getRealCurrentLineNb(), $this->filename);
+
+ $isRef = $mergeNode = false;
+ if (self::preg_match('#^\-((?P<leadspaces>\s+)(?P<value>.+))?$#u', rtrim($this->currentLine), $values)) {
+ if ($context && 'mapping' == $context) {
+ throw new ParseException('You cannot define a sequence item when in a mapping', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
+ }
+ $context = 'sequence';
+
+ if (isset($values['value']) && self::preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
+ $isRef = $matches['ref'];
+ $values['value'] = $matches['value'];
+ }
+
+ if (isset($values['value'][1]) && '?' === $values['value'][0] && ' ' === $values['value'][1]) {
+ throw new ParseException('Complex mappings are not supported.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
+ }
+
+ // array
+ if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
+ $data[] = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true) ?? '', $flags);
+ } elseif (null !== $subTag = $this->getLineTag(ltrim($values['value'], ' '), $flags)) {
+ $data[] = new TaggedValue(
+ $subTag,
+ $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true), $flags)
+ );
+ } else {
+ if (isset($values['leadspaces'])
+ && self::preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->trimTag($values['value']), $matches)
+ ) {
+ // this is a compact notation element, add to next block and parse
+ $block = $values['value'];
+ if ($this->isNextLineIndented()) {
+ $block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + \strlen($values['leadspaces']) + 1);
+ }
+
+ $data[] = $this->parseBlock($this->getRealCurrentLineNb(), $block, $flags);
+ } else {
+ $data[] = $this->parseValue($values['value'], $flags, $context);
+ }
+ }
+ if ($isRef) {
+ $this->refs[$isRef] = end($data);
+ }
+ } elseif (
+ self::preg_match('#^(?P<key>(?:![^\s]++\s++)?(?:'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?[^ \'"\[\{!].*?)) *\:(\s++(?P<value>.+))?$#u', rtrim($this->currentLine), $values)
+ && (false === strpos($values['key'], ' #') || \in_array($values['key'][0], array('"', "'")))
+ ) {
+ if ($context && 'sequence' == $context) {
+ throw new ParseException('You cannot define a mapping item when in a sequence', $this->currentLineNb + 1, $this->currentLine, $this->filename);
+ }
+ $context = 'mapping';
+
+ try {
+ $key = Inline::parseScalar($values['key']);
+ } catch (ParseException $e) {
+ $e->setParsedLine($this->getRealCurrentLineNb() + 1);
+ $e->setSnippet($this->currentLine);
+
+ throw $e;
+ }
+
+ if (!\is_string($key) && !\is_int($key)) {
+ throw new ParseException(sprintf('%s keys are not supported. Quote your evaluable mapping keys instead.', is_numeric($key) ? 'Numeric' : 'Non-string'), $this->getRealCurrentLineNb() + 1, $this->currentLine);
+ }
+
+ // Convert float keys to strings, to avoid being converted to integers by PHP
+ if (\is_float($key)) {
+ $key = (string) $key;
+ }
+
+ if ('<<' === $key && (!isset($values['value']) || !self::preg_match('#^&(?P<ref>[^ ]+)#u', $values['value'], $refMatches))) {
+ $mergeNode = true;
+ $allowOverwrite = true;
+ if (isset($values['value'][0]) && '*' === $values['value'][0]) {
+ $refName = substr(rtrim($values['value']), 1);
+ if (!array_key_exists($refName, $this->refs)) {
+ throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
+ }
+
+ $refValue = $this->refs[$refName];
+
+ if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $refValue instanceof \stdClass) {
+ $refValue = (array) $refValue;
+ }
+
+ if (!\is_array($refValue)) {
+ throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
+ }
+
+ $data += $refValue; // array union
+ } else {
+ if (isset($values['value']) && '' !== $values['value']) {
+ $value = $values['value'];
+ } else {
+ $value = $this->getNextEmbedBlock();
+ }
+ $parsed = $this->parseBlock($this->getRealCurrentLineNb() + 1, $value, $flags);
+
+ if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $parsed instanceof \stdClass) {
+ $parsed = (array) $parsed;
+ }
+
+ if (!\is_array($parsed)) {
+ throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
+ }
+
+ if (isset($parsed[0])) {
+ // If the value associated with the merge key is a sequence, then this sequence is expected to contain mapping nodes
+ // and each of these nodes is merged in turn according to its order in the sequence. Keys in mapping nodes earlier
+ // in the sequence override keys specified in later mapping nodes.
+ foreach ($parsed as $parsedItem) {
+ if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $parsedItem instanceof \stdClass) {
+ $parsedItem = (array) $parsedItem;
+ }
+
+ if (!\is_array($parsedItem)) {
+ throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem, $this->filename);
+ }
+
+ $data += $parsedItem; // array union
+ }
+ } else {
+ // If the value associated with the key is a single mapping node, each of its key/value pairs is inserted into the
+ // current mapping, unless the key already exists in it.
+ $data += $parsed; // array union
+ }
+ }
+ } elseif ('<<' !== $key && isset($values['value']) && self::preg_match('#^&(?P<ref>[^ ]++) *+(?P<value>.*)#u', $values['value'], $matches)) {
+ $isRef = $matches['ref'];
+ $values['value'] = $matches['value'];
+ }
+
+ $subTag = null;
+ if ($mergeNode) {
+ // Merge keys
+ } elseif (!isset($values['value']) || '' === $values['value'] || 0 === strpos($values['value'], '#') || (null !== $subTag = $this->getLineTag($values['value'], $flags)) || '<<' === $key) {
+ // hash
+ // if next line is less indented or equal, then it means that the current value is null
+ if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
+ // Spec: Keys MUST be unique; first one wins.
+ // But overwriting is allowed when a merge node is used in current block.
+ if ($allowOverwrite || !isset($data[$key])) {
+ if (null !== $subTag) {
+ $data[$key] = new TaggedValue($subTag, '');
+ } else {
+ $data[$key] = null;
+ }
+ } else {
+ throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), $this->getRealCurrentLineNb() + 1, $this->currentLine);
+ }
+ } else {
+ // remember the parsed line number here in case we need it to provide some contexts in error messages below
+ $realCurrentLineNbKey = $this->getRealCurrentLineNb();
+ $value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $flags);
+ if ('<<' === $key) {
+ $this->refs[$refMatches['ref']] = $value;
+
+ if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $value instanceof \stdClass) {
+ $value = (array) $value;
+ }
+
+ $data += $value;
+ } elseif ($allowOverwrite || !isset($data[$key])) {
+ // Spec: Keys MUST be unique; first one wins.
+ // But overwriting is allowed when a merge node is used in current block.
+ if (null !== $subTag) {
+ $data[$key] = new TaggedValue($subTag, $value);
+ } else {
+ $data[$key] = $value;
+ }
+ } else {
+ throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), $realCurrentLineNbKey + 1, $this->currentLine);
+ }
+ }
+ } else {
+ $value = $this->parseValue(rtrim($values['value']), $flags, $context);
+ // Spec: Keys MUST be unique; first one wins.
+ // But overwriting is allowed when a merge node is used in current block.
+ if ($allowOverwrite || !isset($data[$key])) {
+ $data[$key] = $value;
+ } else {
+ throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), $this->getRealCurrentLineNb() + 1, $this->currentLine);
+ }
+ }
+ if ($isRef) {
+ $this->refs[$isRef] = $data[$key];
+ }
+ } else {
+ // multiple documents are not supported
+ if ('---' === $this->currentLine) {
+ throw new ParseException('Multiple documents are not supported.', $this->currentLineNb + 1, $this->currentLine, $this->filename);
+ }
+
+ if ($deprecatedUsage = (isset($this->currentLine[1]) && '?' === $this->currentLine[0] && ' ' === $this->currentLine[1])) {
+ throw new ParseException('Complex mappings are not supported.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
+ }
+
+ // 1-liner optionally followed by newline(s)
+ if (\is_string($value) && $this->lines[0] === trim($value)) {
+ try {
+ $value = Inline::parse($this->lines[0], $flags, $this->refs);
+ } catch (ParseException $e) {
+ $e->setParsedLine($this->getRealCurrentLineNb() + 1);
+ $e->setSnippet($this->currentLine);
+
+ throw $e;
+ }
+
+ return $value;
+ }
+
+ // try to parse the value as a multi-line string as a last resort
+ if (0 === $this->currentLineNb) {
+ $previousLineWasNewline = false;
+ $previousLineWasTerminatedWithBackslash = false;
+ $value = '';
+
+ foreach ($this->lines as $line) {
+ // If the indentation is not consistent at offset 0, it is to be considered as a ParseError
+ if (0 === $this->offset && !$deprecatedUsage && isset($line[0]) && ' ' === $line[0]) {
+ throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
+ }
+ if ('' === trim($line)) {
+ $value .= "\n";
+ } elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) {
+ $value .= ' ';
+ }
+
+ if ('' !== trim($line) && '\\' === substr($line, -1)) {
+ $value .= ltrim(substr($line, 0, -1));
+ } elseif ('' !== trim($line)) {
+ $value .= trim($line);
+ }
+
+ if ('' === trim($line)) {
+ $previousLineWasNewline = true;
+ $previousLineWasTerminatedWithBackslash = false;
+ } elseif ('\\' === substr($line, -1)) {
+ $previousLineWasNewline = false;
+ $previousLineWasTerminatedWithBackslash = true;
+ } else {
+ $previousLineWasNewline = false;
+ $previousLineWasTerminatedWithBackslash = false;
+ }
+ }
+
+ try {
+ return Inline::parse(trim($value));
+ } catch (ParseException $e) {
+ // fall-through to the ParseException thrown below
+ }
+ }
+
+ throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
+ }
+ } while ($this->moveToNextLine());
+
+ if (null !== $tag) {
+ $data = new TaggedValue($tag, $data);
+ }
+
+ if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && !\is_object($data) && 'mapping' === $context) {
+ $object = new \stdClass();
+
+ foreach ($data as $key => $value) {
+ $object->$key = $value;
+ }
+
+ $data = $object;
+ }
+
+ return empty($data) ? null : $data;
+ }
+
+ private function parseBlock(int $offset, string $yaml, int $flags)
+ {
+ $skippedLineNumbers = $this->skippedLineNumbers;
+
+ foreach ($this->locallySkippedLineNumbers as $lineNumber) {
+ if ($lineNumber < $offset) {
+ continue;
+ }
+
+ $skippedLineNumbers[] = $lineNumber;
+ }
+
+ $parser = new self();
+ $parser->offset = $offset;
+ $parser->totalNumberOfLines = $this->totalNumberOfLines;
+ $parser->skippedLineNumbers = $skippedLineNumbers;
+ $parser->refs = &$this->refs;
+
+ return $parser->doParse($yaml, $flags);
+ }
+
+ /**
+ * Returns the current line number (takes the offset into account).
+ *
+ * @internal
+ *
+ * @return int The current line number
+ */
+ public function getRealCurrentLineNb(): int
+ {
+ $realCurrentLineNumber = $this->currentLineNb + $this->offset;
+
+ foreach ($this->skippedLineNumbers as $skippedLineNumber) {
+ if ($skippedLineNumber > $realCurrentLineNumber) {
+ break;
+ }
+
+ ++$realCurrentLineNumber;
+ }
+
+ return $realCurrentLineNumber;
+ }
+
+ /**
+ * Returns the current line indentation.
+ *
+ * @return int The current line indentation
+ */
+ private function getCurrentLineIndentation(): int
+ {
+ return \strlen($this->currentLine) - \strlen(ltrim($this->currentLine, ' '));
+ }
+
+ /**
+ * Returns the next embed block of YAML.
+ *
+ * @param int|null $indentation The indent level at which the block is to be read, or null for default
+ * @param bool $inSequence True if the enclosing data structure is a sequence
+ *
+ * @return string A YAML string
+ *
+ * @throws ParseException When indentation problem are detected
+ */
+ private function getNextEmbedBlock(int $indentation = null, bool $inSequence = false): ?string
+ {
+ $oldLineIndentation = $this->getCurrentLineIndentation();
+ $blockScalarIndentations = array();
+
+ if ($this->isBlockScalarHeader()) {
+ $blockScalarIndentations[] = $oldLineIndentation;
+ }
+
+ if (!$this->moveToNextLine()) {
+ return null;
+ }
+
+ if (null === $indentation) {
+ $newIndent = null;
+ $movements = 0;
+
+ do {
+ $EOF = false;
+
+ // empty and comment-like lines do not influence the indentation depth
+ if ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()) {
+ $EOF = !$this->moveToNextLine();
+
+ if (!$EOF) {
+ ++$movements;
+ }
+ } else {
+ $newIndent = $this->getCurrentLineIndentation();
+ }
+ } while (!$EOF && null === $newIndent);
+
+ for ($i = 0; $i < $movements; ++$i) {
+ $this->moveToPreviousLine();
+ }
+
+ $unindentedEmbedBlock = $this->isStringUnIndentedCollectionItem();
+
+ if (!$this->isCurrentLineEmpty() && 0 === $newIndent && !$unindentedEmbedBlock) {
+ throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
+ }
+ } else {
+ $newIndent = $indentation;
+ }
+
+ $data = array();
+ if ($this->getCurrentLineIndentation() >= $newIndent) {
+ $data[] = substr($this->currentLine, $newIndent);
+ } elseif ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()) {
+ $data[] = $this->currentLine;
+ } else {
+ $this->moveToPreviousLine();
+
+ return null;
+ }
+
+ if ($inSequence && $oldLineIndentation === $newIndent && isset($data[0][0]) && '-' === $data[0][0]) {
+ // the previous line contained a dash but no item content, this line is a sequence item with the same indentation
+ // and therefore no nested list or mapping
+ $this->moveToPreviousLine();
+
+ return null;
+ }
+
+ $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem();
+
+ if (empty($blockScalarIndentations) && $this->isBlockScalarHeader()) {
+ $blockScalarIndentations[] = $this->getCurrentLineIndentation();
+ }
+
+ $previousLineIndentation = $this->getCurrentLineIndentation();
+
+ while ($this->moveToNextLine()) {
+ $indent = $this->getCurrentLineIndentation();
+
+ // terminate all block scalars that are more indented than the current line
+ if (!empty($blockScalarIndentations) && $indent < $previousLineIndentation && '' !== trim($this->currentLine)) {
+ foreach ($blockScalarIndentations as $key => $blockScalarIndentation) {
+ if ($blockScalarIndentation >= $indent) {
+ unset($blockScalarIndentations[$key]);
+ }
+ }
+ }
+
+ if (empty($blockScalarIndentations) && !$this->isCurrentLineComment() && $this->isBlockScalarHeader()) {
+ $blockScalarIndentations[] = $indent;
+ }
+
+ $previousLineIndentation = $indent;
+
+ if ($isItUnindentedCollection && !$this->isCurrentLineEmpty() && !$this->isStringUnIndentedCollectionItem() && $newIndent === $indent) {
+ $this->moveToPreviousLine();
+ break;
+ }
+
+ if ($this->isCurrentLineBlank()) {
+ $data[] = substr($this->currentLine, $newIndent);
+ continue;
+ }
+
+ if ($indent >= $newIndent) {
+ $data[] = substr($this->currentLine, $newIndent);
+ } elseif ($this->isCurrentLineComment()) {
+ $data[] = $this->currentLine;
+ } elseif (0 == $indent) {
+ $this->moveToPreviousLine();
+
+ break;
+ } else {
+ throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
+ }
+ }
+
+ return implode("\n", $data);
+ }
+
+ /**
+ * Moves the parser to the next line.
+ *
+ * @return bool
+ */
+ private function moveToNextLine(): bool
+ {
+ if ($this->currentLineNb >= \count($this->lines) - 1) {
+ return false;
+ }
+
+ $this->currentLine = $this->lines[++$this->currentLineNb];
+
+ return true;
+ }
+
+ /**
+ * Moves the parser to the previous line.
+ *
+ * @return bool
+ */
+ private function moveToPreviousLine(): bool
+ {
+ if ($this->currentLineNb < 1) {
+ return false;
+ }
+
+ $this->currentLine = $this->lines[--$this->currentLineNb];
+
+ return true;
+ }
+
+ /**
+ * Parses a YAML value.
+ *
+ * @param string $value A YAML value
+ * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior
+ * @param string $context The parser context (either sequence or mapping)
+ *
+ * @return mixed A PHP value
+ *
+ * @throws ParseException When reference does not exist
+ */
+ private function parseValue(string $value, int $flags, string $context)
+ {
+ if (0 === strpos($value, '*')) {
+ if (false !== $pos = strpos($value, '#')) {
+ $value = substr($value, 1, $pos - 2);
+ } else {
+ $value = substr($value, 1);
+ }
+
+ if (!array_key_exists($value, $this->refs)) {
+ throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLineNb + 1, $this->currentLine, $this->filename);
+ }
+
+ return $this->refs[$value];
+ }
+
+ if (self::preg_match('/^(?:'.self::TAG_PATTERN.' +)?'.self::BLOCK_SCALAR_HEADER_PATTERN.'$/', $value, $matches)) {
+ $modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : '';
+
+ $data = $this->parseBlockScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers));
+
+ if ('' !== $matches['tag'] && '!' !== $matches['tag']) {
+ if ('!!binary' === $matches['tag']) {
+ return Inline::evaluateBinaryScalar($data);
+ }
+
+ return new TaggedValue(substr($matches['tag'], 1), $data);
+ }
+
+ return $data;
+ }
+
+ try {
+ $quotation = '' !== $value && ('"' === $value[0] || "'" === $value[0]) ? $value[0] : null;
+
+ // do not take following lines into account when the current line is a quoted single line value
+ if (null !== $quotation && self::preg_match('/^'.$quotation.'.*'.$quotation.'(\s*#.*)?$/', $value)) {
+ return Inline::parse($value, $flags, $this->refs);
+ }
+
+ $lines = array();
+
+ while ($this->moveToNextLine()) {
+ // unquoted strings end before the first unindented line
+ if (null === $quotation && 0 === $this->getCurrentLineIndentation()) {
+ $this->moveToPreviousLine();
+
+ break;
+ }
+
+ $lines[] = trim($this->currentLine);
+
+ // quoted string values end with a line that is terminated with the quotation character
+ if ('' !== $this->currentLine && substr($this->currentLine, -1) === $quotation) {
+ break;
+ }
+ }
+
+ for ($i = 0, $linesCount = \count($lines), $previousLineBlank = false; $i < $linesCount; ++$i) {
+ if ('' === $lines[$i]) {
+ $value .= "\n";
+ $previousLineBlank = true;
+ } elseif ($previousLineBlank) {
+ $value .= $lines[$i];
+ $previousLineBlank = false;
+ } else {
+ $value .= ' '.$lines[$i];
+ $previousLineBlank = false;
+ }
+ }
+
+ Inline::$parsedLineNumber = $this->getRealCurrentLineNb();
+
+ $parsedValue = Inline::parse($value, $flags, $this->refs);
+
+ if ('mapping' === $context && \is_string($parsedValue) && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($parsedValue, ': ')) {
+ throw new ParseException('A colon cannot be used in an unquoted mapping value.', $this->getRealCurrentLineNb() + 1, $value, $this->filename);
+ }
+
+ return $parsedValue;
+ } catch (ParseException $e) {
+ $e->setParsedLine($this->getRealCurrentLineNb() + 1);
+ $e->setSnippet($this->currentLine);
+
+ throw $e;
+ }
+ }
+
+ /**
+ * Parses a block scalar.
+ *
+ * @param string $style The style indicator that was used to begin this block scalar (| or >)
+ * @param string $chomping The chomping indicator that was used to begin this block scalar (+ or -)
+ * @param int $indentation The indentation indicator that was used to begin this block scalar
+ *
+ * @return string The text value
+ */
+ private function parseBlockScalar(string $style, string $chomping = '', int $indentation = 0): string
+ {
+ $notEOF = $this->moveToNextLine();
+ if (!$notEOF) {
+ return '';
+ }
+
+ $isCurrentLineBlank = $this->isCurrentLineBlank();
+ $blockLines = array();
+
+ // leading blank lines are consumed before determining indentation
+ while ($notEOF && $isCurrentLineBlank) {
+ // newline only if not EOF
+ if ($notEOF = $this->moveToNextLine()) {
+ $blockLines[] = '';
+ $isCurrentLineBlank = $this->isCurrentLineBlank();
+ }
+ }
+
+ // determine indentation if not specified
+ if (0 === $indentation) {
+ if (self::preg_match('/^ +/', $this->currentLine, $matches)) {
+ $indentation = \strlen($matches[0]);
+ }
+ }
+
+ if ($indentation > 0) {
+ $pattern = sprintf('/^ {%d}(.*)$/', $indentation);
+
+ while (
+ $notEOF && (
+ $isCurrentLineBlank ||
+ self::preg_match($pattern, $this->currentLine, $matches)
+ )
+ ) {
+ if ($isCurrentLineBlank && \strlen($this->currentLine) > $indentation) {
+ $blockLines[] = substr($this->currentLine, $indentation);
+ } elseif ($isCurrentLineBlank) {
+ $blockLines[] = '';
+ } else {
+ $blockLines[] = $matches[1];
+ }
+
+ // newline only if not EOF
+ if ($notEOF = $this->moveToNextLine()) {
+ $isCurrentLineBlank = $this->isCurrentLineBlank();
+ }
+ }
+ } elseif ($notEOF) {
+ $blockLines[] = '';
+ }
+
+ if ($notEOF) {
+ $blockLines[] = '';
+ $this->moveToPreviousLine();
+ } elseif (!$notEOF && !$this->isCurrentLineLastLineInDocument()) {
+ $blockLines[] = '';
+ }
+
+ // folded style
+ if ('>' === $style) {
+ $text = '';
+ $previousLineIndented = false;
+ $previousLineBlank = false;
+
+ for ($i = 0, $blockLinesCount = \count($blockLines); $i < $blockLinesCount; ++$i) {
+ if ('' === $blockLines[$i]) {
+ $text .= "\n";
+ $previousLineIndented = false;
+ $previousLineBlank = true;
+ } elseif (' ' === $blockLines[$i][0]) {
+ $text .= "\n".$blockLines[$i];
+ $previousLineIndented = true;
+ $previousLineBlank = false;
+ } elseif ($previousLineIndented) {
+ $text .= "\n".$blockLines[$i];
+ $previousLineIndented = false;
+ $previousLineBlank = false;
+ } elseif ($previousLineBlank || 0 === $i) {
+ $text .= $blockLines[$i];
+ $previousLineIndented = false;
+ $previousLineBlank = false;
+ } else {
+ $text .= ' '.$blockLines[$i];
+ $previousLineIndented = false;
+ $previousLineBlank = false;
+ }
+ }
+ } else {
+ $text = implode("\n", $blockLines);
+ }
+
+ // deal with trailing newlines
+ if ('' === $chomping) {
+ $text = preg_replace('/\n+$/', "\n", $text);
+ } elseif ('-' === $chomping) {
+ $text = preg_replace('/\n+$/', '', $text);
+ }
+
+ return $text;
+ }
+
+ /**
+ * Returns true if the next line is indented.
+ *
+ * @return bool Returns true if the next line is indented, false otherwise
+ */
+ private function isNextLineIndented(): bool
+ {
+ $currentIndentation = $this->getCurrentLineIndentation();
+ $movements = 0;
+
+ do {
+ $EOF = !$this->moveToNextLine();
+
+ if (!$EOF) {
+ ++$movements;
+ }
+ } while (!$EOF && ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()));
+
+ if ($EOF) {
+ return false;
+ }
+
+ $ret = $this->getCurrentLineIndentation() > $currentIndentation;
+
+ for ($i = 0; $i < $movements; ++$i) {
+ $this->moveToPreviousLine();
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Returns true if the current line is blank or if it is a comment line.
+ *
+ * @return bool Returns true if the current line is empty or if it is a comment line, false otherwise
+ */
+ private function isCurrentLineEmpty(): bool
+ {
+ return $this->isCurrentLineBlank() || $this->isCurrentLineComment();
+ }
+
+ /**
+ * Returns true if the current line is blank.
+ *
+ * @return bool Returns true if the current line is blank, false otherwise
+ */
+ private function isCurrentLineBlank(): bool
+ {
+ return '' == trim($this->currentLine, ' ');
+ }
+
+ /**
+ * Returns true if the current line is a comment line.
+ *
+ * @return bool Returns true if the current line is a comment line, false otherwise
+ */
+ private function isCurrentLineComment(): bool
+ {
+ //checking explicitly the first char of the trim is faster than loops or strpos
+ $ltrimmedLine = ltrim($this->currentLine, ' ');
+
+ return '' !== $ltrimmedLine && '#' === $ltrimmedLine[0];
+ }
+
+ private function isCurrentLineLastLineInDocument(): bool
+ {
+ return ($this->offset + $this->currentLineNb) >= ($this->totalNumberOfLines - 1);
+ }
+
+ /**
+ * Cleanups a YAML string to be parsed.
+ *
+ * @param string $value The input YAML string
+ *
+ * @return string A cleaned up YAML string
+ */
+ private function cleanup(string $value): string
+ {
+ $value = str_replace(array("\r\n", "\r"), "\n", $value);
+
+ // strip YAML header
+ $count = 0;
+ $value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#u', '', $value, -1, $count);
+ $this->offset += $count;
+
+ // remove leading comments
+ $trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
+ if (1 === $count) {
+ // items have been removed, update the offset
+ $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
+ $value = $trimmedValue;
+ }
+
+ // remove start of the document marker (---)
+ $trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
+ if (1 === $count) {
+ // items have been removed, update the offset
+ $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
+ $value = $trimmedValue;
+
+ // remove end of the document marker (...)
+ $value = preg_replace('#\.\.\.\s*$#', '', $value);
+ }
+
+ return $value;
+ }
+
+ /**
+ * Returns true if the next line starts unindented collection.
+ *
+ * @return bool Returns true if the next line starts unindented collection, false otherwise
+ */
+ private function isNextLineUnIndentedCollection(): bool
+ {
+ $currentIndentation = $this->getCurrentLineIndentation();
+ $movements = 0;
+
+ do {
+ $EOF = !$this->moveToNextLine();
+
+ if (!$EOF) {
+ ++$movements;
+ }
+ } while (!$EOF && ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()));
+
+ if ($EOF) {
+ return false;
+ }
+
+ $ret = $this->getCurrentLineIndentation() === $currentIndentation && $this->isStringUnIndentedCollectionItem();
+
+ for ($i = 0; $i < $movements; ++$i) {
+ $this->moveToPreviousLine();
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Returns true if the string is un-indented collection item.
+ *
+ * @return bool Returns true if the string is un-indented collection item, false otherwise
+ */
+ private function isStringUnIndentedCollectionItem(): bool
+ {
+ return '-' === rtrim($this->currentLine) || 0 === strpos($this->currentLine, '- ');
+ }
+
+ /**
+ * Tests whether or not the current line is the header of a block scalar.
+ *
+ * @return bool
+ */
+ private function isBlockScalarHeader(): bool
+ {
+ return (bool) self::preg_match('~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~', $this->currentLine);
+ }
+
+ /**
+ * A local wrapper for `preg_match` which will throw a ParseException if there
+ * is an internal error in the PCRE engine.
+ *
+ * This avoids us needing to check for "false" every time PCRE is used
+ * in the YAML engine
+ *
+ * @throws ParseException on a PCRE internal error
+ *
+ * @see preg_last_error()
+ *
+ * @internal
+ */
+ public static function preg_match(string $pattern, string $subject, array &$matches = null, int $flags = 0, int $offset = 0): int
+ {
+ if (false === $ret = preg_match($pattern, $subject, $matches, $flags, $offset)) {
+ switch (preg_last_error()) {
+ case PREG_INTERNAL_ERROR:
+ $error = 'Internal PCRE error.';
+ break;
+ case PREG_BACKTRACK_LIMIT_ERROR:
+ $error = 'pcre.backtrack_limit reached.';
+ break;
+ case PREG_RECURSION_LIMIT_ERROR:
+ $error = 'pcre.recursion_limit reached.';
+ break;
+ case PREG_BAD_UTF8_ERROR:
+ $error = 'Malformed UTF-8 data.';
+ break;
+ case PREG_BAD_UTF8_OFFSET_ERROR:
+ $error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.';
+ break;
+ default:
+ $error = 'Error.';
+ }
+
+ throw new ParseException($error);
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Trim the tag on top of the value.
+ *
+ * Prevent values such as `!foo {quz: bar}` to be considered as
+ * a mapping block.
+ */
+ private function trimTag(string $value): string
+ {
+ if ('!' === $value[0]) {
+ return ltrim(substr($value, 1, strcspn($value, " \r\n", 1)), ' ');
+ }
+
+ return $value;
+ }
+
+ private function getLineTag(string $value, int $flags, bool $nextLineCheck = true): ?string
+ {
+ if ('' === $value || '!' !== $value[0] || 1 !== self::preg_match('/^'.self::TAG_PATTERN.' *( +#.*)?$/', $value, $matches)) {
+ return null;
+ }
+
+ if ($nextLineCheck && !$this->isNextLineIndented()) {
+ return null;
+ }
+
+ $tag = substr($matches['tag'], 1);
+
+ // Built-in tags
+ if ($tag && '!' === $tag[0]) {
+ throw new ParseException(sprintf('The built-in tag "!%s" is not implemented.', $tag), $this->getRealCurrentLineNb() + 1, $value, $this->filename);
+ }
+
+ if (Yaml::PARSE_CUSTOM_TAGS & $flags) {
+ return $tag;
+ }
+
+ throw new ParseException(sprintf('Tags support is not enabled. You must use the flag `Yaml::PARSE_CUSTOM_TAGS` to use "%s".', $matches['tag']), $this->getRealCurrentLineNb() + 1, $value, $this->filename);
+ }
+}
diff --git a/vendor/symfony/yaml/README.md b/vendor/symfony/yaml/README.md
new file mode 100644
index 0000000..0d32488
--- /dev/null
+++ b/vendor/symfony/yaml/README.md
@@ -0,0 +1,13 @@
+Yaml Component
+==============
+
+The Yaml component loads and dumps YAML files.
+
+Resources
+---------
+
+ * [Documentation](https://symfony.com/doc/current/components/yaml/index.html)
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/symfony/issues) and
+ [send Pull Requests](https://github.com/symfony/symfony/pulls)
+ in the [main Symfony repository](https://github.com/symfony/symfony)
diff --git a/vendor/symfony/yaml/Tag/TaggedValue.php b/vendor/symfony/yaml/Tag/TaggedValue.php
new file mode 100644
index 0000000..4ea3406
--- /dev/null
+++ b/vendor/symfony/yaml/Tag/TaggedValue.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Tag;
+
+/**
+ * @author Nicolas Grekas <p@tchwork.com>
+ * @author Guilhem N. <egetick@gmail.com>
+ */
+final class TaggedValue
+{
+ private $tag;
+ private $value;
+
+ public function __construct(string $tag, $value)
+ {
+ $this->tag = $tag;
+ $this->value = $value;
+ }
+
+ public function getTag(): string
+ {
+ return $this->tag;
+ }
+
+ public function getValue()
+ {
+ return $this->value;
+ }
+}
diff --git a/vendor/symfony/yaml/Tests/Command/LintCommandTest.php b/vendor/symfony/yaml/Tests/Command/LintCommandTest.php
new file mode 100644
index 0000000..a5baf23
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Command/LintCommandTest.php
@@ -0,0 +1,139 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Tests\Command;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Tester\CommandTester;
+use Symfony\Component\Yaml\Command\LintCommand;
+
+/**
+ * Tests the YamlLintCommand.
+ *
+ * @author Robin Chalas <robin.chalas@gmail.com>
+ */
+class LintCommandTest extends TestCase
+{
+ private $files;
+
+ public function testLintCorrectFile()
+ {
+ $tester = $this->createCommandTester();
+ $filename = $this->createFile('foo: bar');
+
+ $ret = $tester->execute(array('filename' => $filename), array('verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false));
+
+ $this->assertEquals(0, $ret, 'Returns 0 in case of success');
+ $this->assertRegExp('/^\/\/ OK in /', trim($tester->getDisplay()));
+ }
+
+ public function testLintIncorrectFile()
+ {
+ $incorrectContent = '
+foo:
+bar';
+ $tester = $this->createCommandTester();
+ $filename = $this->createFile($incorrectContent);
+
+ $ret = $tester->execute(array('filename' => $filename), array('decorated' => false));
+
+ $this->assertEquals(1, $ret, 'Returns 1 in case of error');
+ $this->assertContains('Unable to parse at line 3 (near "bar").', trim($tester->getDisplay()));
+ }
+
+ public function testConstantAsKey()
+ {
+ $yaml = <<<YAML
+!php/const 'Symfony\Component\Yaml\Tests\Command\Foo::TEST': bar
+YAML;
+ $ret = $this->createCommandTester()->execute(array('filename' => $this->createFile($yaml)), array('verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false));
+ $this->assertSame(0, $ret, 'lint:yaml exits with code 0 in case of success');
+ }
+
+ public function testCustomTags()
+ {
+ $yaml = <<<YAML
+foo: !my_tag {foo: bar}
+YAML;
+ $ret = $this->createCommandTester()->execute(array('filename' => $this->createFile($yaml), '--parse-tags' => true), array('verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false));
+ $this->assertSame(0, $ret, 'lint:yaml exits with code 0 in case of success');
+ }
+
+ public function testCustomTagsError()
+ {
+ $yaml = <<<YAML
+foo: !my_tag {foo: bar}
+YAML;
+ $ret = $this->createCommandTester()->execute(array('filename' => $this->createFile($yaml)), array('verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false));
+ $this->assertSame(1, $ret, 'lint:yaml exits with code 1 in case of error');
+ }
+
+ /**
+ * @expectedException \RuntimeException
+ */
+ public function testLintFileNotReadable()
+ {
+ $tester = $this->createCommandTester();
+ $filename = $this->createFile('');
+ unlink($filename);
+
+ $ret = $tester->execute(array('filename' => $filename), array('decorated' => false));
+ }
+
+ /**
+ * @return string Path to the new file
+ */
+ private function createFile($content)
+ {
+ $filename = tempnam(sys_get_temp_dir().'/framework-yml-lint-test', 'sf-');
+ file_put_contents($filename, $content);
+
+ $this->files[] = $filename;
+
+ return $filename;
+ }
+
+ /**
+ * @return CommandTester
+ */
+ protected function createCommandTester()
+ {
+ $application = new Application();
+ $application->add(new LintCommand());
+ $command = $application->find('lint:yaml');
+
+ return new CommandTester($command);
+ }
+
+ protected function setUp()
+ {
+ $this->files = array();
+ @mkdir(sys_get_temp_dir().'/framework-yml-lint-test');
+ }
+
+ protected function tearDown()
+ {
+ foreach ($this->files as $file) {
+ if (file_exists($file)) {
+ unlink($file);
+ }
+ }
+
+ rmdir(sys_get_temp_dir().'/framework-yml-lint-test');
+ }
+}
+
+class Foo
+{
+ const TEST = 'foo';
+}
diff --git a/vendor/symfony/yaml/Tests/DumperTest.php b/vendor/symfony/yaml/Tests/DumperTest.php
new file mode 100644
index 0000000..85dfd5b
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/DumperTest.php
@@ -0,0 +1,429 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Yaml\Dumper;
+use Symfony\Component\Yaml\Parser;
+use Symfony\Component\Yaml\Yaml;
+
+class DumperTest extends TestCase
+{
+ protected $parser;
+ protected $dumper;
+ protected $path;
+
+ protected $array = array(
+ '' => 'bar',
+ 'foo' => '#bar',
+ 'foo\'bar' => array(),
+ 'bar' => array(1, 'foo'),
+ 'foobar' => array(
+ 'foo' => 'bar',
+ 'bar' => array(1, 'foo'),
+ 'foobar' => array(
+ 'foo' => 'bar',
+ 'bar' => array(1, 'foo'),
+ ),
+ ),
+ );
+
+ protected function setUp()
+ {
+ $this->parser = new Parser();
+ $this->dumper = new Dumper();
+ $this->path = __DIR__.'/Fixtures';
+ }
+
+ protected function tearDown()
+ {
+ $this->parser = null;
+ $this->dumper = null;
+ $this->path = null;
+ $this->array = null;
+ }
+
+ public function testIndentationInConstructor()
+ {
+ $dumper = new Dumper(7);
+ $expected = <<<'EOF'
+'': bar
+foo: '#bar'
+'foo''bar': { }
+bar:
+ - 1
+ - foo
+foobar:
+ foo: bar
+ bar:
+ - 1
+ - foo
+ foobar:
+ foo: bar
+ bar:
+ - 1
+ - foo
+
+EOF;
+ $this->assertEquals($expected, $dumper->dump($this->array, 4, 0));
+ }
+
+ public function testSpecifications()
+ {
+ $files = $this->parser->parse(file_get_contents($this->path.'/index.yml'));
+ foreach ($files as $file) {
+ $yamls = file_get_contents($this->path.'/'.$file.'.yml');
+
+ // split YAMLs documents
+ foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) {
+ if (!$yaml) {
+ continue;
+ }
+
+ $test = $this->parser->parse($yaml);
+ if (isset($test['dump_skip']) && $test['dump_skip']) {
+ continue;
+ } elseif (isset($test['todo']) && $test['todo']) {
+ // TODO
+ } else {
+ eval('$expected = '.trim($test['php']).';');
+ $this->assertSame($expected, $this->parser->parse($this->dumper->dump($expected, 10)), $test['test']);
+ }
+ }
+ }
+ }
+
+ public function testInlineLevel()
+ {
+ $expected = <<<'EOF'
+{ '': bar, foo: '#bar', 'foo''bar': { }, bar: [1, foo], foobar: { foo: bar, bar: [1, foo], foobar: { foo: bar, bar: [1, foo] } } }
+EOF;
+ $this->assertEquals($expected, $this->dumper->dump($this->array, -10), '->dump() takes an inline level argument');
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 0), '->dump() takes an inline level argument');
+
+ $expected = <<<'EOF'
+'': bar
+foo: '#bar'
+'foo''bar': { }
+bar: [1, foo]
+foobar: { foo: bar, bar: [1, foo], foobar: { foo: bar, bar: [1, foo] } }
+
+EOF;
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 1), '->dump() takes an inline level argument');
+
+ $expected = <<<'EOF'
+'': bar
+foo: '#bar'
+'foo''bar': { }
+bar:
+ - 1
+ - foo
+foobar:
+ foo: bar
+ bar: [1, foo]
+ foobar: { foo: bar, bar: [1, foo] }
+
+EOF;
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 2), '->dump() takes an inline level argument');
+
+ $expected = <<<'EOF'
+'': bar
+foo: '#bar'
+'foo''bar': { }
+bar:
+ - 1
+ - foo
+foobar:
+ foo: bar
+ bar:
+ - 1
+ - foo
+ foobar:
+ foo: bar
+ bar: [1, foo]
+
+EOF;
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 3), '->dump() takes an inline level argument');
+
+ $expected = <<<'EOF'
+'': bar
+foo: '#bar'
+'foo''bar': { }
+bar:
+ - 1
+ - foo
+foobar:
+ foo: bar
+ bar:
+ - 1
+ - foo
+ foobar:
+ foo: bar
+ bar:
+ - 1
+ - foo
+
+EOF;
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 4), '->dump() takes an inline level argument');
+ $this->assertEquals($expected, $this->dumper->dump($this->array, 10), '->dump() takes an inline level argument');
+ }
+
+ public function testObjectSupportEnabled()
+ {
+ $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, Yaml::DUMP_OBJECT);
+
+ $this->assertEquals('{ foo: !php/object \'O:30:"Symfony\Component\Yaml\Tests\A":1:{s:1:"a";s:3:"foo";}\', bar: 1 }', $dump, '->dump() is able to dump objects');
+ }
+
+ public function testObjectSupportDisabledButNoExceptions()
+ {
+ $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1));
+
+ $this->assertEquals('{ foo: null, bar: 1 }', $dump, '->dump() does not dump objects when disabled');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\DumpException
+ */
+ public function testObjectSupportDisabledWithExceptions()
+ {
+ $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE);
+ }
+
+ /**
+ * @dataProvider getEscapeSequences
+ */
+ public function testEscapedEscapeSequencesInQuotedScalar($input, $expected)
+ {
+ $this->assertEquals($expected, $this->dumper->dump($input));
+ }
+
+ public function getEscapeSequences()
+ {
+ return array(
+ 'empty string' => array('', "''"),
+ 'null' => array("\x0", '"\\0"'),
+ 'bell' => array("\x7", '"\\a"'),
+ 'backspace' => array("\x8", '"\\b"'),
+ 'horizontal-tab' => array("\t", '"\\t"'),
+ 'line-feed' => array("\n", '"\\n"'),
+ 'vertical-tab' => array("\v", '"\\v"'),
+ 'form-feed' => array("\xC", '"\\f"'),
+ 'carriage-return' => array("\r", '"\\r"'),
+ 'escape' => array("\x1B", '"\\e"'),
+ 'space' => array(' ', "' '"),
+ 'double-quote' => array('"', "'\"'"),
+ 'slash' => array('/', '/'),
+ 'backslash' => array('\\', '\\'),
+ 'next-line' => array("\xC2\x85", '"\\N"'),
+ 'non-breaking-space' => array("\xc2\xa0", '"\\_"'),
+ 'line-separator' => array("\xE2\x80\xA8", '"\\L"'),
+ 'paragraph-separator' => array("\xE2\x80\xA9", '"\\P"'),
+ 'colon' => array(':', "':'"),
+ );
+ }
+
+ public function testBinaryDataIsDumpedBase64Encoded()
+ {
+ $binaryData = file_get_contents(__DIR__.'/Fixtures/arrow.gif');
+ $expected = '{ data: !!binary '.base64_encode($binaryData).' }';
+
+ $this->assertSame($expected, $this->dumper->dump(array('data' => $binaryData)));
+ }
+
+ public function testNonUtf8DataIsDumpedBase64Encoded()
+ {
+ // "für" (ISO-8859-1 encoded)
+ $this->assertSame('!!binary ZsM/cg==', $this->dumper->dump("f\xc3\x3fr"));
+ }
+
+ /**
+ * @dataProvider objectAsMapProvider
+ */
+ public function testDumpObjectAsMap($object, $expected)
+ {
+ $yaml = $this->dumper->dump($object, 0, 0, Yaml::DUMP_OBJECT_AS_MAP);
+
+ $this->assertEquals($expected, Yaml::parse($yaml, Yaml::PARSE_OBJECT_FOR_MAP));
+ }
+
+ public function objectAsMapProvider()
+ {
+ $tests = array();
+
+ $bar = new \stdClass();
+ $bar->class = 'classBar';
+ $bar->args = array('bar');
+ $zar = new \stdClass();
+ $foo = new \stdClass();
+ $foo->bar = $bar;
+ $foo->zar = $zar;
+ $object = new \stdClass();
+ $object->foo = $foo;
+ $tests['stdClass'] = array($object, $object);
+
+ $arrayObject = new \ArrayObject();
+ $arrayObject['foo'] = 'bar';
+ $arrayObject['baz'] = 'foobar';
+ $parsedArrayObject = new \stdClass();
+ $parsedArrayObject->foo = 'bar';
+ $parsedArrayObject->baz = 'foobar';
+ $tests['ArrayObject'] = array($arrayObject, $parsedArrayObject);
+
+ $a = new A();
+ $tests['arbitrary-object'] = array($a, null);
+
+ return $tests;
+ }
+
+ public function testDumpingArrayObjectInstancesRespectsInlineLevel()
+ {
+ $deep = new \ArrayObject(array('deep1' => 'd', 'deep2' => 'e'));
+ $inner = new \ArrayObject(array('inner1' => 'b', 'inner2' => 'c', 'inner3' => $deep));
+ $outer = new \ArrayObject(array('outer1' => 'a', 'outer2' => $inner));
+
+ $yaml = $this->dumper->dump($outer, 2, 0, Yaml::DUMP_OBJECT_AS_MAP);
+
+ $expected = <<<YAML
+outer1: a
+outer2:
+ inner1: b
+ inner2: c
+ inner3: { deep1: d, deep2: e }
+
+YAML;
+ $this->assertSame($expected, $yaml);
+ }
+
+ public function testDumpingArrayObjectInstancesWithNumericKeysInlined()
+ {
+ $deep = new \ArrayObject(array('d', 'e'));
+ $inner = new \ArrayObject(array('b', 'c', $deep));
+ $outer = new \ArrayObject(array('a', $inner));
+
+ $yaml = $this->dumper->dump($outer, 0, 0, Yaml::DUMP_OBJECT_AS_MAP);
+ $expected = <<<YAML
+{ 0: a, 1: { 0: b, 1: c, 2: { 0: d, 1: e } } }
+YAML;
+ $this->assertSame($expected, $yaml);
+ }
+
+ public function testDumpingArrayObjectInstancesWithNumericKeysRespectsInlineLevel()
+ {
+ $deep = new \ArrayObject(array('d', 'e'));
+ $inner = new \ArrayObject(array('b', 'c', $deep));
+ $outer = new \ArrayObject(array('a', $inner));
+ $yaml = $this->dumper->dump($outer, 2, 0, Yaml::DUMP_OBJECT_AS_MAP);
+ $expected = <<<YAML
+0: a
+1:
+ 0: b
+ 1: c
+ 2: { 0: d, 1: e }
+
+YAML;
+ $this->assertEquals($expected, $yaml);
+ }
+
+ public function testDumpEmptyArrayObjectInstanceAsMap()
+ {
+ $this->assertSame('{ }', $this->dumper->dump(new \ArrayObject(), 2, 0, Yaml::DUMP_OBJECT_AS_MAP));
+ }
+
+ public function testDumpEmptyStdClassInstanceAsMap()
+ {
+ $this->assertSame('{ }', $this->dumper->dump(new \stdClass(), 2, 0, Yaml::DUMP_OBJECT_AS_MAP));
+ }
+
+ public function testDumpingStdClassInstancesRespectsInlineLevel()
+ {
+ $deep = new \stdClass();
+ $deep->deep1 = 'd';
+ $deep->deep2 = 'e';
+
+ $inner = new \stdClass();
+ $inner->inner1 = 'b';
+ $inner->inner2 = 'c';
+ $inner->inner3 = $deep;
+
+ $outer = new \stdClass();
+ $outer->outer1 = 'a';
+ $outer->outer2 = $inner;
+
+ $yaml = $this->dumper->dump($outer, 2, 0, Yaml::DUMP_OBJECT_AS_MAP);
+
+ $expected = <<<YAML
+outer1: a
+outer2:
+ inner1: b
+ inner2: c
+ inner3: { deep1: d, deep2: e }
+
+YAML;
+ $this->assertSame($expected, $yaml);
+ }
+
+ public function testDumpMultiLineStringAsScalarBlock()
+ {
+ $data = array(
+ 'data' => array(
+ 'single_line' => 'foo bar baz',
+ 'multi_line' => "foo\nline with trailing spaces:\n \nbar\ninteger like line:\n123456789\nempty line:\n\nbaz",
+ 'multi_line_with_carriage_return' => "foo\nbar\r\nbaz",
+ 'nested_inlined_multi_line_string' => array(
+ 'inlined_multi_line' => "foo\nbar\r\nempty line:\n\nbaz",
+ ),
+ ),
+ );
+
+ $this->assertSame(file_get_contents(__DIR__.'/Fixtures/multiple_lines_as_literal_block.yml'), $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK));
+ }
+
+ public function testDumpMultiLineStringAsScalarBlockWhenFirstLineHasLeadingSpace()
+ {
+ $data = array(
+ 'data' => array(
+ 'multi_line' => " the first line has leading spaces\nThe second line does not.",
+ ),
+ );
+
+ $this->assertSame(file_get_contents(__DIR__.'/Fixtures/multiple_lines_as_literal_block_leading_space_in_first_line.yml'), $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK));
+ }
+
+ public function testCarriageReturnIsMaintainedWhenDumpingAsMultiLineLiteralBlock()
+ {
+ $this->assertSame("- \"a\\r\\nb\\nc\"\n", $this->dumper->dump(array("a\r\nb\nc"), 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK));
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The indentation must be greater than zero
+ */
+ public function testZeroIndentationThrowsException()
+ {
+ new Dumper(0);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The indentation must be greater than zero
+ */
+ public function testNegativeIndentationThrowsException()
+ {
+ new Dumper(-4);
+ }
+}
+
+class A
+{
+ public $a = 'foo';
+}
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsAnchorAlias.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsAnchorAlias.yml
new file mode 100644
index 0000000..5f9c942
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsAnchorAlias.yml
@@ -0,0 +1,31 @@
+--- %YAML:1.0
+test: Simple Alias Example
+brief: >
+ If you need to refer to the same item of data twice,
+ you can give that item an alias. The alias is a plain
+ string, starting with an ampersand. The item may then
+ be referred to by the alias throughout your document
+ by using an asterisk before the name of the alias.
+ This is called an anchor.
+yaml: |
+ - &showell Steve
+ - Clark
+ - Brian
+ - Oren
+ - *showell
+php: |
+ array('Steve', 'Clark', 'Brian', 'Oren', 'Steve')
+
+---
+test: Alias of a Mapping
+brief: >
+ An alias can be used on any item of data, including
+ sequences, mappings, and other complex data types.
+yaml: |
+ - &hello
+ Meat: pork
+ Starch: potato
+ - banana
+ - *hello
+php: |
+ array(array('Meat'=>'pork', 'Starch'=>'potato'), 'banana', array('Meat'=>'pork', 'Starch'=>'potato'))
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsBasicTests.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsBasicTests.yml
new file mode 100644
index 0000000..dfd9302
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsBasicTests.yml
@@ -0,0 +1,202 @@
+--- %YAML:1.0
+test: Simple Sequence
+brief: |
+ You can specify a list in YAML by placing each
+ member of the list on a new line with an opening
+ dash. These lists are called sequences.
+yaml: |
+ - apple
+ - banana
+ - carrot
+php: |
+ array('apple', 'banana', 'carrot')
+---
+test: Sequence With Item Being Null In The Middle
+brief: |
+ You can specify a list in YAML by placing each
+ member of the list on a new line with an opening
+ dash. These lists are called sequences.
+yaml: |
+ - apple
+ -
+ - carrot
+php: |
+ array('apple', null, 'carrot')
+---
+test: Sequence With Last Item Being Null
+brief: |
+ You can specify a list in YAML by placing each
+ member of the list on a new line with an opening
+ dash. These lists are called sequences.
+yaml: |
+ - apple
+ - banana
+ -
+php: |
+ array('apple', 'banana', null)
+---
+test: Nested Sequences
+brief: |
+ You can include a sequence within another
+ sequence by giving the sequence an empty
+ dash, followed by an indented list.
+yaml: |
+ -
+ - foo
+ - bar
+ - baz
+php: |
+ array(array('foo', 'bar', 'baz'))
+---
+test: Mixed Sequences
+brief: |
+ Sequences can contain any YAML data,
+ including strings and other sequences.
+yaml: |
+ - apple
+ -
+ - foo
+ - bar
+ - x123
+ - banana
+ - carrot
+php: |
+ array('apple', array('foo', 'bar', 'x123'), 'banana', 'carrot')
+---
+test: Deeply Nested Sequences
+brief: |
+ Sequences can be nested even deeper, with each
+ level of indentation representing a level of
+ depth.
+yaml: |
+ -
+ -
+ - uno
+ - dos
+php: |
+ array(array(array('uno', 'dos')))
+---
+test: Simple Mapping
+brief: |
+ You can add a keyed list (also known as a dictionary or
+ hash) to your document by placing each member of the
+ list on a new line, with a colon separating the key
+ from its value. In YAML, this type of list is called
+ a mapping.
+yaml: |
+ foo: whatever
+ bar: stuff
+php: |
+ array('foo' => 'whatever', 'bar' => 'stuff')
+---
+test: Sequence in a Mapping
+brief: |
+ A value in a mapping can be a sequence.
+yaml: |
+ foo: whatever
+ bar:
+ - uno
+ - dos
+php: |
+ array('foo' => 'whatever', 'bar' => array('uno', 'dos'))
+---
+test: Nested Mappings
+brief: |
+ A value in a mapping can be another mapping.
+yaml: |
+ foo: whatever
+ bar:
+ fruit: apple
+ name: steve
+ sport: baseball
+php: |
+ array(
+ 'foo' => 'whatever',
+ 'bar' => array(
+ 'fruit' => 'apple',
+ 'name' => 'steve',
+ 'sport' => 'baseball'
+ )
+ )
+---
+test: Mixed Mapping
+brief: |
+ A mapping can contain any assortment
+ of mappings and sequences as values.
+yaml: |
+ foo: whatever
+ bar:
+ -
+ fruit: apple
+ name: steve
+ sport: baseball
+ - more
+ -
+ python: rocks
+ perl: papers
+ ruby: scissorses
+php: |
+ array(
+ 'foo' => 'whatever',
+ 'bar' => array(
+ array(
+ 'fruit' => 'apple',
+ 'name' => 'steve',
+ 'sport' => 'baseball'
+ ),
+ 'more',
+ array(
+ 'python' => 'rocks',
+ 'perl' => 'papers',
+ 'ruby' => 'scissorses'
+ )
+ )
+ )
+---
+test: Mapping-in-Sequence Shortcut
+todo: true
+brief: |
+ If you are adding a mapping to a sequence, you
+ can place the mapping on the same line as the
+ dash as a shortcut.
+yaml: |
+ - work on YAML.py:
+ - work on Store
+php: |
+ array(array('work on YAML.py' => array('work on Store')))
+---
+test: Sequence-in-Mapping Shortcut
+todo: true
+brief: |
+ The dash in a sequence counts as indentation, so
+ you can add a sequence inside of a mapping without
+ needing spaces as indentation.
+yaml: |
+ allow:
+ - 'localhost'
+ - '%.sourceforge.net'
+ - '%.freepan.org'
+php: |
+ array('allow' => array('localhost', '%.sourceforge.net', '%.freepan.org'))
+---
+todo: true
+test: Merge key
+brief: |
+ A merge key ('<<') can be used in a mapping to insert other mappings. If
+ the value associated with the merge key is a mapping, each of its key/value
+ pairs is inserted into the current mapping.
+yaml: |
+ mapping:
+ name: Joe
+ job: Accountant
+ <<:
+ age: 38
+php: |
+ array(
+ 'mapping' =>
+ array(
+ 'name' => 'Joe',
+ 'job' => 'Accountant',
+ 'age' => 38
+ )
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsBlockMapping.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsBlockMapping.yml
new file mode 100644
index 0000000..f7ca469
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsBlockMapping.yml
@@ -0,0 +1,51 @@
+---
+test: One Element Mapping
+brief: |
+ A mapping with one key/value pair
+yaml: |
+ foo: bar
+php: |
+ array('foo' => 'bar')
+---
+test: Multi Element Mapping
+brief: |
+ More than one key/value pair
+yaml: |
+ red: baron
+ white: walls
+ blue: berries
+php: |
+ array(
+ 'red' => 'baron',
+ 'white' => 'walls',
+ 'blue' => 'berries',
+ )
+---
+test: Values aligned
+brief: |
+ Often times human editors of documents will align the values even
+ though YAML emitters generally don't.
+yaml: |
+ red: baron
+ white: walls
+ blue: berries
+php: |
+ array(
+ 'red' => 'baron',
+ 'white' => 'walls',
+ 'blue' => 'berries',
+ )
+---
+test: Colons aligned
+brief: |
+ Spaces can come before the ': ' key/value separator.
+yaml: |
+ red : baron
+ white : walls
+ blue : berries
+php: |
+ array(
+ 'red' => 'baron',
+ 'white' => 'walls',
+ 'blue' => 'berries',
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsDocumentSeparator.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsDocumentSeparator.yml
new file mode 100644
index 0000000..d988102
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsDocumentSeparator.yml
@@ -0,0 +1,85 @@
+--- %YAML:1.0
+test: Trailing Document Separator
+todo: true
+brief: >
+ You can separate YAML documents
+ with a string of three dashes.
+yaml: |
+ - foo: 1
+ bar: 2
+ ---
+ more: stuff
+python: |
+ [
+ [ { 'foo': 1, 'bar': 2 } ],
+ { 'more': 'stuff' }
+ ]
+ruby: |
+ [ { 'foo' => 1, 'bar' => 2 } ]
+
+---
+test: Leading Document Separator
+todo: true
+brief: >
+ You can explicitly give an opening
+ document separator to your YAML stream.
+yaml: |
+ ---
+ - foo: 1
+ bar: 2
+ ---
+ more: stuff
+python: |
+ [
+ [ {'foo': 1, 'bar': 2}],
+ {'more': 'stuff'}
+ ]
+ruby: |
+ [ { 'foo' => 1, 'bar' => 2 } ]
+
+---
+test: YAML Header
+todo: true
+brief: >
+ The opening separator can contain directives
+ to the YAML parser, such as the version
+ number.
+yaml: |
+ --- %YAML:1.0
+ foo: 1
+ bar: 2
+php: |
+ array('foo' => 1, 'bar' => 2)
+documents: 1
+
+---
+test: Red Herring Document Separator
+brief: >
+ Separators included in blocks or strings
+ are treated as blocks or strings, as the
+ document separator should have no indentation
+ preceding it.
+yaml: |
+ foo: |
+ ---
+php: |
+ array('foo' => "---\n")
+
+---
+test: Multiple Document Separators in Block
+brief: >
+ This technique allows you to embed other YAML
+ documents within literal blocks.
+yaml: |
+ foo: |
+ ---
+ foo: bar
+ ---
+ yo: baz
+ bar: |
+ fooness
+php: |
+ array(
+ 'foo' => "---\nfoo: bar\n---\nyo: baz\n",
+ 'bar' => "fooness\n"
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsErrorTests.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsErrorTests.yml
new file mode 100644
index 0000000..e8506fc
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsErrorTests.yml
@@ -0,0 +1,25 @@
+---
+test: Missing value for hash item
+todo: true
+brief: |
+ Third item in this hash doesn't have a value
+yaml: |
+ okay: value
+ also okay: ~
+ causes error because no value specified
+ last key: value okay here too
+python-error: causes error because no value specified
+
+---
+test: Not indenting enough
+brief: |
+ There was a bug in PyYaml where it was off by one
+ in the indentation check. It was allowing the YAML
+ below.
+# This is actually valid YAML now. Someone should tell showell.
+yaml: |
+ foo:
+ firstline: 1
+ secondline: 2
+php: |
+ array('foo' => null, 'firstline' => 1, 'secondline' => 2)
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsFlowCollections.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsFlowCollections.yml
new file mode 100644
index 0000000..03090e4
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsFlowCollections.yml
@@ -0,0 +1,60 @@
+---
+test: Simple Inline Array
+brief: >
+ Sequences can be contained on a
+ single line, using the inline syntax.
+ Separate each entry with commas and
+ enclose in square brackets.
+yaml: |
+ seq: [ a, b, c ]
+php: |
+ array('seq' => array('a', 'b', 'c'))
+---
+test: Simple Inline Hash
+brief: >
+ Mapping can also be contained on
+ a single line, using the inline
+ syntax. Each key-value pair is
+ separated by a colon, with a comma
+ between each entry in the mapping.
+ Enclose with curly braces.
+yaml: |
+ hash: { name: Steve, foo: bar }
+php: |
+ array('hash' => array('name' => 'Steve', 'foo' => 'bar'))
+---
+test: Multi-line Inline Collections
+todo: true
+brief: >
+ Both inline sequences and inline mappings
+ can span multiple lines, provided that you
+ indent the additional lines.
+yaml: |
+ languages: [ Ruby,
+ Perl,
+ Python ]
+ websites: { YAML: yaml.org,
+ Ruby: ruby-lang.org,
+ Python: python.org,
+ Perl: use.perl.org }
+php: |
+ array(
+ 'languages' => array('Ruby', 'Perl', 'Python'),
+ 'websites' => array(
+ 'YAML' => 'yaml.org',
+ 'Ruby' => 'ruby-lang.org',
+ 'Python' => 'python.org',
+ 'Perl' => 'use.perl.org'
+ )
+ )
+---
+test: Commas in Values (not in the spec!)
+todo: true
+brief: >
+ List items in collections are delimited by commas, but
+ there must be a space after each comma. This allows you
+ to add numbers without quoting.
+yaml: |
+ attendances: [ 45,123, 70,000, 17,222 ]
+php: |
+ array('attendances' => array(45123, 70000, 17222))
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsFoldedScalars.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsFoldedScalars.yml
new file mode 100644
index 0000000..a14735a
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsFoldedScalars.yml
@@ -0,0 +1,176 @@
+--- %YAML:1.0
+test: Single ending newline
+brief: >
+ A pipe character, followed by an indented
+ block of text is treated as a literal
+ block, in which newlines are preserved
+ throughout the block, including the final
+ newline.
+yaml: |
+ ---
+ this: |
+ Foo
+ Bar
+php: |
+ array('this' => "Foo\nBar\n")
+---
+test: The '+' indicator
+brief: >
+ The '+' indicator says to keep newlines at the end of text
+ blocks.
+yaml: |
+ normal: |
+ extra new lines not kept
+
+ preserving: |+
+ extra new lines are kept
+
+
+ dummy: value
+php: |
+ array(
+ 'normal' => "extra new lines not kept\n",
+ 'preserving' => "extra new lines are kept\n\n\n",
+ 'dummy' => 'value'
+ )
+---
+test: Three trailing newlines in literals
+brief: >
+ To give you more control over how space
+ is preserved in text blocks, YAML has
+ the keep '+' and chomp '-' indicators.
+ The keep indicator will preserve all
+ ending newlines, while the chomp indicator
+ will strip all ending newlines.
+yaml: |
+ clipped: |
+ This has one newline.
+
+
+
+ same as "clipped" above: "This has one newline.\n"
+
+ stripped: |-
+ This has no newline.
+
+
+
+ same as "stripped" above: "This has no newline."
+
+ kept: |+
+ This has four newlines.
+
+
+
+ same as "kept" above: "This has four newlines.\n\n\n\n"
+php: |
+ array(
+ 'clipped' => "This has one newline.\n",
+ 'same as "clipped" above' => "This has one newline.\n",
+ 'stripped' => 'This has no newline.',
+ 'same as "stripped" above' => 'This has no newline.',
+ 'kept' => "This has four newlines.\n\n\n\n",
+ 'same as "kept" above' => "This has four newlines.\n\n\n\n"
+ )
+---
+test: Extra trailing newlines with spaces
+todo: true
+brief: >
+ Normally, only a single newline is kept
+ from the end of a literal block, unless the
+ keep '+' character is used in combination
+ with the pipe. The following example
+ will preserve all ending whitespace
+ since the last line of both literal blocks
+ contains spaces which extend past the indentation
+ level.
+yaml: |
+ ---
+ this: |
+ Foo
+
+
+ kept: |+
+ Foo
+
+
+php: |
+ array('this' => "Foo\n\n \n",
+ 'kept' => "Foo\n\n \n" )
+
+---
+test: Folded Block in a Sequence
+brief: >
+ A greater-then character, followed by an indented
+ block of text is treated as a folded block, in
+ which lines of text separated by a single newline
+ are concatenated as a single line.
+yaml: |
+ ---
+ - apple
+ - banana
+ - >
+ can't you see
+ the beauty of yaml?
+ hmm
+ - dog
+php: |
+ array(
+ 'apple',
+ 'banana',
+ "can't you see the beauty of yaml? hmm\n",
+ 'dog'
+ )
+---
+test: Folded Block as a Mapping Value
+brief: >
+ Both literal and folded blocks can be
+ used in collections, as values in a
+ sequence or a mapping.
+yaml: |
+ ---
+ quote: >
+ Mark McGwire's
+ year was crippled
+ by a knee injury.
+ source: espn
+php: |
+ array(
+ 'quote' => "Mark McGwire's year was crippled by a knee injury.\n",
+ 'source' => 'espn'
+ )
+---
+test: Three trailing newlines in folded blocks
+brief: >
+ The keep and chomp indicators can also
+ be applied to folded blocks.
+yaml: |
+ clipped: >
+ This has one newline.
+
+
+
+ same as "clipped" above: "This has one newline.\n"
+
+ stripped: >-
+ This has no newline.
+
+
+
+ same as "stripped" above: "This has no newline."
+
+ kept: >+
+ This has four newlines.
+
+
+
+ same as "kept" above: "This has four newlines.\n\n\n\n"
+php: |
+ array(
+ 'clipped' => "This has one newline.\n",
+ 'same as "clipped" above' => "This has one newline.\n",
+ 'stripped' => 'This has no newline.',
+ 'same as "stripped" above' => 'This has no newline.',
+ 'kept' => "This has four newlines.\n\n\n\n",
+ 'same as "kept" above' => "This has four newlines.\n\n\n\n"
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsNullsAndEmpties.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsNullsAndEmpties.yml
new file mode 100644
index 0000000..9a5300f
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsNullsAndEmpties.yml
@@ -0,0 +1,45 @@
+--- %YAML:1.0
+test: Empty Sequence
+brief: >
+ You can represent the empty sequence
+ with an empty inline sequence.
+yaml: |
+ empty: []
+php: |
+ array('empty' => array())
+---
+test: Empty Mapping
+brief: >
+ You can represent the empty mapping
+ with an empty inline mapping.
+yaml: |
+ empty: {}
+php: |
+ array('empty' => array())
+---
+test: Empty Sequence as Entire Document
+yaml: |
+ []
+php: |
+ array()
+---
+test: Empty Mapping as Entire Document
+yaml: |
+ {}
+php: |
+ array()
+---
+test: Null as Document
+yaml: |
+ ~
+php: |
+ null
+---
+test: Empty String
+brief: >
+ You can represent an empty string
+ with a pair of quotes.
+yaml: |
+ ''
+php: |
+ ''
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsSpecificationExamples.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsSpecificationExamples.yml
new file mode 100644
index 0000000..3ee795a
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsSpecificationExamples.yml
@@ -0,0 +1,1662 @@
+--- %YAML:1.0
+test: Sequence of scalars
+spec: 2.1
+yaml: |
+ - Mark McGwire
+ - Sammy Sosa
+ - Ken Griffey
+php: |
+ array('Mark McGwire', 'Sammy Sosa', 'Ken Griffey')
+---
+test: Mapping of scalars to scalars
+spec: 2.2
+yaml: |
+ hr: 65
+ avg: 0.278
+ rbi: 147
+php: |
+ array('hr' => 65, 'avg' => 0.278, 'rbi' => 147)
+---
+test: Mapping of scalars to sequences
+spec: 2.3
+yaml: |
+ american:
+ - Boston Red Sox
+ - Detroit Tigers
+ - New York Yankees
+ national:
+ - New York Mets
+ - Chicago Cubs
+ - Atlanta Braves
+php: |
+ array('american' =>
+ array( 'Boston Red Sox', 'Detroit Tigers',
+ 'New York Yankees' ),
+ 'national' =>
+ array( 'New York Mets', 'Chicago Cubs',
+ 'Atlanta Braves' )
+ )
+---
+test: Sequence of mappings
+spec: 2.4
+yaml: |
+ -
+ name: Mark McGwire
+ hr: 65
+ avg: 0.278
+ -
+ name: Sammy Sosa
+ hr: 63
+ avg: 0.288
+php: |
+ array(
+ array('name' => 'Mark McGwire', 'hr' => 65, 'avg' => 0.278),
+ array('name' => 'Sammy Sosa', 'hr' => 63, 'avg' => 0.288)
+ )
+---
+test: Legacy A5
+todo: true
+spec: legacy_A5
+yaml: |
+ ?
+ - New York Yankees
+ - Atlanta Braves
+ :
+ - 2001-07-02
+ - 2001-08-12
+ - 2001-08-14
+ ?
+ - Detroit Tigers
+ - Chicago Cubs
+ :
+ - 2001-07-23
+perl-busted: >
+ YAML.pm will be able to emulate this behavior soon. In this regard
+ it may be somewhat more correct than Python's native behaviour which
+ can only use tuples as mapping keys. PyYAML will also need to figure
+ out some clever way to roundtrip structured keys.
+python: |
+ [
+ {
+ ('New York Yankees', 'Atlanta Braves'):
+ [yaml.timestamp('2001-07-02'),
+ yaml.timestamp('2001-08-12'),
+ yaml.timestamp('2001-08-14')],
+ ('Detroit Tigers', 'Chicago Cubs'):
+ [yaml.timestamp('2001-07-23')]
+ }
+ ]
+ruby: |
+ {
+ [ 'New York Yankees', 'Atlanta Braves' ] =>
+ [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ],
+ [ 'Detroit Tigers', 'Chicago Cubs' ] =>
+ [ Date.new( 2001, 7, 23 ) ]
+ }
+syck: |
+ struct test_node seq1[] = {
+ { T_STR, 0, "New York Yankees" },
+ { T_STR, 0, "Atlanta Braves" },
+ end_node
+ };
+ struct test_node seq2[] = {
+ { T_STR, 0, "2001-07-02" },
+ { T_STR, 0, "2001-08-12" },
+ { T_STR, 0, "2001-08-14" },
+ end_node
+ };
+ struct test_node seq3[] = {
+ { T_STR, 0, "Detroit Tigers" },
+ { T_STR, 0, "Chicago Cubs" },
+ end_node
+ };
+ struct test_node seq4[] = {
+ { T_STR, 0, "2001-07-23" },
+ end_node
+ };
+ struct test_node map[] = {
+ { T_SEQ, 0, 0, seq1 },
+ { T_SEQ, 0, 0, seq2 },
+ { T_SEQ, 0, 0, seq3 },
+ { T_SEQ, 0, 0, seq4 },
+ end_node
+ };
+ struct test_node stream[] = {
+ { T_MAP, 0, 0, map },
+ end_node
+ };
+
+---
+test: Sequence of sequences
+spec: 2.5
+yaml: |
+ - [ name , hr , avg ]
+ - [ Mark McGwire , 65 , 0.278 ]
+ - [ Sammy Sosa , 63 , 0.288 ]
+php: |
+ array(
+ array( 'name', 'hr', 'avg' ),
+ array( 'Mark McGwire', 65, 0.278 ),
+ array( 'Sammy Sosa', 63, 0.288 )
+ )
+---
+test: Mapping of mappings
+todo: true
+spec: 2.6
+yaml: |
+ Mark McGwire: {hr: 65, avg: 0.278}
+ Sammy Sosa: {
+ hr: 63,
+ avg: 0.288
+ }
+php: |
+ array(
+ 'Mark McGwire' =>
+ array( 'hr' => 65, 'avg' => 0.278 ),
+ 'Sammy Sosa' =>
+ array( 'hr' => 63, 'avg' => 0.288 )
+ )
+---
+test: Two documents in a stream each with a leading comment
+todo: true
+spec: 2.7
+yaml: |
+ # Ranking of 1998 home runs
+ ---
+ - Mark McGwire
+ - Sammy Sosa
+ - Ken Griffey
+
+ # Team ranking
+ ---
+ - Chicago Cubs
+ - St Louis Cardinals
+ruby: |
+ y = YAML::Stream.new
+ y.add( [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ] )
+ y.add( [ 'Chicago Cubs', 'St Louis Cardinals' ] )
+documents: 2
+
+---
+test: Play by play feed from a game
+todo: true
+spec: 2.8
+yaml: |
+ ---
+ time: 20:03:20
+ player: Sammy Sosa
+ action: strike (miss)
+ ...
+ ---
+ time: 20:03:47
+ player: Sammy Sosa
+ action: grand slam
+ ...
+perl: |
+ [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ]
+documents: 2
+
+---
+test: Single document with two comments
+spec: 2.9
+yaml: |
+ hr: # 1998 hr ranking
+ - Mark McGwire
+ - Sammy Sosa
+ rbi:
+ # 1998 rbi ranking
+ - Sammy Sosa
+ - Ken Griffey
+php: |
+ array(
+ 'hr' => array( 'Mark McGwire', 'Sammy Sosa' ),
+ 'rbi' => array( 'Sammy Sosa', 'Ken Griffey' )
+ )
+---
+test: Node for Sammy Sosa appears twice in this document
+spec: 2.10
+yaml: |
+ ---
+ hr:
+ - Mark McGwire
+ # Following node labeled SS
+ - &SS Sammy Sosa
+ rbi:
+ - *SS # Subsequent occurrence
+ - Ken Griffey
+php: |
+ array(
+ 'hr' =>
+ array('Mark McGwire', 'Sammy Sosa'),
+ 'rbi' =>
+ array('Sammy Sosa', 'Ken Griffey')
+ )
+---
+test: Mapping between sequences
+todo: true
+spec: 2.11
+yaml: |
+ ? # PLAY SCHEDULE
+ - Detroit Tigers
+ - Chicago Cubs
+ :
+ - 2001-07-23
+
+ ? [ New York Yankees,
+ Atlanta Braves ]
+ : [ 2001-07-02, 2001-08-12,
+ 2001-08-14 ]
+ruby: |
+ {
+ [ 'Detroit Tigers', 'Chicago Cubs' ] => [ Date.new( 2001, 7, 23 ) ],
+ [ 'New York Yankees', 'Atlanta Braves' ] => [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ]
+ }
+syck: |
+ struct test_node seq1[] = {
+ { T_STR, 0, "New York Yankees" },
+ { T_STR, 0, "Atlanta Braves" },
+ end_node
+ };
+ struct test_node seq2[] = {
+ { T_STR, 0, "2001-07-02" },
+ { T_STR, 0, "2001-08-12" },
+ { T_STR, 0, "2001-08-14" },
+ end_node
+ };
+ struct test_node seq3[] = {
+ { T_STR, 0, "Detroit Tigers" },
+ { T_STR, 0, "Chicago Cubs" },
+ end_node
+ };
+ struct test_node seq4[] = {
+ { T_STR, 0, "2001-07-23" },
+ end_node
+ };
+ struct test_node map[] = {
+ { T_SEQ, 0, 0, seq3 },
+ { T_SEQ, 0, 0, seq4 },
+ { T_SEQ, 0, 0, seq1 },
+ { T_SEQ, 0, 0, seq2 },
+ end_node
+ };
+ struct test_node stream[] = {
+ { T_MAP, 0, 0, map },
+ end_node
+ };
+
+---
+test: Sequence key shortcut
+spec: 2.12
+yaml: |
+ ---
+ # products purchased
+ - item : Super Hoop
+ quantity: 1
+ - item : Basketball
+ quantity: 4
+ - item : Big Shoes
+ quantity: 1
+php: |
+ array (
+ array (
+ 'item' => 'Super Hoop',
+ 'quantity' => 1,
+ ),
+ array (
+ 'item' => 'Basketball',
+ 'quantity' => 4,
+ ),
+ array (
+ 'item' => 'Big Shoes',
+ 'quantity' => 1,
+ )
+ )
+perl: |
+ [
+ { item => 'Super Hoop', quantity => 1 },
+ { item => 'Basketball', quantity => 4 },
+ { item => 'Big Shoes', quantity => 1 }
+ ]
+
+ruby: |
+ [
+ { 'item' => 'Super Hoop', 'quantity' => 1 },
+ { 'item' => 'Basketball', 'quantity' => 4 },
+ { 'item' => 'Big Shoes', 'quantity' => 1 }
+ ]
+python: |
+ [
+ { 'item': 'Super Hoop', 'quantity': 1 },
+ { 'item': 'Basketball', 'quantity': 4 },
+ { 'item': 'Big Shoes', 'quantity': 1 }
+ ]
+syck: |
+ struct test_node map1[] = {
+ { T_STR, 0, "item" },
+ { T_STR, 0, "Super Hoop" },
+ { T_STR, 0, "quantity" },
+ { T_STR, 0, "1" },
+ end_node
+ };
+ struct test_node map2[] = {
+ { T_STR, 0, "item" },
+ { T_STR, 0, "Basketball" },
+ { T_STR, 0, "quantity" },
+ { T_STR, 0, "4" },
+ end_node
+ };
+ struct test_node map3[] = {
+ { T_STR, 0, "item" },
+ { T_STR, 0, "Big Shoes" },
+ { T_STR, 0, "quantity" },
+ { T_STR, 0, "1" },
+ end_node
+ };
+ struct test_node seq[] = {
+ { T_MAP, 0, 0, map1 },
+ { T_MAP, 0, 0, map2 },
+ { T_MAP, 0, 0, map3 },
+ end_node
+ };
+ struct test_node stream[] = {
+ { T_SEQ, 0, 0, seq },
+ end_node
+ };
+
+
+---
+test: Literal perserves newlines
+todo: true
+spec: 2.13
+yaml: |
+ # ASCII Art
+ --- |
+ \//||\/||
+ // || ||_
+perl: |
+ "\\//||\\/||\n// || ||_\n"
+ruby: |
+ "\\//||\\/||\n// || ||_\n"
+python: |
+ [
+ flushLeft(
+ """
+ \//||\/||
+ // || ||_
+ """
+ )
+ ]
+syck: |
+ struct test_node stream[] = {
+ { T_STR, 0, "\\//||\\/||\n// || ||_\n" },
+ end_node
+ };
+
+---
+test: Folded treats newlines as a space
+todo: true
+spec: 2.14
+yaml: |
+ ---
+ Mark McGwire's
+ year was crippled
+ by a knee injury.
+perl: |
+ "Mark McGwire's year was crippled by a knee injury."
+ruby: |
+ "Mark McGwire's year was crippled by a knee injury."
+python: |
+ [ "Mark McGwire's year was crippled by a knee injury." ]
+syck: |
+ struct test_node stream[] = {
+ { T_STR, 0, "Mark McGwire's year was crippled by a knee injury." },
+ end_node
+ };
+
+---
+test: Newlines preserved for indented and blank lines
+todo: true
+spec: 2.15
+yaml: |
+ --- >
+ Sammy Sosa completed another
+ fine season with great stats.
+
+ 63 Home Runs
+ 0.288 Batting Average
+
+ What a year!
+perl: |
+ "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n"
+ruby: |
+ "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n"
+python: |
+ [
+ flushLeft(
+ """
+ Sammy Sosa completed another fine season with great stats.
+
+ 63 Home Runs
+ 0.288 Batting Average
+
+ What a year!
+ """
+ )
+ ]
+syck: |
+ struct test_node stream[] = {
+ { T_STR, 0, "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n" },
+ end_node
+ };
+
+
+---
+test: Indentation determines scope
+spec: 2.16
+yaml: |
+ name: Mark McGwire
+ accomplishment: >
+ Mark set a major league
+ home run record in 1998.
+ stats: |
+ 65 Home Runs
+ 0.278 Batting Average
+php: |
+ array(
+ 'name' => 'Mark McGwire',
+ 'accomplishment' => "Mark set a major league home run record in 1998.\n",
+ 'stats' => "65 Home Runs\n0.278 Batting Average\n"
+ )
+---
+test: Quoted scalars
+todo: true
+spec: 2.17
+yaml: |
+ unicode: "Sosa did fine.\u263A"
+ control: "\b1998\t1999\t2000\n"
+ hexesc: "\x0D\x0A is \r\n"
+
+ single: '"Howdy!" he cried.'
+ quoted: ' # not a ''comment''.'
+ tie-fighter: '|\-*-/|'
+ruby: |
+ {
+ "tie-fighter" => "|\\-*-/|",
+ "control"=>"\0101998\t1999\t2000\n",
+ "unicode"=>"Sosa did fine." + ["263A".hex ].pack('U*'),
+ "quoted"=>" # not a 'comment'.",
+ "single"=>"\"Howdy!\" he cried.",
+ "hexesc"=>"\r\n is \r\n"
+ }
+---
+test: Multiline flow scalars
+todo: true
+spec: 2.18
+yaml: |
+ plain:
+ This unquoted scalar
+ spans many lines.
+
+ quoted: "So does this
+ quoted scalar.\n"
+ruby: |
+ {
+ 'plain' => 'This unquoted scalar spans many lines.',
+ 'quoted' => "So does this quoted scalar.\n"
+ }
+---
+test: Integers
+spec: 2.19
+yaml: |
+ canonical: 12345
+ octal: 014
+ hexadecimal: 0xC
+php: |
+ array(
+ 'canonical' => 12345,
+ 'octal' => 014,
+ 'hexadecimal' => 0xC
+ )
+---
+# FIX: spec shows parens around -inf and NaN
+test: Floating point
+spec: 2.20
+yaml: |
+ canonical: 1.23015e+3
+ exponential: 12.3015e+02
+ negative infinity: -.inf
+ not a number: .NaN
+ float as whole number: !!float 1
+php: |
+ array(
+ 'canonical' => 1230.15,
+ 'exponential' => 1230.15,
+ 'negative infinity' => log(0),
+ 'not a number' => -log(0),
+ 'float as whole number' => (float) 1
+ )
+---
+test: Timestamps
+todo: true
+spec: 2.22
+yaml: |
+ canonical: 2001-12-15T02:59:43.1Z
+ iso8601: 2001-12-14t21:59:43.10-05:00
+ spaced: 2001-12-14 21:59:43.10 -05:00
+ date: 2002-12-14 # Time is noon UTC
+php: |
+ array(
+ 'canonical' => YAML::mktime( 2001, 12, 15, 2, 59, 43, 0.10 ),
+ 'iso8601' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
+ 'spaced' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
+ 'date' => Date.new( 2002, 12, 14 )
+ )
+---
+test: legacy Timestamps test
+todo: true
+spec: legacy D4
+yaml: |
+ canonical: 2001-12-15T02:59:43.00Z
+ iso8601: 2001-02-28t21:59:43.00-05:00
+ spaced: 2001-12-14 21:59:43.00 -05:00
+ date: 2002-12-14
+php: |
+ array(
+ 'canonical' => Time::utc( 2001, 12, 15, 2, 59, 43, 0 ),
+ 'iso8601' => YAML::mktime( 2001, 2, 28, 21, 59, 43, 0, "-05:00" ),
+ 'spaced' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0, "-05:00" ),
+ 'date' => Date.new( 2002, 12, 14 )
+ )
+---
+test: Various explicit families
+todo: true
+spec: 2.23
+yaml: |
+ not-date: !!str 2002-04-28
+ picture: !binary |
+ R0lGODlhDAAMAIQAAP//9/X
+ 17unp5WZmZgAAAOfn515eXv
+ Pz7Y6OjuDg4J+fn5OTk6enp
+ 56enmleECcgggoBADs=
+
+ application specific tag: !!something |
+ The semantics of the tag
+ above may be different for
+ different documents.
+
+ruby-setup: |
+ YAML.add_private_type( "something" ) do |type, val|
+ "SOMETHING: #{val}"
+ end
+ruby: |
+ {
+ 'not-date' => '2002-04-28',
+ 'picture' => "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236i^\020' \202\n\001\000;",
+ 'application specific tag' => "SOMETHING: The semantics of the tag\nabove may be different for\ndifferent documents.\n"
+ }
+---
+test: Application specific family
+todo: true
+spec: 2.24
+yaml: |
+ # Establish a tag prefix
+ --- !clarkevans.com,2002/graph/^shape
+ # Use the prefix: shorthand for
+ # !clarkevans.com,2002/graph/circle
+ - !^circle
+ center: &ORIGIN {x: 73, 'y': 129}
+ radius: 7
+ - !^line # !clarkevans.com,2002/graph/line
+ start: *ORIGIN
+ finish: { x: 89, 'y': 102 }
+ - !^label
+ start: *ORIGIN
+ color: 0xFFEEBB
+ value: Pretty vector drawing.
+ruby-setup: |
+ YAML.add_domain_type( "clarkevans.com,2002", 'graph/shape' ) { |type, val|
+ if Array === val
+ val << "Shape Container"
+ val
+ else
+ raise YAML::Error, "Invalid graph of class #{ val.class }: " + val.inspect
+ end
+ }
+ one_shape_proc = Proc.new { |type, val|
+ scheme, domain, type = type.split( /:/, 3 )
+ if val.is_a? ::Hash
+ val['TYPE'] = "Shape: #{type}"
+ val
+ else
+ raise YAML::Error, "Invalid graph of class #{ val.class }: " + val.inspect
+ end
+ }
+ YAML.add_domain_type( "clarkevans.com,2002", 'graph/circle', &one_shape_proc )
+ YAML.add_domain_type( "clarkevans.com,2002", 'graph/line', &one_shape_proc )
+ YAML.add_domain_type( "clarkevans.com,2002", 'graph/label', &one_shape_proc )
+ruby: |
+ [
+ {
+ "radius" => 7,
+ "center"=>
+ {
+ "x" => 73,
+ "y" => 129
+ },
+ "TYPE" => "Shape: graph/circle"
+ }, {
+ "finish" =>
+ {
+ "x" => 89,
+ "y" => 102
+ },
+ "TYPE" => "Shape: graph/line",
+ "start" =>
+ {
+ "x" => 73,
+ "y" => 129
+ }
+ }, {
+ "TYPE" => "Shape: graph/label",
+ "value" => "Pretty vector drawing.",
+ "start" =>
+ {
+ "x" => 73,
+ "y" => 129
+ },
+ "color" => 16772795
+ },
+ "Shape Container"
+ ]
+# ---
+# test: Unordered set
+# spec: 2.25
+# yaml: |
+# # sets are represented as a
+# # mapping where each key is
+# # associated with the empty string
+# --- !set
+# ? Mark McGwire
+# ? Sammy Sosa
+# ? Ken Griff
+---
+test: Ordered mappings
+todo: true
+spec: 2.26
+yaml: |
+ # ordered maps are represented as
+ # a sequence of mappings, with
+ # each mapping having one key
+ --- !omap
+ - Mark McGwire: 65
+ - Sammy Sosa: 63
+ - Ken Griffy: 58
+ruby: |
+ YAML::Omap[
+ 'Mark McGwire', 65,
+ 'Sammy Sosa', 63,
+ 'Ken Griffy', 58
+ ]
+---
+test: Invoice
+dump_skip: true
+spec: 2.27
+yaml: |
+ --- !clarkevans.com,2002/^invoice
+ invoice: 34843
+ date : 2001-01-23
+ bill-to: &id001
+ given : Chris
+ family : Dumars
+ address:
+ lines: |
+ 458 Walkman Dr.
+ Suite #292
+ city : Royal Oak
+ state : MI
+ postal : 48046
+ ship-to: *id001
+ product:
+ -
+ sku : BL394D
+ quantity : 4
+ description : Basketball
+ price : 450.00
+ -
+ sku : BL4438H
+ quantity : 1
+ description : Super Hoop
+ price : 2392.00
+ tax : 251.42
+ total: 4443.52
+ comments: >
+ Late afternoon is best.
+ Backup contact is Nancy
+ Billsmer @ 338-4338.
+php: |
+ array(
+ 'invoice' => 34843, 'date' => gmmktime(0, 0, 0, 1, 23, 2001),
+ 'bill-to' =>
+ array( 'given' => 'Chris', 'family' => 'Dumars', 'address' => array( 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak', 'state' => 'MI', 'postal' => 48046 ) )
+ , 'ship-to' =>
+ array( 'given' => 'Chris', 'family' => 'Dumars', 'address' => array( 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak', 'state' => 'MI', 'postal' => 48046 ) )
+ , 'product' =>
+ array(
+ array( 'sku' => 'BL394D', 'quantity' => 4, 'description' => 'Basketball', 'price' => 450.00 ),
+ array( 'sku' => 'BL4438H', 'quantity' => 1, 'description' => 'Super Hoop', 'price' => 2392.00 )
+ ),
+ 'tax' => 251.42, 'total' => 4443.52,
+ 'comments' => "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.\n"
+ )
+---
+test: Log file
+todo: true
+spec: 2.28
+yaml: |
+ ---
+ Time: 2001-11-23 15:01:42 -05:00
+ User: ed
+ Warning: >
+ This is an error message
+ for the log file
+ ---
+ Time: 2001-11-23 15:02:31 -05:00
+ User: ed
+ Warning: >
+ A slightly different error
+ message.
+ ---
+ Date: 2001-11-23 15:03:17 -05:00
+ User: ed
+ Fatal: >
+ Unknown variable "bar"
+ Stack:
+ - file: TopClass.py
+ line: 23
+ code: |
+ x = MoreObject("345\n")
+ - file: MoreClass.py
+ line: 58
+ code: |-
+ foo = bar
+ruby: |
+ y = YAML::Stream.new
+ y.add( { 'Time' => YAML::mktime( 2001, 11, 23, 15, 01, 42, 00, "-05:00" ),
+ 'User' => 'ed', 'Warning' => "This is an error message for the log file\n" } )
+ y.add( { 'Time' => YAML::mktime( 2001, 11, 23, 15, 02, 31, 00, "-05:00" ),
+ 'User' => 'ed', 'Warning' => "A slightly different error message.\n" } )
+ y.add( { 'Date' => YAML::mktime( 2001, 11, 23, 15, 03, 17, 00, "-05:00" ),
+ 'User' => 'ed', 'Fatal' => "Unknown variable \"bar\"\n",
+ 'Stack' => [
+ { 'file' => 'TopClass.py', 'line' => 23, 'code' => "x = MoreObject(\"345\\n\")\n" },
+ { 'file' => 'MoreClass.py', 'line' => 58, 'code' => "foo = bar" } ] } )
+documents: 3
+
+---
+test: Throwaway comments
+yaml: |
+ ### These are four throwaway comment ###
+
+ ### lines (the second line is empty). ###
+ this: | # Comments may trail lines.
+ contains three lines of text.
+ The third one starts with a
+ # character. This isn't a comment.
+
+ # These are three throwaway comment
+ # lines (the first line is empty).
+php: |
+ array(
+ 'this' => "contains three lines of text.\nThe third one starts with a\n# character. This isn't a comment.\n"
+ )
+---
+test: Document with a single value
+todo: true
+yaml: |
+ --- >
+ This YAML stream contains a single text value.
+ The next stream is a log file - a sequence of
+ log entries. Adding an entry to the log is a
+ simple matter of appending it at the end.
+ruby: |
+ "This YAML stream contains a single text value. The next stream is a log file - a sequence of log entries. Adding an entry to the log is a simple matter of appending it at the end.\n"
+---
+test: Document stream
+todo: true
+yaml: |
+ ---
+ at: 2001-08-12 09:25:00.00 Z
+ type: GET
+ HTTP: '1.0'
+ url: '/index.html'
+ ---
+ at: 2001-08-12 09:25:10.00 Z
+ type: GET
+ HTTP: '1.0'
+ url: '/toc.html'
+ruby: |
+ y = YAML::Stream.new
+ y.add( {
+ 'at' => Time::utc( 2001, 8, 12, 9, 25, 00 ),
+ 'type' => 'GET',
+ 'HTTP' => '1.0',
+ 'url' => '/index.html'
+ } )
+ y.add( {
+ 'at' => Time::utc( 2001, 8, 12, 9, 25, 10 ),
+ 'type' => 'GET',
+ 'HTTP' => '1.0',
+ 'url' => '/toc.html'
+ } )
+documents: 2
+
+---
+test: Top level mapping
+yaml: |
+ # This stream is an example of a top-level mapping.
+ invoice : 34843
+ date : 2001-01-23
+ total : 4443.52
+php: |
+ array(
+ 'invoice' => 34843,
+ 'date' => gmmktime(0, 0, 0, 1, 23, 2001),
+ 'total' => 4443.52
+ )
+---
+test: Single-line documents
+todo: true
+yaml: |
+ # The following is a sequence of three documents.
+ # The first contains an empty mapping, the second
+ # an empty sequence, and the last an empty string.
+ --- {}
+ --- [ ]
+ --- ''
+ruby: |
+ y = YAML::Stream.new
+ y.add( {} )
+ y.add( [] )
+ y.add( '' )
+documents: 3
+
+---
+test: Document with pause
+todo: true
+yaml: |
+ # A communication channel based on a YAML stream.
+ ---
+ sent at: 2002-06-06 11:46:25.10 Z
+ payload: Whatever
+ # Receiver can process this as soon as the following is sent:
+ ...
+ # Even if the next message is sent long after:
+ ---
+ sent at: 2002-06-06 12:05:53.47 Z
+ payload: Whatever
+ ...
+ruby: |
+ y = YAML::Stream.new
+ y.add(
+ { 'sent at' => YAML::mktime( 2002, 6, 6, 11, 46, 25, 0.10 ),
+ 'payload' => 'Whatever' }
+ )
+ y.add(
+ { "payload" => "Whatever", "sent at" => YAML::mktime( 2002, 6, 6, 12, 5, 53, 0.47 ) }
+ )
+documents: 2
+
+---
+test: Explicit typing
+yaml: |
+ integer: 12
+ no int: ! 12
+ string: !!str 12
+php: |
+ array( 'integer' => 12, 'no int' => '12', 'string' => '12' )
+---
+test: Private types
+todo: true
+yaml: |
+ # Both examples below make use of the 'x-private:ball'
+ # type family URI, but with different semantics.
+ ---
+ pool: !!ball
+ number: 8
+ color: black
+ ---
+ bearing: !!ball
+ material: steel
+ruby: |
+ y = YAML::Stream.new
+ y.add( { 'pool' =>
+ YAML::PrivateType.new( 'ball',
+ { 'number' => 8, 'color' => 'black' } ) }
+ )
+ y.add( { 'bearing' =>
+ YAML::PrivateType.new( 'ball',
+ { 'material' => 'steel' } ) }
+ )
+documents: 2
+
+---
+test: Type family under yaml.org
+yaml: |
+ # The URI is 'tag:yaml.org,2002:str'
+ - !!str a Unicode string
+php: |
+ array( 'a Unicode string' )
+---
+test: Type family under perl.yaml.org
+todo: true
+yaml: |
+ # The URI is 'tag:perl.yaml.org,2002:Text::Tabs'
+ - !perl/Text::Tabs {}
+ruby: |
+ [ YAML::DomainType.new( 'perl.yaml.org,2002', 'Text::Tabs', {} ) ]
+---
+test: Type family under clarkevans.com
+todo: true
+yaml: |
+ # The URI is 'tag:clarkevans.com,2003-02:timesheet'
+ - !clarkevans.com,2003-02/timesheet {}
+ruby: |
+ [ YAML::DomainType.new( 'clarkevans.com,2003-02', 'timesheet', {} ) ]
+---
+test: URI Escaping
+todo: true
+yaml: |
+ same:
+ - !domain.tld,2002/type\x30 value
+ - !domain.tld,2002/type0 value
+ different: # As far as the YAML parser is concerned
+ - !domain.tld,2002/type%30 value
+ - !domain.tld,2002/type0 value
+ruby-setup: |
+ YAML.add_domain_type( "domain.tld,2002", "type0" ) { |type, val|
+ "ONE: #{val}"
+ }
+ YAML.add_domain_type( "domain.tld,2002", "type%30" ) { |type, val|
+ "TWO: #{val}"
+ }
+ruby: |
+ { 'same' => [ 'ONE: value', 'ONE: value' ], 'different' => [ 'TWO: value', 'ONE: value' ] }
+---
+test: URI Prefixing
+todo: true
+yaml: |
+ # 'tag:domain.tld,2002:invoice' is some type family.
+ invoice: !domain.tld,2002/^invoice
+ # 'seq' is shorthand for 'tag:yaml.org,2002:seq'.
+ # This does not effect '^customer' below
+ # because it is does not specify a prefix.
+ customers: !seq
+ # '^customer' is shorthand for the full
+ # notation 'tag:domain.tld,2002:customer'.
+ - !^customer
+ given : Chris
+ family : Dumars
+ruby-setup: |
+ YAML.add_domain_type( "domain.tld,2002", /(invoice|customer)/ ) { |type, val|
+ if val.is_a? ::Hash
+ scheme, domain, type = type.split( /:/, 3 )
+ val['type'] = "domain #{type}"
+ val
+ else
+ raise YAML::Error, "Not a Hash in domain.tld/invoice: " + val.inspect
+ end
+ }
+ruby: |
+ { "invoice"=> { "customers"=> [ { "given"=>"Chris", "type"=>"domain customer", "family"=>"Dumars" } ], "type"=>"domain invoice" } }
+
+---
+test: Overriding anchors
+yaml: |
+ anchor : &A001 This scalar has an anchor.
+ override : &A001 >
+ The alias node below is a
+ repeated use of this value.
+ alias : *A001
+php: |
+ array( 'anchor' => 'This scalar has an anchor.',
+ 'override' => "The alias node below is a repeated use of this value.\n",
+ 'alias' => "The alias node below is a repeated use of this value.\n" )
+---
+test: Flow and block formatting
+todo: true
+yaml: |
+ empty: []
+ flow: [ one, two, three # May span lines,
+ , four, # indentation is
+ five ] # mostly ignored.
+ block:
+ - First item in top sequence
+ -
+ - Subordinate sequence entry
+ - >
+ A folded sequence entry
+ - Sixth item in top sequence
+ruby: |
+ { 'empty' => [], 'flow' => [ 'one', 'two', 'three', 'four', 'five' ],
+ 'block' => [ 'First item in top sequence', [ 'Subordinate sequence entry' ],
+ "A folded sequence entry\n", 'Sixth item in top sequence' ] }
+---
+test: Complete mapping test
+todo: true
+yaml: |
+ empty: {}
+ flow: { one: 1, two: 2 }
+ spanning: { one: 1,
+ two: 2 }
+ block:
+ first : First entry
+ second:
+ key: Subordinate mapping
+ third:
+ - Subordinate sequence
+ - { }
+ - Previous mapping is empty.
+ - A key: value pair in a sequence.
+ A second: key:value pair.
+ - The previous entry is equal to the following one.
+ -
+ A key: value pair in a sequence.
+ A second: key:value pair.
+ !float 12 : This key is a float.
+ ? >
+ ?
+ : This key had to be protected.
+ "\a" : This key had to be escaped.
+ ? >
+ This is a
+ multi-line
+ folded key
+ : Whose value is
+ also multi-line.
+ ? this also works as a key
+ : with a value at the next line.
+ ?
+ - This key
+ - is a sequence
+ :
+ - With a sequence value.
+ ?
+ This: key
+ is a: mapping
+ :
+ with a: mapping value.
+ruby: |
+ { 'empty' => {}, 'flow' => { 'one' => 1, 'two' => 2 },
+ 'spanning' => { 'one' => 1, 'two' => 2 },
+ 'block' => { 'first' => 'First entry', 'second' =>
+ { 'key' => 'Subordinate mapping' }, 'third' =>
+ [ 'Subordinate sequence', {}, 'Previous mapping is empty.',
+ { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' },
+ 'The previous entry is equal to the following one.',
+ { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' } ],
+ 12.0 => 'This key is a float.', "?\n" => 'This key had to be protected.',
+ "\a" => 'This key had to be escaped.',
+ "This is a multi-line folded key\n" => "Whose value is also multi-line.",
+ 'this also works as a key' => 'with a value at the next line.',
+ [ 'This key', 'is a sequence' ] => [ 'With a sequence value.' ] } }
+ # Couldn't recreate map exactly, so we'll do a detailed check to be sure it's entact
+ obj_y['block'].keys.each { |k|
+ if Hash === k
+ v = obj_y['block'][k]
+ if k['This'] == 'key' and k['is a'] == 'mapping' and v['with a'] == 'mapping value.'
+ obj_r['block'][k] = v
+ end
+ end
+ }
+---
+test: Literal explicit indentation
+yaml: |
+ # Explicit indentation must
+ # be given in all the three
+ # following cases.
+ leading spaces: |2
+ This value starts with four spaces.
+
+ leading line break: |2
+
+ This value starts with a line break.
+
+ leading comment indicator: |2
+ # first line starts with a
+ # character.
+
+ # Explicit indentation may
+ # also be given when it is
+ # not required.
+ redundant: |2
+ This value is indented 2 spaces.
+php: |
+ array(
+ 'leading spaces' => " This value starts with four spaces.\n",
+ 'leading line break' => "\nThis value starts with a line break.\n",
+ 'leading comment indicator' => "# first line starts with a\n# character.\n",
+ 'redundant' => "This value is indented 2 spaces.\n"
+ )
+---
+test: Chomping and keep modifiers
+yaml: |
+ clipped: |
+ This has one newline.
+
+ same as "clipped" above: "This has one newline.\n"
+
+ stripped: |-
+ This has no newline.
+
+ same as "stripped" above: "This has no newline."
+
+ kept: |+
+ This has two newlines.
+
+ same as "kept" above: "This has two newlines.\n\n"
+php: |
+ array(
+ 'clipped' => "This has one newline.\n",
+ 'same as "clipped" above' => "This has one newline.\n",
+ 'stripped' => 'This has no newline.',
+ 'same as "stripped" above' => 'This has no newline.',
+ 'kept' => "This has two newlines.\n\n",
+ 'same as "kept" above' => "This has two newlines.\n\n"
+ )
+---
+test: Literal combinations
+todo: true
+yaml: |
+ empty: |
+
+ literal: |
+ The \ ' " characters may be
+ freely used. Leading white
+ space is significant.
+
+ Line breaks are significant.
+ Thus this value contains one
+ empty line and ends with a
+ single line break, but does
+ not start with one.
+
+ is equal to: "The \\ ' \" characters may \
+ be\nfreely used. Leading white\n space \
+ is significant.\n\nLine breaks are \
+ significant.\nThus this value contains \
+ one\nempty line and ends with a\nsingle \
+ line break, but does\nnot start with one.\n"
+
+ # Comments may follow a block
+ # scalar value. They must be
+ # less indented.
+
+ # Modifiers may be combined in any order.
+ indented and chomped: |2-
+ This has no newline.
+
+ also written as: |-2
+ This has no newline.
+
+ both are equal to: " This has no newline."
+php: |
+ array(
+ 'empty' => '',
+ 'literal' => "The \\ ' \" characters may be\nfreely used. Leading white\n space " +
+ "is significant.\n\nLine breaks are significant.\nThus this value contains one\n" +
+ "empty line and ends with a\nsingle line break, but does\nnot start with one.\n",
+ 'is equal to' => "The \\ ' \" characters may be\nfreely used. Leading white\n space " +
+ "is significant.\n\nLine breaks are significant.\nThus this value contains one\n" +
+ "empty line and ends with a\nsingle line break, but does\nnot start with one.\n",
+ 'indented and chomped' => ' This has no newline.',
+ 'also written as' => ' This has no newline.',
+ 'both are equal to' => ' This has no newline.'
+ )
+---
+test: Folded combinations
+todo: true
+yaml: |
+ empty: >
+
+ one paragraph: >
+ Line feeds are converted
+ to spaces, so this value
+ contains no line breaks
+ except for the final one.
+
+ multiple paragraphs: >2
+
+ An empty line, either
+ at the start or in
+ the value:
+
+ Is interpreted as a
+ line break. Thus this
+ value contains three
+ line breaks.
+
+ indented text: >
+ This is a folded
+ paragraph followed
+ by a list:
+ * first entry
+ * second entry
+ Followed by another
+ folded paragraph,
+ another list:
+
+ * first entry
+
+ * second entry
+
+ And a final folded
+ paragraph.
+
+ above is equal to: |
+ This is a folded paragraph followed by a list:
+ * first entry
+ * second entry
+ Followed by another folded paragraph, another list:
+
+ * first entry
+
+ * second entry
+
+ And a final folded paragraph.
+
+ # Explicit comments may follow
+ # but must be less indented.
+php: |
+ array(
+ 'empty' => '',
+ 'one paragraph' => 'Line feeds are converted to spaces, so this value'.
+ " contains no line breaks except for the final one.\n",
+ 'multiple paragraphs' => "\nAn empty line, either at the start or in the value:\n".
+ "Is interpreted as a line break. Thus this value contains three line breaks.\n",
+ 'indented text' => "This is a folded paragraph followed by a list:\n".
+ " * first entry\n * second entry\nFollowed by another folded paragraph, ".
+ "another list:\n\n * first entry\n\n * second entry\n\nAnd a final folded paragraph.\n",
+ 'above is equal to' => "This is a folded paragraph followed by a list:\n".
+ " * first entry\n * second entry\nFollowed by another folded paragraph, ".
+ "another list:\n\n * first entry\n\n * second entry\n\nAnd a final folded paragraph.\n"
+ )
+---
+test: Single quotes
+todo: true
+yaml: |
+ empty: ''
+ second: '! : \ etc. can be used freely.'
+ third: 'a single quote '' must be escaped.'
+ span: 'this contains
+ six spaces
+
+ and one
+ line break'
+ is same as: "this contains six spaces\nand one line break"
+php: |
+ array(
+ 'empty' => '',
+ 'second' => '! : \\ etc. can be used freely.',
+ 'third' => "a single quote ' must be escaped.",
+ 'span' => "this contains six spaces\nand one line break",
+ 'is same as' => "this contains six spaces\nand one line break"
+ )
+---
+test: Double quotes
+todo: true
+yaml: |
+ empty: ""
+ second: "! : etc. can be used freely."
+ third: "a \" or a \\ must be escaped."
+ fourth: "this value ends with an LF.\n"
+ span: "this contains
+ four \
+ spaces"
+ is equal to: "this contains four spaces"
+php: |
+ array(
+ 'empty' => '',
+ 'second' => '! : etc. can be used freely.',
+ 'third' => 'a " or a \\ must be escaped.',
+ 'fourth' => "this value ends with an LF.\n",
+ 'span' => "this contains four spaces",
+ 'is equal to' => "this contains four spaces"
+ )
+---
+test: Unquoted strings
+todo: true
+yaml: |
+ first: There is no unquoted empty string.
+
+ second: 12 ## This is an integer.
+
+ third: !!str 12 ## This is a string.
+
+ span: this contains
+ six spaces
+
+ and one
+ line break
+
+ indicators: this has no comments.
+ #:foo and bar# are
+ both text.
+
+ flow: [ can span
+ lines, # comment
+ like
+ this ]
+
+ note: { one-line keys: but multi-line values }
+
+php: |
+ array(
+ 'first' => 'There is no unquoted empty string.',
+ 'second' => 12,
+ 'third' => '12',
+ 'span' => "this contains six spaces\nand one line break",
+ 'indicators' => "this has no comments. #:foo and bar# are both text.",
+ 'flow' => [ 'can span lines', 'like this' ],
+ 'note' => { 'one-line keys' => 'but multi-line values' }
+ )
+---
+test: Spanning sequences
+todo: true
+yaml: |
+ # The following are equal seqs
+ # with different identities.
+ flow: [ one, two ]
+ spanning: [ one,
+ two ]
+ block:
+ - one
+ - two
+php: |
+ array(
+ 'flow' => [ 'one', 'two' ],
+ 'spanning' => [ 'one', 'two' ],
+ 'block' => [ 'one', 'two' ]
+ )
+---
+test: Flow mappings
+yaml: |
+ # The following are equal maps
+ # with different identities.
+ flow: { one: 1, two: 2 }
+ block:
+ one: 1
+ two: 2
+php: |
+ array(
+ 'flow' => array( 'one' => 1, 'two' => 2 ),
+ 'block' => array( 'one' => 1, 'two' => 2 )
+ )
+---
+test: Representations of 12
+todo: true
+yaml: |
+ - 12 # An integer
+ # The following scalars
+ # are loaded to the
+ # string value '1' '2'.
+ - !!str 12
+ - '12'
+ - "12"
+ - "\
+ 1\
+ 2\
+ "
+ # Strings containing paths and regexps can be unquoted:
+ - /foo/bar
+ - d:/foo/bar
+ - foo/bar
+ - /a.*b/
+php: |
+ array( 12, '12', '12', '12', '12', '/foo/bar', 'd:/foo/bar', 'foo/bar', '/a.*b/' )
+---
+test: "Null"
+todo: true
+yaml: |
+ canonical: ~
+
+ english: null
+
+ # This sequence has five
+ # entries, two with values.
+ sparse:
+ - ~
+ - 2nd entry
+ - Null
+ - 4th entry
+ -
+
+ four: This mapping has five keys,
+ only two with values.
+
+php: |
+ array (
+ 'canonical' => null,
+ 'english' => null,
+ 'sparse' => array( null, '2nd entry', null, '4th entry', null ]),
+ 'four' => 'This mapping has five keys, only two with values.'
+ )
+---
+test: Omap
+todo: true
+yaml: |
+ # Explicitly typed dictionary.
+ Bestiary: !omap
+ - aardvark: African pig-like ant eater. Ugly.
+ - anteater: South-American ant eater. Two species.
+ - anaconda: South-American constrictor snake. Scary.
+ # Etc.
+ruby: |
+ {
+ 'Bestiary' => YAML::Omap[
+ 'aardvark', 'African pig-like ant eater. Ugly.',
+ 'anteater', 'South-American ant eater. Two species.',
+ 'anaconda', 'South-American constrictor snake. Scary.'
+ ]
+ }
+
+---
+test: Pairs
+todo: true
+yaml: |
+ # Explicitly typed pairs.
+ tasks: !pairs
+ - meeting: with team.
+ - meeting: with boss.
+ - break: lunch.
+ - meeting: with client.
+ruby: |
+ {
+ 'tasks' => YAML::Pairs[
+ 'meeting', 'with team.',
+ 'meeting', 'with boss.',
+ 'break', 'lunch.',
+ 'meeting', 'with client.'
+ ]
+ }
+
+---
+test: Set
+todo: true
+yaml: |
+ # Explicitly typed set.
+ baseball players: !set
+ Mark McGwire:
+ Sammy Sosa:
+ Ken Griffey:
+ruby: |
+ {
+ 'baseball players' => YAML::Set[
+ 'Mark McGwire', nil,
+ 'Sammy Sosa', nil,
+ 'Ken Griffey', nil
+ ]
+ }
+
+---
+test: Integer
+yaml: |
+ canonical: 12345
+ octal: 014
+ hexadecimal: 0xC
+php: |
+ array(
+ 'canonical' => 12345,
+ 'octal' => 12,
+ 'hexadecimal' => 12
+ )
+---
+test: Float
+yaml: |
+ canonical: 1.23015e+3
+ exponential: 12.3015e+02
+ negative infinity: -.inf
+ not a number: .NaN
+php: |
+ array(
+ 'canonical' => 1230.15,
+ 'exponential' => 1230.15,
+ 'negative infinity' => log(0),
+ 'not a number' => -log(0)
+ )
+---
+test: Timestamp
+todo: true
+yaml: |
+ canonical: 2001-12-15T02:59:43.1Z
+ valid iso8601: 2001-12-14t21:59:43.10-05:00
+ space separated: 2001-12-14 21:59:43.10 -05:00
+ date (noon UTC): 2002-12-14
+ruby: |
+ array(
+ 'canonical' => YAML::mktime( 2001, 12, 15, 2, 59, 43, 0.10 ),
+ 'valid iso8601' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
+ 'space separated' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
+ 'date (noon UTC)' => Date.new( 2002, 12, 14 )
+ )
+---
+test: Binary
+todo: true
+yaml: |
+ canonical: !binary "\
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs="
+ base64: !binary |
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
+ description: >
+ The binary value above is a tiny arrow
+ encoded as a gif image.
+ruby-setup: |
+ arrow_gif = "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236iiiccc\243\243\243\204\204\204\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371!\376\016Made with GIMP\000,\000\000\000\000\f\000\f\000\000\005, \216\2010\236\343@\024\350i\020\304\321\212\010\034\317\200M$z\357\3770\205p\270\2601f\r\e\316\001\303\001\036\020' \202\n\001\000;"
+ruby: |
+ {
+ 'canonical' => arrow_gif,
+ 'base64' => arrow_gif,
+ 'description' => "The binary value above is a tiny arrow encoded as a gif image.\n"
+ }
+
+---
+test: Merge key
+todo: true
+yaml: |
+ ---
+ - &CENTER { x: 1, y: 2 }
+ - &LEFT { x: 0, y: 2 }
+ - &BIG { r: 10 }
+ - &SMALL { r: 1 }
+
+ # All the following maps are equal:
+
+ - # Explicit keys
+ x: 1
+ y: 2
+ r: 10
+ label: center/big
+
+ - # Merge one map
+ << : *CENTER
+ r: 10
+ label: center/big
+
+ - # Merge multiple maps
+ << : [ *CENTER, *BIG ]
+ label: center/big
+
+ - # Override
+ << : [ *BIG, *LEFT, *SMALL ]
+ x: 1
+ label: center/big
+
+ruby-setup: |
+ center = { 'x' => 1, 'y' => 2 }
+ left = { 'x' => 0, 'y' => 2 }
+ big = { 'r' => 10 }
+ small = { 'r' => 1 }
+ node1 = { 'x' => 1, 'y' => 2, 'r' => 10, 'label' => 'center/big' }
+ node2 = center.dup
+ node2.update( { 'r' => 10, 'label' => 'center/big' } )
+ node3 = big.dup
+ node3.update( center )
+ node3.update( { 'label' => 'center/big' } )
+ node4 = small.dup
+ node4.update( left )
+ node4.update( big )
+ node4.update( { 'x' => 1, 'label' => 'center/big' } )
+
+ruby: |
+ [
+ center, left, big, small, node1, node2, node3, node4
+ ]
+
+---
+test: Default key
+todo: true
+yaml: |
+ --- # Old schema
+ link with:
+ - library1.dll
+ - library2.dll
+ --- # New schema
+ link with:
+ - = : library1.dll
+ version: 1.2
+ - = : library2.dll
+ version: 2.3
+ruby: |
+ y = YAML::Stream.new
+ y.add( { 'link with' => [ 'library1.dll', 'library2.dll' ] } )
+ obj_h = Hash[ 'version' => 1.2 ]
+ obj_h.default = 'library1.dll'
+ obj_h2 = Hash[ 'version' => 2.3 ]
+ obj_h2.default = 'library2.dll'
+ y.add( { 'link with' => [ obj_h, obj_h2 ] } )
+documents: 2
+
+---
+test: Special keys
+todo: true
+yaml: |
+ "!": These three keys
+ "&": had to be quoted
+ "=": and are normal strings.
+ # NOTE: the following node should NOT be serialized this way.
+ encoded node :
+ !special '!' : '!type'
+ !special|canonical '&' : 12
+ = : value
+ # The proper way to serialize the above node is as follows:
+ node : !!type &12 value
+ruby: |
+ { '!' => 'These three keys', '&' => 'had to be quoted',
+ '=' => 'and are normal strings.',
+ 'encoded node' => YAML::PrivateType.new( 'type', 'value' ),
+ 'node' => YAML::PrivateType.new( 'type', 'value' ) }
diff --git a/vendor/symfony/yaml/Tests/Fixtures/YtsTypeTransfers.yml b/vendor/symfony/yaml/Tests/Fixtures/YtsTypeTransfers.yml
new file mode 100644
index 0000000..f1a7832
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/YtsTypeTransfers.yml
@@ -0,0 +1,224 @@
+--- %YAML:1.0
+test: Strings
+brief: >
+ Any group of characters beginning with an
+ alphabetic or numeric character is a string,
+ unless it belongs to one of the groups below
+ (such as an Integer or Time).
+yaml: |
+ String
+php: |
+ 'String'
+---
+test: String characters
+brief: >
+ A string can contain any alphabetic or
+ numeric character, along with many
+ punctuation characters, including the
+ period, dash, space, quotes, exclamation, and
+ question mark.
+yaml: |
+ - What's Yaml?
+ - It's for writing data structures in plain text.
+ - And?
+ - And what? That's not good enough for you?
+ - No, I mean, "And what about Yaml?"
+ - Oh, oh yeah. Uh.. Yaml for Ruby.
+php: |
+ array(
+ "What's Yaml?",
+ "It's for writing data structures in plain text.",
+ "And?",
+ "And what? That's not good enough for you?",
+ "No, I mean, \"And what about Yaml?\"",
+ "Oh, oh yeah. Uh.. Yaml for Ruby."
+ )
+---
+test: Indicators in Strings
+brief: >
+ Be careful using indicators in strings. In particular,
+ the comma, colon, and pound sign must be used carefully.
+yaml: |
+ the colon followed by space is an indicator: but is a string:right here
+ same for the pound sign: here we have it#in a string
+ the comma can, honestly, be used in most cases: [ but not in, inline collections ]
+php: |
+ array(
+ 'the colon followed by space is an indicator' => 'but is a string:right here',
+ 'same for the pound sign' => 'here we have it#in a string',
+ 'the comma can, honestly, be used in most cases' => array('but not in', 'inline collections')
+ )
+---
+test: Forcing Strings
+brief: >
+ Any YAML type can be forced into a string using the
+ explicit !!str method.
+yaml: |
+ date string: !!str 2001-08-01
+ number string: !!str 192
+php: |
+ array(
+ 'date string' => '2001-08-01',
+ 'number string' => '192'
+ )
+---
+test: Single-quoted Strings
+brief: >
+ You can also enclose your strings within single quotes,
+ which allows use of slashes, colons, and other indicators
+ freely. Inside single quotes, you can represent a single
+ quote in your string by using two single quotes next to
+ each other.
+yaml: |
+ all my favorite symbols: '#:!/%.)'
+ a few i hate: '&(*'
+ why do i hate them?: 'it''s very hard to explain'
+ entities: '&pound; me'
+php: |
+ array(
+ 'all my favorite symbols' => '#:!/%.)',
+ 'a few i hate' => '&(*',
+ 'why do i hate them?' => 'it\'s very hard to explain',
+ 'entities' => '&pound; me'
+ )
+---
+test: Double-quoted Strings
+brief: >
+ Enclosing strings in double quotes allows you
+ to use escapings to represent ASCII and
+ Unicode characters.
+yaml: |
+ i know where i want my line breaks: "one here\nand another here\n"
+php: |
+ array(
+ 'i know where i want my line breaks' => "one here\nand another here\n"
+ )
+---
+test: Multi-line Quoted Strings
+todo: true
+brief: >
+ Both single- and double-quoted strings may be
+ carried on to new lines in your YAML document.
+ They must be indented a step and indentation
+ is interpreted as a single space.
+yaml: |
+ i want a long string: "so i'm going to
+ let it go on and on to other lines
+ until i end it with a quote."
+php: |
+ array('i want a long string' => "so i'm going to ".
+ "let it go on and on to other lines ".
+ "until i end it with a quote."
+ )
+
+---
+test: Plain scalars
+todo: true
+brief: >
+ Unquoted strings may also span multiple lines, if they
+ are free of YAML space indicators and indented.
+yaml: |
+ - My little toe is broken in two places;
+ - I'm crazy to have skied this way;
+ - I'm not the craziest he's seen, since there was always the German guy
+ who skied for 3 hours on a broken shin bone (just below the kneecap);
+ - Nevertheless, second place is respectable, and he doesn't
+ recommend going for the record;
+ - He's going to put my foot in plaster for a month;
+ - This would impair my skiing ability somewhat for the
+ duration, as can be imagined.
+php: |
+ array(
+ "My little toe is broken in two places;",
+ "I'm crazy to have skied this way;",
+ "I'm not the craziest he's seen, since there was always ".
+ "the German guy who skied for 3 hours on a broken shin ".
+ "bone (just below the kneecap);",
+ "Nevertheless, second place is respectable, and he doesn't ".
+ "recommend going for the record;",
+ "He's going to put my foot in plaster for a month;",
+ "This would impair my skiing ability somewhat for the duration, ".
+ "as can be imagined."
+ )
+---
+test: 'Null'
+brief: >
+ You can use the tilde '~' character for a null value.
+yaml: |
+ name: Mr. Show
+ hosted by: Bob and David
+ date of next season: ~
+php: |
+ array(
+ 'name' => 'Mr. Show',
+ 'hosted by' => 'Bob and David',
+ 'date of next season' => null
+ )
+---
+test: Boolean
+brief: >
+ You can use 'true' and 'false' for Boolean values.
+yaml: |
+ Is Gus a Liar?: true
+ Do I rely on Gus for Sustenance?: false
+php: |
+ array(
+ 'Is Gus a Liar?' => true,
+ 'Do I rely on Gus for Sustenance?' => false
+ )
+---
+test: Integers
+dump_skip: true
+brief: >
+ An integer is a series of numbers, optionally
+ starting with a positive or negative sign. Integers
+ may also contain commas for readability.
+yaml: |
+ zero: 0
+ simple: 12
+php: |
+ array(
+ 'zero' => 0,
+ 'simple' => 12,
+ )
+---
+test: Floats
+dump_skip: true
+brief: >
+ Floats are represented by numbers with decimals,
+ allowing for scientific notation, as well as
+ positive and negative infinity and "not a number."
+yaml: |
+ a simple float: 2.00
+ scientific notation: 1.00009e+3
+php: |
+ array(
+ 'a simple float' => 2.0,
+ 'scientific notation' => 1000.09
+ )
+---
+test: Time
+todo: true
+brief: >
+ You can represent timestamps by using
+ ISO8601 format, or a variation which
+ allows spaces between the date, time and
+ time zone.
+yaml: |
+ iso8601: 2001-12-14t21:59:43.10-05:00
+ space separated: 2001-12-14 21:59:43.10 -05:00
+php: |
+ array(
+ 'iso8601' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ),
+ 'space separated' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" )
+ )
+---
+test: Date
+todo: true
+brief: >
+ A date can be represented by its year,
+ month and day in ISO8601 order.
+yaml: |
+ 1976-07-31
+php: |
+ date( 1976, 7, 31 )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/arrow.gif b/vendor/symfony/yaml/Tests/Fixtures/arrow.gif
new file mode 100644
index 0000000..443aca4
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/arrow.gif
Binary files differ
diff --git a/vendor/symfony/yaml/Tests/Fixtures/booleanMappingKeys.yml b/vendor/symfony/yaml/Tests/Fixtures/booleanMappingKeys.yml
new file mode 100644
index 0000000..26799e8
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/booleanMappingKeys.yml
@@ -0,0 +1,11 @@
+--- %YAML:1.0
+test: Miscellaneous
+spec: 2.21
+yaml: |
+ true: true
+ false: false
+php: |
+ array(
+ 'true' => true,
+ 'false' => false,
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/embededPhp.yml b/vendor/symfony/yaml/Tests/Fixtures/embededPhp.yml
new file mode 100644
index 0000000..ec456ed
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/embededPhp.yml
@@ -0,0 +1 @@
+value: <?php echo 1 + 2 + 3 ?>
diff --git a/vendor/symfony/yaml/Tests/Fixtures/escapedCharacters.yml b/vendor/symfony/yaml/Tests/Fixtures/escapedCharacters.yml
new file mode 100644
index 0000000..cc0356d
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/escapedCharacters.yml
@@ -0,0 +1,155 @@
+test: outside double quotes
+yaml: |
+ \0 \ \a \b \n
+php: |
+ "\\0 \\ \\a \\b \\n"
+---
+test: 'null'
+yaml: |
+ "\0"
+php: |
+ "\x00"
+---
+test: bell
+yaml: |
+ "\a"
+php: |
+ "\x07"
+---
+test: backspace
+yaml: |
+ "\b"
+php: |
+ "\x08"
+---
+test: horizontal tab (1)
+yaml: |
+ "\t"
+php: |
+ "\x09"
+---
+test: horizontal tab (2)
+yaml: |
+ "\ "
+php: |
+ "\x09"
+---
+test: line feed
+yaml: |
+ "\n"
+php: |
+ "\x0a"
+---
+test: vertical tab
+yaml: |
+ "\v"
+php: |
+ "\x0b"
+---
+test: form feed
+yaml: |
+ "\f"
+php: |
+ "\x0c"
+---
+test: carriage return
+yaml: |
+ "\r"
+php: |
+ "\x0d"
+---
+test: escape
+yaml: |
+ "\e"
+php: |
+ "\x1b"
+---
+test: space
+yaml: |
+ "\ "
+php: |
+ "\x20"
+---
+test: slash
+yaml: |
+ "\/"
+php: |
+ "\x2f"
+---
+test: backslash
+yaml: |
+ "\\"
+php: |
+ "\\"
+---
+test: Unicode next line
+yaml: |
+ "\N"
+php: |
+ "\xc2\x85"
+---
+test: Unicode non-breaking space
+yaml: |
+ "\_"
+php: |
+ "\xc2\xa0"
+---
+test: Unicode line separator
+yaml: |
+ "\L"
+php: |
+ "\xe2\x80\xa8"
+---
+test: Unicode paragraph separator
+yaml: |
+ "\P"
+php: |
+ "\xe2\x80\xa9"
+---
+test: Escaped 8-bit Unicode
+yaml: |
+ "\x42"
+php: |
+ "B"
+---
+test: Escaped 16-bit Unicode
+yaml: |
+ "\u20ac"
+php: |
+ "\xe2\x82\xac"
+---
+test: Escaped 32-bit Unicode
+yaml: |
+ "\U00000043"
+php: |
+ "C"
+---
+test: Example 5.13 Escaped Characters
+note: |
+ Currently throws an error parsing first line. Maybe Symfony Yaml doesn't support
+ continuation of string across multiple lines? Keeping test here but disabled.
+todo: true
+yaml: |
+ "Fun with \\
+ \" \a \b \e \f \
+ \n \r \t \v \0 \
+ \ \_ \N \L \P \
+ \x41 \u0041 \U00000041"
+php: |
+ "Fun with \x5C\n\x22 \x07 \x08 \x1B \x0C\n\x0A \x0D \x09 \x0B \x00\n\x20 \xA0 \x85 \xe2\x80\xa8 \xe2\x80\xa9\nA A A"
+---
+test: Double quotes with a line feed
+yaml: |
+ { double: "some value\n \"some quoted string\" and 'some single quotes one'" }
+php: |
+ array(
+ 'double' => "some value\n \"some quoted string\" and 'some single quotes one'"
+ )
+---
+test: Backslashes
+yaml: |
+ { single: 'foo\Var', no-quotes: foo\Var, double: "foo\\Var" }
+php: |
+ array(
+ 'single' => 'foo\Var', 'no-quotes' => 'foo\Var', 'double' => 'foo\Var'
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/index.yml b/vendor/symfony/yaml/Tests/Fixtures/index.yml
new file mode 100644
index 0000000..3216a89
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/index.yml
@@ -0,0 +1,18 @@
+- escapedCharacters
+- sfComments
+- sfCompact
+- sfTests
+- sfObjects
+- sfMergeKey
+- sfQuotes
+- YtsAnchorAlias
+- YtsBasicTests
+- YtsBlockMapping
+- YtsDocumentSeparator
+- YtsErrorTests
+- YtsFlowCollections
+- YtsFoldedScalars
+- YtsNullsAndEmpties
+- YtsSpecificationExamples
+- YtsTypeTransfers
+- unindentedCollections
diff --git a/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml b/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml
new file mode 100644
index 0000000..9d72f09
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml
@@ -0,0 +1,14 @@
+data:
+ single_line: 'foo bar baz'
+ multi_line: |
+ foo
+ line with trailing spaces:
+
+ bar
+ integer like line:
+ 123456789
+ empty line:
+
+ baz
+ multi_line_with_carriage_return: "foo\nbar\r\nbaz"
+ nested_inlined_multi_line_string: { inlined_multi_line: "foo\nbar\r\nempty line:\n\nbaz" }
diff --git a/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block_leading_space_in_first_line.yml b/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block_leading_space_in_first_line.yml
new file mode 100644
index 0000000..3f2dedd
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block_leading_space_in_first_line.yml
@@ -0,0 +1,4 @@
+data:
+ multi_line: |4
+ the first line has leading spaces
+ The second line does not.
diff --git a/vendor/symfony/yaml/Tests/Fixtures/nonStringKeys.yml b/vendor/symfony/yaml/Tests/Fixtures/nonStringKeys.yml
new file mode 100644
index 0000000..354b079
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/nonStringKeys.yml
@@ -0,0 +1,3 @@
+- booleanMappingKeys
+- numericMappingKeys
+- nullMappingKey
diff --git a/vendor/symfony/yaml/Tests/Fixtures/not_readable.yml b/vendor/symfony/yaml/Tests/Fixtures/not_readable.yml
new file mode 100644
index 0000000..3216a89
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/not_readable.yml
@@ -0,0 +1,18 @@
+- escapedCharacters
+- sfComments
+- sfCompact
+- sfTests
+- sfObjects
+- sfMergeKey
+- sfQuotes
+- YtsAnchorAlias
+- YtsBasicTests
+- YtsBlockMapping
+- YtsDocumentSeparator
+- YtsErrorTests
+- YtsFlowCollections
+- YtsFoldedScalars
+- YtsNullsAndEmpties
+- YtsSpecificationExamples
+- YtsTypeTransfers
+- unindentedCollections
diff --git a/vendor/symfony/yaml/Tests/Fixtures/nullMappingKey.yml b/vendor/symfony/yaml/Tests/Fixtures/nullMappingKey.yml
new file mode 100644
index 0000000..7dcadc7
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/nullMappingKey.yml
@@ -0,0 +1,9 @@
+--- %YAML:1.0
+test: Miscellaneous
+spec: 2.21
+yaml: |
+ null: ~
+php: |
+ array(
+ 'null' => null,
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/numericMappingKeys.yml b/vendor/symfony/yaml/Tests/Fixtures/numericMappingKeys.yml
new file mode 100644
index 0000000..9cfb771
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/numericMappingKeys.yml
@@ -0,0 +1,23 @@
+--- %YAML:1.0
+test: A sequence with an unordered array
+brief: >
+ A sequence with an unordered array
+yaml: |
+ 1: foo
+ 0: bar
+php: |
+ array(1 => 'foo', 0 => 'bar')
+---
+test: Integers as Map Keys
+brief: >
+ An integer can be used as dictionary key.
+yaml: |
+ 1: one
+ 2: two
+ 3: three
+php: |
+ array(
+ 1 => 'one',
+ 2 => 'two',
+ 3 => 'three'
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfComments.yml b/vendor/symfony/yaml/Tests/Fixtures/sfComments.yml
new file mode 100644
index 0000000..b72a9b6
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/sfComments.yml
@@ -0,0 +1,76 @@
+--- %YAML:1.0
+test: Comments at the end of a line
+brief: >
+ Comments at the end of a line
+yaml: |
+ ex1: "foo # bar"
+ ex2: "foo # bar" # comment
+ ex3: 'foo # bar' # comment
+ ex4: foo # comment
+ ex5: foo # comment with tab before
+ ex6: foo#foo # comment here
+ ex7: foo # ignore me # and me
+php: |
+ array('ex1' => 'foo # bar', 'ex2' => 'foo # bar', 'ex3' => 'foo # bar', 'ex4' => 'foo', 'ex5' => 'foo', 'ex6' => 'foo#foo', 'ex7' => 'foo')
+---
+test: Comments in the middle
+brief: >
+ Comments in the middle
+yaml: |
+ foo:
+ # some comment
+ # some comment
+ bar: foo
+ # some comment
+ # some comment
+php: |
+ array('foo' => array('bar' => 'foo'))
+---
+test: Comments on a hash line
+brief: >
+ Comments on a hash line
+yaml: |
+ foo: # a comment
+ foo: bar # a comment
+php: |
+ array('foo' => array('foo' => 'bar'))
+---
+test: 'Value starting with a #'
+brief: >
+ 'Value starting with a #'
+yaml: |
+ foo: '#bar'
+php: |
+ array('foo' => '#bar')
+---
+test: Document starting with a comment and a separator
+brief: >
+ Commenting before document start is allowed
+yaml: |
+ # document comment
+ ---
+ foo: bar # a comment
+php: |
+ array('foo' => 'bar')
+---
+test: Comment containing a colon on a hash line
+brief: >
+ Comment containing a colon on a scalar line
+yaml: 'foo # comment: this is also part of the comment'
+php: |
+ 'foo'
+---
+test: 'Hash key containing a #'
+brief: >
+ 'Hash key containing a #'
+yaml: 'foo#bar: baz'
+php: |
+ array('foo#bar' => 'baz')
+---
+test: 'Hash key ending with a space and a #'
+brief: >
+ 'Hash key ending with a space and a #'
+yaml: |
+ 'foo #': baz
+php: |
+ array('foo #' => 'baz')
diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfCompact.yml b/vendor/symfony/yaml/Tests/Fixtures/sfCompact.yml
new file mode 100644
index 0000000..1339d23
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/sfCompact.yml
@@ -0,0 +1,159 @@
+--- %YAML:1.0
+test: Compact notation
+brief: |
+ Compact notation for sets of mappings with single element
+yaml: |
+ ---
+ # products purchased
+ - item : Super Hoop
+ - item : Basketball
+ quantity: 1
+ - item:
+ name: Big Shoes
+ nick: Biggies
+ quantity: 1
+php: |
+ array (
+ array (
+ 'item' => 'Super Hoop',
+ ),
+ array (
+ 'item' => 'Basketball',
+ 'quantity' => 1,
+ ),
+ array (
+ 'item' => array(
+ 'name' => 'Big Shoes',
+ 'nick' => 'Biggies'
+ ),
+ 'quantity' => 1
+ )
+ )
+---
+test: Compact notation combined with inline notation
+brief: |
+ Combinations of compact and inline notation are allowed
+yaml: |
+ ---
+ items:
+ - { item: Super Hoop, quantity: 1 }
+ - [ Basketball, Big Shoes ]
+php: |
+ array (
+ 'items' => array (
+ array (
+ 'item' => 'Super Hoop',
+ 'quantity' => 1,
+ ),
+ array (
+ 'Basketball',
+ 'Big Shoes'
+ )
+ )
+ )
+--- %YAML:1.0
+test: Compact notation
+brief: |
+ Compact notation for sets of mappings with single element
+yaml: |
+ ---
+ # products purchased
+ - item : Super Hoop
+ - item : Basketball
+ quantity: 1
+ - item:
+ name: Big Shoes
+ nick: Biggies
+ quantity: 1
+php: |
+ array (
+ array (
+ 'item' => 'Super Hoop',
+ ),
+ array (
+ 'item' => 'Basketball',
+ 'quantity' => 1,
+ ),
+ array (
+ 'item' => array(
+ 'name' => 'Big Shoes',
+ 'nick' => 'Biggies'
+ ),
+ 'quantity' => 1
+ )
+ )
+---
+test: Compact notation combined with inline notation
+brief: |
+ Combinations of compact and inline notation are allowed
+yaml: |
+ ---
+ items:
+ - { item: Super Hoop, quantity: 1 }
+ - [ Basketball, Big Shoes ]
+php: |
+ array (
+ 'items' => array (
+ array (
+ 'item' => 'Super Hoop',
+ 'quantity' => 1,
+ ),
+ array (
+ 'Basketball',
+ 'Big Shoes'
+ )
+ )
+ )
+--- %YAML:1.0
+test: Compact notation
+brief: |
+ Compact notation for sets of mappings with single element
+yaml: |
+ ---
+ # products purchased
+ - item : Super Hoop
+ - item : Basketball
+ quantity: 1
+ - item:
+ name: Big Shoes
+ nick: Biggies
+ quantity: 1
+php: |
+ array (
+ array (
+ 'item' => 'Super Hoop',
+ ),
+ array (
+ 'item' => 'Basketball',
+ 'quantity' => 1,
+ ),
+ array (
+ 'item' => array(
+ 'name' => 'Big Shoes',
+ 'nick' => 'Biggies'
+ ),
+ 'quantity' => 1
+ )
+ )
+---
+test: Compact notation combined with inline notation
+brief: |
+ Combinations of compact and inline notation are allowed
+yaml: |
+ ---
+ items:
+ - { item: Super Hoop, quantity: 1 }
+ - [ Basketball, Big Shoes ]
+php: |
+ array (
+ 'items' => array (
+ array (
+ 'item' => 'Super Hoop',
+ 'quantity' => 1,
+ ),
+ array (
+ 'Basketball',
+ 'Big Shoes'
+ )
+ )
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfMergeKey.yml b/vendor/symfony/yaml/Tests/Fixtures/sfMergeKey.yml
new file mode 100644
index 0000000..83264cf
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/sfMergeKey.yml
@@ -0,0 +1,61 @@
+--- %YAML:1.0
+test: Simple In Place Substitution
+brief: >
+ If you want to reuse an entire alias, only overwriting what is different
+ you can use a << in place substitution. This is not part of the official
+ YAML spec, but a widely implemented extension. See the following URL for
+ details: http://yaml.org/type/merge.html
+yaml: |
+ foo: &foo
+ a: Steve
+ b: Clark
+ c: Brian
+ e: notnull
+ bar:
+ a: before
+ d: other
+ e: ~
+ <<: *foo
+ b: new
+ x: Oren
+ c:
+ foo: bar
+ bar: foo
+ bar_inline: {a: before, d: other, <<: *foo, b: new, x: Oren, c: { foo: bar, bar: foo}}
+ foo2: &foo2
+ a: Ballmer
+ ding: &dong [ fi, fei, fo, fam]
+ check:
+ <<:
+ - *foo
+ - *dong
+ isit: tested
+ head:
+ <<: [ *foo , *dong , *foo2 ]
+ taz: &taz
+ a: Steve
+ w:
+ p: 1234
+ nested:
+ <<: *taz
+ d: Doug
+ w: &nestedref
+ p: 12345
+ z:
+ <<: *nestedref
+ head_inline: &head_inline { <<: [ *foo , *dong , *foo2 ] }
+ recursive_inline: { <<: *head_inline, c: { <<: *foo2 } }
+php: |
+ array(
+ 'foo' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull'),
+ 'bar' => array('a' => 'before', 'd' => 'other', 'e' => null, 'b' => 'new', 'c' => array('foo' => 'bar', 'bar' => 'foo'), 'x' => 'Oren'),
+ 'bar_inline' => array('a' => 'before', 'd' => 'other', 'b' => 'new', 'c' => array('foo' => 'bar', 'bar' => 'foo'), 'e' => 'notnull', 'x' => 'Oren'),
+ 'foo2' => array('a' => 'Ballmer'),
+ 'ding' => array('fi', 'fei', 'fo', 'fam'),
+ 'check' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam', 'isit' => 'tested'),
+ 'head' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'),
+ 'taz' => array('a' => 'Steve', 'w' => array('p' => 1234)),
+ 'nested' => array('a' => 'Steve', 'w' => array('p' => 12345), 'd' => 'Doug', 'z' => array('p' => 12345)),
+ 'head_inline' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'),
+ 'recursive_inline' => array('a' => 'Steve', 'b' => 'Clark', 'c' => array('a' => 'Ballmer'), 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'),
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfObjects.yml b/vendor/symfony/yaml/Tests/Fixtures/sfObjects.yml
new file mode 100644
index 0000000..ee124b2
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/sfObjects.yml
@@ -0,0 +1,11 @@
+--- %YAML:1.0
+test: Objects
+brief: >
+ Comments at the end of a line
+yaml: |
+ ex1: "foo # bar"
+ ex2: "foo # bar" # comment
+ ex3: 'foo # bar' # comment
+ ex4: foo # comment
+php: |
+ array('ex1' => 'foo # bar', 'ex2' => 'foo # bar', 'ex3' => 'foo # bar', 'ex4' => 'foo')
diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfQuotes.yml b/vendor/symfony/yaml/Tests/Fixtures/sfQuotes.yml
new file mode 100644
index 0000000..7c60bae
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/sfQuotes.yml
@@ -0,0 +1,33 @@
+--- %YAML:1.0
+test: Some characters at the beginning of a string must be escaped
+brief: >
+ Some characters at the beginning of a string must be escaped
+yaml: |
+ foo: '| bar'
+php: |
+ array('foo' => '| bar')
+---
+test: A key can be a quoted string
+brief: >
+ A key can be a quoted string
+yaml: |
+ "foo1": bar
+ 'foo2': bar
+ "foo \" bar": bar
+ 'foo '' bar': bar
+ 'foo3: ': bar
+ "foo4: ": bar
+ foo5: { "foo \" bar: ": bar, 'foo '' bar: ': bar }
+php: |
+ array(
+ 'foo1' => 'bar',
+ 'foo2' => 'bar',
+ 'foo " bar' => 'bar',
+ 'foo \' bar' => 'bar',
+ 'foo3: ' => 'bar',
+ 'foo4: ' => 'bar',
+ 'foo5' => array(
+ 'foo " bar: ' => 'bar',
+ 'foo \' bar: ' => 'bar',
+ ),
+ )
diff --git a/vendor/symfony/yaml/Tests/Fixtures/sfTests.yml b/vendor/symfony/yaml/Tests/Fixtures/sfTests.yml
new file mode 100644
index 0000000..2a0b9c8
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/sfTests.yml
@@ -0,0 +1,140 @@
+--- %YAML:1.0
+test: Multiple quoted string on one line
+brief: >
+ Multiple quoted string on one line
+yaml: |
+ stripped_title: { name: "foo bar", help: "bar foo" }
+php: |
+ array('stripped_title' => array('name' => 'foo bar', 'help' => 'bar foo'))
+---
+test: Empty sequence
+yaml: |
+ foo: [ ]
+php: |
+ array('foo' => array())
+---
+test: Empty value
+yaml: |
+ foo:
+php: |
+ array('foo' => null)
+---
+test: Inline string parsing
+brief: >
+ Inline string parsing
+yaml: |
+ test: ['complex: string', 'another [string]']
+php: |
+ array('test' => array('complex: string', 'another [string]'))
+---
+test: Boolean
+brief: >
+ Boolean
+yaml: |
+ - false
+ - true
+ - null
+ - ~
+ - 'false'
+ - 'true'
+ - 'null'
+ - '~'
+php: |
+ array(
+ false,
+ true,
+ null,
+ null,
+ 'false',
+ 'true',
+ 'null',
+ '~',
+ )
+---
+test: Empty lines in literal blocks
+brief: >
+ Empty lines in literal blocks
+yaml: |
+ foo:
+ bar: |
+ foo
+
+
+
+ bar
+php: |
+ array('foo' => array('bar' => "foo\n\n\n \nbar\n"))
+---
+test: Empty lines in folded blocks
+brief: >
+ Empty lines in folded blocks
+yaml: |
+ foo:
+ bar: >
+
+ foo
+
+
+ bar
+php: |
+ array('foo' => array('bar' => "\nfoo\n\nbar\n"))
+---
+test: IP addresses
+brief: >
+ IP addresses
+yaml: |
+ foo: 10.0.0.2
+php: |
+ array('foo' => '10.0.0.2')
+---
+test: A sequence with an embedded mapping
+brief: >
+ A sequence with an embedded mapping
+yaml: |
+ - foo
+ - bar: { bar: foo }
+php: |
+ array('foo', array('bar' => array('bar' => 'foo')))
+---
+test: Octal
+brief: as in spec example 2.19, octal value is converted
+yaml: |
+ foo: 0123
+php: |
+ array('foo' => 83)
+---
+test: Octal strings
+brief: Octal notation in a string must remain a string
+yaml: |
+ foo: "0123"
+php: |
+ array('foo' => '0123')
+---
+test: Octal strings
+brief: Octal notation in a string must remain a string
+yaml: |
+ foo: '0123'
+php: |
+ array('foo' => '0123')
+---
+test: Octal strings
+brief: Octal notation in a string must remain a string
+yaml: |
+ foo: |
+ 0123
+php: |
+ array('foo' => "0123\n")
+---
+test: Document as a simple hash
+brief: Document as a simple hash
+yaml: |
+ { foo: bar }
+php: |
+ array('foo' => 'bar')
+---
+test: Document as a simple array
+brief: Document as a simple array
+yaml: |
+ [ foo, bar ]
+php: |
+ array('foo', 'bar')
diff --git a/vendor/symfony/yaml/Tests/Fixtures/unindentedCollections.yml b/vendor/symfony/yaml/Tests/Fixtures/unindentedCollections.yml
new file mode 100644
index 0000000..0c96108
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/Fixtures/unindentedCollections.yml
@@ -0,0 +1,82 @@
+--- %YAML:1.0
+test: Unindented collection
+brief: >
+ Unindented collection
+yaml: |
+ collection:
+ - item1
+ - item2
+ - item3
+php: |
+ array('collection' => array('item1', 'item2', 'item3'))
+---
+test: Nested unindented collection (two levels)
+brief: >
+ Nested unindented collection
+yaml: |
+ collection:
+ key:
+ - a
+ - b
+ - c
+php: |
+ array('collection' => array('key' => array('a', 'b', 'c')))
+---
+test: Nested unindented collection (three levels)
+brief: >
+ Nested unindented collection
+yaml: |
+ collection:
+ key:
+ subkey:
+ - one
+ - two
+ - three
+php: |
+ array('collection' => array('key' => array('subkey' => array('one', 'two', 'three'))))
+---
+test: Key/value after unindented collection (1)
+brief: >
+ Key/value after unindented collection (1)
+yaml: |
+ collection:
+ key:
+ - a
+ - b
+ - c
+ foo: bar
+php: |
+ array('collection' => array('key' => array('a', 'b', 'c')), 'foo' => 'bar')
+---
+test: Key/value after unindented collection (at the same level)
+brief: >
+ Key/value after unindented collection
+yaml: |
+ collection:
+ key:
+ - a
+ - b
+ - c
+ foo: bar
+php: |
+ array('collection' => array('key' => array('a', 'b', 'c'), 'foo' => 'bar'))
+---
+test: Shortcut Key after unindented collection
+brief: >
+ Key/value after unindented collection
+yaml: |
+ collection:
+ - key: foo
+ foo: bar
+php: |
+ array('collection' => array(array('key' => 'foo', 'foo' => 'bar')))
+---
+test: Shortcut Key after unindented collection with custom spaces
+brief: >
+ Key/value after unindented collection
+yaml: |
+ collection:
+ - key: foo
+ foo: bar
+php: |
+ array('collection' => array(array('key' => 'foo', 'foo' => 'bar')))
diff --git a/vendor/symfony/yaml/Tests/InlineTest.php b/vendor/symfony/yaml/Tests/InlineTest.php
new file mode 100644
index 0000000..7ba46bd
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/InlineTest.php
@@ -0,0 +1,760 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Yaml\Exception\ParseException;
+use Symfony\Component\Yaml\Inline;
+use Symfony\Component\Yaml\Tag\TaggedValue;
+use Symfony\Component\Yaml\Yaml;
+
+class InlineTest extends TestCase
+{
+ protected function setUp()
+ {
+ Inline::initialize(0, 0);
+ }
+
+ /**
+ * @dataProvider getTestsForParse
+ */
+ public function testParse($yaml, $value, $flags = 0)
+ {
+ $this->assertSame($value, Inline::parse($yaml, $flags), sprintf('::parse() converts an inline YAML to a PHP structure (%s)', $yaml));
+ }
+
+ /**
+ * @dataProvider getTestsForParseWithMapObjects
+ */
+ public function testParseWithMapObjects($yaml, $value, $flags = Yaml::PARSE_OBJECT_FOR_MAP)
+ {
+ $actual = Inline::parse($yaml, $flags);
+
+ $this->assertSame(serialize($value), serialize($actual));
+ }
+
+ /**
+ * @dataProvider getTestsForParsePhpConstants
+ */
+ public function testParsePhpConstants($yaml, $value)
+ {
+ $actual = Inline::parse($yaml, Yaml::PARSE_CONSTANT);
+
+ $this->assertSame($value, $actual);
+ }
+
+ public function getTestsForParsePhpConstants()
+ {
+ return array(
+ array('!php/const Symfony\Component\Yaml\Yaml::PARSE_CONSTANT', Yaml::PARSE_CONSTANT),
+ array('!php/const PHP_INT_MAX', PHP_INT_MAX),
+ array('[!php/const PHP_INT_MAX]', array(PHP_INT_MAX)),
+ array('{ foo: !php/const PHP_INT_MAX }', array('foo' => PHP_INT_MAX)),
+ array('!php/const NULL', null),
+ );
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage The constant "WRONG_CONSTANT" is not defined
+ */
+ public function testParsePhpConstantThrowsExceptionWhenUndefined()
+ {
+ Inline::parse('!php/const WRONG_CONSTANT', Yaml::PARSE_CONSTANT);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessageRegExp #The string "!php/const PHP_INT_MAX" could not be parsed as a constant.*#
+ */
+ public function testParsePhpConstantThrowsExceptionOnInvalidType()
+ {
+ Inline::parse('!php/const PHP_INT_MAX', Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE);
+ }
+
+ /**
+ * @dataProvider getTestsForDump
+ */
+ public function testDump($yaml, $value, $parseFlags = 0)
+ {
+ $this->assertEquals($yaml, Inline::dump($value), sprintf('::dump() converts a PHP structure to an inline YAML (%s)', $yaml));
+
+ $this->assertSame($value, Inline::parse(Inline::dump($value), $parseFlags), 'check consistency');
+ }
+
+ public function testDumpNumericValueWithLocale()
+ {
+ $locale = setlocale(LC_NUMERIC, 0);
+ if (false === $locale) {
+ $this->markTestSkipped('Your platform does not support locales.');
+ }
+
+ try {
+ $requiredLocales = array('fr_FR.UTF-8', 'fr_FR.UTF8', 'fr_FR.utf-8', 'fr_FR.utf8', 'French_France.1252');
+ if (false === setlocale(LC_NUMERIC, $requiredLocales)) {
+ $this->markTestSkipped('Could not set any of required locales: '.implode(', ', $requiredLocales));
+ }
+
+ $this->assertEquals('1.2', Inline::dump(1.2));
+ $this->assertContains('fr', strtolower(setlocale(LC_NUMERIC, 0)));
+ } finally {
+ setlocale(LC_NUMERIC, $locale);
+ }
+ }
+
+ public function testHashStringsResemblingExponentialNumericsShouldNotBeChangedToINF()
+ {
+ $value = '686e444';
+
+ $this->assertSame($value, Inline::parse(Inline::dump($value)));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Found unknown escape character "\V".
+ */
+ public function testParseScalarWithNonEscapedBlackslashShouldThrowException()
+ {
+ Inline::parse('"Foo\Var"');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseScalarWithNonEscapedBlackslashAtTheEndShouldThrowException()
+ {
+ Inline::parse('"Foo\\"');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseScalarWithIncorrectlyQuotedStringShouldThrowException()
+ {
+ $value = "'don't do somthin' like that'";
+ Inline::parse($value);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseScalarWithIncorrectlyDoubleQuotedStringShouldThrowException()
+ {
+ $value = '"don"t do somthin" like that"';
+ Inline::parse($value);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseInvalidMappingKeyShouldThrowException()
+ {
+ $value = '{ "foo " bar": "bar" }';
+ Inline::parse($value);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Colons must be followed by a space or an indication character (i.e. " ", ",", "[", "]", "{", "}")
+ */
+ public function testParseMappingKeyWithColonNotFollowedBySpace()
+ {
+ Inline::parse('{foo:""}');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseInvalidMappingShouldThrowException()
+ {
+ Inline::parse('[foo] bar');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseInvalidSequenceShouldThrowException()
+ {
+ Inline::parse('{ foo: bar } bar');
+ }
+
+ public function testParseScalarWithCorrectlyQuotedStringShouldReturnString()
+ {
+ $value = "'don''t do somthin'' like that'";
+ $expect = "don't do somthin' like that";
+
+ $this->assertSame($expect, Inline::parseScalar($value));
+ }
+
+ /**
+ * @dataProvider getDataForParseReferences
+ */
+ public function testParseReferences($yaml, $expected)
+ {
+ $this->assertSame($expected, Inline::parse($yaml, 0, array('var' => 'var-value')));
+ }
+
+ public function getDataForParseReferences()
+ {
+ return array(
+ 'scalar' => array('*var', 'var-value'),
+ 'list' => array('[ *var ]', array('var-value')),
+ 'list-in-list' => array('[[ *var ]]', array(array('var-value'))),
+ 'map-in-list' => array('[ { key: *var } ]', array(array('key' => 'var-value'))),
+ 'embedded-mapping-in-list' => array('[ key: *var ]', array(array('key' => 'var-value'))),
+ 'map' => array('{ key: *var }', array('key' => 'var-value')),
+ 'list-in-map' => array('{ key: [*var] }', array('key' => array('var-value'))),
+ 'map-in-map' => array('{ foo: { bar: *var } }', array('foo' => array('bar' => 'var-value'))),
+ );
+ }
+
+ public function testParseMapReferenceInSequence()
+ {
+ $foo = array(
+ 'a' => 'Steve',
+ 'b' => 'Clark',
+ 'c' => 'Brian',
+ );
+ $this->assertSame(array($foo), Inline::parse('[*foo]', 0, array('foo' => $foo)));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage A reference must contain at least one character at line 1.
+ */
+ public function testParseUnquotedAsterisk()
+ {
+ Inline::parse('{ foo: * }');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage A reference must contain at least one character at line 1.
+ */
+ public function testParseUnquotedAsteriskFollowedByAComment()
+ {
+ Inline::parse('{ foo: * #foo }');
+ }
+
+ /**
+ * @dataProvider getReservedIndicators
+ */
+ public function testParseUnquotedScalarStartingWithReservedIndicator($indicator)
+ {
+ if (method_exists($this, 'expectExceptionMessage')) {
+ $this->expectException(ParseException::class);
+ $this->expectExceptionMessage(sprintf('cannot start a plain scalar; you need to quote the scalar at line 1 (near "%sfoo").', $indicator));
+ } else {
+ $this->setExpectedException(ParseException::class, sprintf('cannot start a plain scalar; you need to quote the scalar at line 1 (near "%sfoo").', $indicator));
+ }
+
+ Inline::parse(sprintf('{ foo: %sfoo }', $indicator));
+ }
+
+ public function getReservedIndicators()
+ {
+ return array(array('@'), array('`'));
+ }
+
+ /**
+ * @dataProvider getScalarIndicators
+ */
+ public function testParseUnquotedScalarStartingWithScalarIndicator($indicator)
+ {
+ if (method_exists($this, 'expectExceptionMessage')) {
+ $this->expectException(ParseException::class);
+ $this->expectExceptionMessage(sprintf('cannot start a plain scalar; you need to quote the scalar at line 1 (near "%sfoo").', $indicator));
+ } else {
+ $this->setExpectedException(ParseException::class, sprintf('cannot start a plain scalar; you need to quote the scalar at line 1 (near "%sfoo").', $indicator));
+ }
+
+ Inline::parse(sprintf('{ foo: %sfoo }', $indicator));
+ }
+
+ public function getScalarIndicators()
+ {
+ return array(array('|'), array('>'), array('%'));
+ }
+
+ /**
+ * @dataProvider getDataForIsHash
+ */
+ public function testIsHash($array, $expected)
+ {
+ $this->assertSame($expected, Inline::isHash($array));
+ }
+
+ public function getDataForIsHash()
+ {
+ return array(
+ array(array(), false),
+ array(array(1, 2, 3), false),
+ array(array(2 => 1, 1 => 2, 0 => 3), true),
+ array(array('foo' => 1, 'bar' => 2), true),
+ );
+ }
+
+ public function getTestsForParse()
+ {
+ return array(
+ array('', ''),
+ array('null', null),
+ array('false', false),
+ array('true', true),
+ array('12', 12),
+ array('-12', -12),
+ array('1_2', 12),
+ array('_12', '_12'),
+ array('12_', 12),
+ array('"quoted string"', 'quoted string'),
+ array("'quoted string'", 'quoted string'),
+ array('12.30e+02', 12.30e+02),
+ array('123.45_67', 123.4567),
+ array('0x4D2', 0x4D2),
+ array('0x_4_D_2_', 0x4D2),
+ array('02333', 02333),
+ array('0_2_3_3_3', 02333),
+ array('.Inf', -log(0)),
+ array('-.Inf', log(0)),
+ array("'686e444'", '686e444'),
+ array('686e444', 646e444),
+ array('123456789123456789123456789123456789', '123456789123456789123456789123456789'),
+ array('"foo\r\nbar"', "foo\r\nbar"),
+ array("'foo#bar'", 'foo#bar'),
+ array("'foo # bar'", 'foo # bar'),
+ array("'#cfcfcf'", '#cfcfcf'),
+ array('::form_base.html.twig', '::form_base.html.twig'),
+
+ // Pre-YAML-1.2 booleans
+ array("'y'", 'y'),
+ array("'n'", 'n'),
+ array("'yes'", 'yes'),
+ array("'no'", 'no'),
+ array("'on'", 'on'),
+ array("'off'", 'off'),
+
+ array('2007-10-30', gmmktime(0, 0, 0, 10, 30, 2007)),
+ array('2007-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 2007)),
+ array('2007-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 2007)),
+ array('1960-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 1960)),
+ array('1730-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 1730)),
+
+ array('"a \\"string\\" with \'quoted strings inside\'"', 'a "string" with \'quoted strings inside\''),
+ array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''),
+
+ // sequences
+ // urls are no key value mapping. see #3609. Valid yaml "key: value" mappings require a space after the colon
+ array('[foo, http://urls.are/no/mappings, false, null, 12]', array('foo', 'http://urls.are/no/mappings', false, null, 12)),
+ array('[ foo , bar , false , null , 12 ]', array('foo', 'bar', false, null, 12)),
+ array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')),
+
+ // mappings
+ array('{foo: bar,bar: foo,"false": false, "null": null,integer: 12}', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
+ array('{ foo : bar, bar : foo, "false" : false, "null" : null, integer : 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
+ array('{foo: \'bar\', bar: \'foo: bar\'}', array('foo' => 'bar', 'bar' => 'foo: bar')),
+ array('{\'foo\': \'bar\', "bar": \'foo: bar\'}', array('foo' => 'bar', 'bar' => 'foo: bar')),
+ array('{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', array('foo\'' => 'bar', 'bar"' => 'foo: bar')),
+ array('{\'foo: \': \'bar\', "bar: ": \'foo: bar\'}', array('foo: ' => 'bar', 'bar: ' => 'foo: bar')),
+ array('{"foo:bar": "baz"}', array('foo:bar' => 'baz')),
+ array('{"foo":"bar"}', array('foo' => 'bar')),
+
+ // nested sequences and mappings
+ array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))),
+ array('[foo, {bar: foo}]', array('foo', array('bar' => 'foo'))),
+ array('{ foo: {bar: foo} }', array('foo' => array('bar' => 'foo'))),
+ array('{ foo: [bar, foo] }', array('foo' => array('bar', 'foo'))),
+ array('{ foo:{bar: foo} }', array('foo' => array('bar' => 'foo'))),
+ array('{ foo:[bar, foo] }', array('foo' => array('bar', 'foo'))),
+
+ array('[ foo, [ bar, foo ] ]', array('foo', array('bar', 'foo'))),
+
+ array('[{ foo: {bar: foo} }]', array(array('foo' => array('bar' => 'foo')))),
+
+ array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))),
+
+ array('[foo, {bar: foo, foo: [foo, {bar: foo}]}, [foo, {bar: foo}]]', array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo')))),
+
+ array('[foo, bar: { foo: bar }]', array('foo', '1' => array('bar' => array('foo' => 'bar')))),
+ array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')),
+ );
+ }
+
+ public function getTestsForParseWithMapObjects()
+ {
+ return array(
+ array('', ''),
+ array('null', null),
+ array('false', false),
+ array('true', true),
+ array('12', 12),
+ array('-12', -12),
+ array('"quoted string"', 'quoted string'),
+ array("'quoted string'", 'quoted string'),
+ array('12.30e+02', 12.30e+02),
+ array('0x4D2', 0x4D2),
+ array('02333', 02333),
+ array('.Inf', -log(0)),
+ array('-.Inf', log(0)),
+ array("'686e444'", '686e444'),
+ array('686e444', 646e444),
+ array('123456789123456789123456789123456789', '123456789123456789123456789123456789'),
+ array('"foo\r\nbar"', "foo\r\nbar"),
+ array("'foo#bar'", 'foo#bar'),
+ array("'foo # bar'", 'foo # bar'),
+ array("'#cfcfcf'", '#cfcfcf'),
+ array('::form_base.html.twig', '::form_base.html.twig'),
+
+ array('2007-10-30', gmmktime(0, 0, 0, 10, 30, 2007)),
+ array('2007-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 2007)),
+ array('2007-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 2007)),
+ array('1960-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 1960)),
+ array('1730-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 1730)),
+
+ array('"a \\"string\\" with \'quoted strings inside\'"', 'a "string" with \'quoted strings inside\''),
+ array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''),
+
+ // sequences
+ // urls are no key value mapping. see #3609. Valid yaml "key: value" mappings require a space after the colon
+ array('[foo, http://urls.are/no/mappings, false, null, 12]', array('foo', 'http://urls.are/no/mappings', false, null, 12)),
+ array('[ foo , bar , false , null , 12 ]', array('foo', 'bar', false, null, 12)),
+ array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')),
+
+ // mappings
+ array('{foo: bar,bar: foo,"false": false,"null": null,integer: 12}', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12), Yaml::PARSE_OBJECT_FOR_MAP),
+ array('{ foo : bar, bar : foo, "false" : false, "null" : null, integer : 12 }', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12), Yaml::PARSE_OBJECT_FOR_MAP),
+ array('{foo: \'bar\', bar: \'foo: bar\'}', (object) array('foo' => 'bar', 'bar' => 'foo: bar')),
+ array('{\'foo\': \'bar\', "bar": \'foo: bar\'}', (object) array('foo' => 'bar', 'bar' => 'foo: bar')),
+ array('{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', (object) array('foo\'' => 'bar', 'bar"' => 'foo: bar')),
+ array('{\'foo: \': \'bar\', "bar: ": \'foo: bar\'}', (object) array('foo: ' => 'bar', 'bar: ' => 'foo: bar')),
+ array('{"foo:bar": "baz"}', (object) array('foo:bar' => 'baz')),
+ array('{"foo":"bar"}', (object) array('foo' => 'bar')),
+
+ // nested sequences and mappings
+ array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))),
+ array('[foo, {bar: foo}]', array('foo', (object) array('bar' => 'foo'))),
+ array('{ foo: {bar: foo} }', (object) array('foo' => (object) array('bar' => 'foo'))),
+ array('{ foo: [bar, foo] }', (object) array('foo' => array('bar', 'foo'))),
+
+ array('[ foo, [ bar, foo ] ]', array('foo', array('bar', 'foo'))),
+
+ array('[{ foo: {bar: foo} }]', array((object) array('foo' => (object) array('bar' => 'foo')))),
+
+ array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))),
+
+ array('[foo, {bar: foo, foo: [foo, {bar: foo}]}, [foo, {bar: foo}]]', array('foo', (object) array('bar' => 'foo', 'foo' => array('foo', (object) array('bar' => 'foo'))), array('foo', (object) array('bar' => 'foo')))),
+
+ array('[foo, bar: { foo: bar }]', array('foo', '1' => (object) array('bar' => (object) array('foo' => 'bar')))),
+ array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', (object) array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')),
+
+ array('{}', new \stdClass()),
+ array('{ foo : bar, bar : {} }', (object) array('foo' => 'bar', 'bar' => new \stdClass())),
+ array('{ foo : [], bar : {} }', (object) array('foo' => array(), 'bar' => new \stdClass())),
+ array('{foo: \'bar\', bar: {} }', (object) array('foo' => 'bar', 'bar' => new \stdClass())),
+ array('{\'foo\': \'bar\', "bar": {}}', (object) array('foo' => 'bar', 'bar' => new \stdClass())),
+ array('{\'foo\': \'bar\', "bar": \'{}\'}', (object) array('foo' => 'bar', 'bar' => '{}')),
+
+ array('[foo, [{}, {}]]', array('foo', array(new \stdClass(), new \stdClass()))),
+ array('[foo, [[], {}]]', array('foo', array(array(), new \stdClass()))),
+ array('[foo, [[{}, {}], {}]]', array('foo', array(array(new \stdClass(), new \stdClass()), new \stdClass()))),
+ array('[foo, {bar: {}}]', array('foo', '1' => (object) array('bar' => new \stdClass()))),
+ );
+ }
+
+ public function getTestsForDump()
+ {
+ return array(
+ array('null', null),
+ array('false', false),
+ array('true', true),
+ array('12', 12),
+ array("'1_2'", '1_2'),
+ array('_12', '_12'),
+ array("'12_'", '12_'),
+ array("'quoted string'", 'quoted string'),
+ array('!!float 1230', 12.30e+02),
+ array('1234', 0x4D2),
+ array('1243', 02333),
+ array("'0x_4_D_2_'", '0x_4_D_2_'),
+ array("'0_2_3_3_3'", '0_2_3_3_3'),
+ array('.Inf', -log(0)),
+ array('-.Inf', log(0)),
+ array("'686e444'", '686e444'),
+ array('"foo\r\nbar"', "foo\r\nbar"),
+ array("'foo#bar'", 'foo#bar'),
+ array("'foo # bar'", 'foo # bar'),
+ array("'#cfcfcf'", '#cfcfcf'),
+
+ array("'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''),
+
+ array("'-dash'", '-dash'),
+ array("'-'", '-'),
+
+ // Pre-YAML-1.2 booleans
+ array("'y'", 'y'),
+ array("'n'", 'n'),
+ array("'yes'", 'yes'),
+ array("'no'", 'no'),
+ array("'on'", 'on'),
+ array("'off'", 'off'),
+
+ // sequences
+ array('[foo, bar, false, null, 12]', array('foo', 'bar', false, null, 12)),
+ array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')),
+
+ // mappings
+ array('{ foo: bar, bar: foo, \'false\': false, \'null\': null, integer: 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
+ array('{ foo: bar, bar: \'foo: bar\' }', array('foo' => 'bar', 'bar' => 'foo: bar')),
+
+ // nested sequences and mappings
+ array('[foo, [bar, foo]]', array('foo', array('bar', 'foo'))),
+
+ array('[foo, [bar, [foo, [bar, foo]], foo]]', array('foo', array('bar', array('foo', array('bar', 'foo')), 'foo'))),
+
+ array('{ foo: { bar: foo } }', array('foo' => array('bar' => 'foo'))),
+
+ array('[foo, { bar: foo }]', array('foo', array('bar' => 'foo'))),
+
+ array('[foo, { bar: foo, foo: [foo, { bar: foo }] }, [foo, { bar: foo }]]', array('foo', array('bar' => 'foo', 'foo' => array('foo', array('bar' => 'foo'))), array('foo', array('bar' => 'foo')))),
+
+ array('[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', array('foo', '@foo.baz', array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, '@service_container')),
+
+ array('{ foo: { bar: { 1: 2, baz: 3 } } }', array('foo' => array('bar' => array(1 => 2, 'baz' => 3)))),
+ );
+ }
+
+ /**
+ * @dataProvider getTimestampTests
+ */
+ public function testParseTimestampAsUnixTimestampByDefault($yaml, $year, $month, $day, $hour, $minute, $second)
+ {
+ $this->assertSame(gmmktime($hour, $minute, $second, $month, $day, $year), Inline::parse($yaml));
+ }
+
+ /**
+ * @dataProvider getTimestampTests
+ */
+ public function testParseTimestampAsDateTimeObject($yaml, $year, $month, $day, $hour, $minute, $second, $timezone)
+ {
+ $expected = new \DateTime($yaml);
+ $expected->setTimeZone(new \DateTimeZone('UTC'));
+ $expected->setDate($year, $month, $day);
+ $expected->setTime($hour, $minute, $second, 1000000 * ($second - (int) $second));
+
+ $date = Inline::parse($yaml, Yaml::PARSE_DATETIME);
+ $this->assertEquals($expected, $date);
+ $this->assertSame($timezone, $date->format('O'));
+ }
+
+ public function getTimestampTests()
+ {
+ return array(
+ 'canonical' => array('2001-12-15T02:59:43.1Z', 2001, 12, 15, 2, 59, 43.1, '+0000'),
+ 'ISO-8601' => array('2001-12-15t21:59:43.10-05:00', 2001, 12, 16, 2, 59, 43.1, '-0500'),
+ 'spaced' => array('2001-12-15 21:59:43.10 -5', 2001, 12, 16, 2, 59, 43.1, '-0500'),
+ 'date' => array('2001-12-15', 2001, 12, 15, 0, 0, 0, '+0000'),
+ );
+ }
+
+ /**
+ * @dataProvider getTimestampTests
+ */
+ public function testParseNestedTimestampListAsDateTimeObject($yaml, $year, $month, $day, $hour, $minute, $second)
+ {
+ $expected = new \DateTime($yaml);
+ $expected->setTimeZone(new \DateTimeZone('UTC'));
+ $expected->setDate($year, $month, $day);
+ $expected->setTime($hour, $minute, $second, 1000000 * ($second - (int) $second));
+
+ $expectedNested = array('nested' => array($expected));
+ $yamlNested = "{nested: [$yaml]}";
+
+ $this->assertEquals($expectedNested, Inline::parse($yamlNested, Yaml::PARSE_DATETIME));
+ }
+
+ /**
+ * @dataProvider getDateTimeDumpTests
+ */
+ public function testDumpDateTime($dateTime, $expected)
+ {
+ $this->assertSame($expected, Inline::dump($dateTime));
+ }
+
+ public function getDateTimeDumpTests()
+ {
+ $tests = array();
+
+ $dateTime = new \DateTime('2001-12-15 21:59:43', new \DateTimeZone('UTC'));
+ $tests['date-time-utc'] = array($dateTime, '2001-12-15T21:59:43+00:00');
+
+ $dateTime = new \DateTimeImmutable('2001-07-15 21:59:43', new \DateTimeZone('Europe/Berlin'));
+ $tests['immutable-date-time-europe-berlin'] = array($dateTime, '2001-07-15T21:59:43+02:00');
+
+ return $tests;
+ }
+
+ /**
+ * @dataProvider getBinaryData
+ */
+ public function testParseBinaryData($data)
+ {
+ $this->assertSame('Hello world', Inline::parse($data));
+ }
+
+ public function getBinaryData()
+ {
+ return array(
+ 'enclosed with double quotes' => array('!!binary "SGVsbG8gd29ybGQ="'),
+ 'enclosed with single quotes' => array("!!binary 'SGVsbG8gd29ybGQ='"),
+ 'containing spaces' => array('!!binary "SGVs bG8gd 29ybGQ="'),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidBinaryData
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseInvalidBinaryData($data, $expectedMessage)
+ {
+ if (method_exists($this, 'expectException')) {
+ $this->expectExceptionMessageRegExp($expectedMessage);
+ } else {
+ $this->setExpectedExceptionRegExp(ParseException::class, $expectedMessage);
+ }
+
+ Inline::parse($data);
+ }
+
+ public function getInvalidBinaryData()
+ {
+ return array(
+ 'length not a multiple of four' => array('!!binary "SGVsbG8d29ybGQ="', '/The normalized base64 encoded data \(data without whitespace characters\) length must be a multiple of four \(\d+ bytes given\)/'),
+ 'invalid characters' => array('!!binary "SGVsbG8#d29ybGQ="', '/The base64 encoded data \(.*\) contains invalid characters/'),
+ 'too many equals characters' => array('!!binary "SGVsbG8gd29yb==="', '/The base64 encoded data \(.*\) contains invalid characters/'),
+ 'misplaced equals character' => array('!!binary "SGVsbG8gd29ybG=Q"', '/The base64 encoded data \(.*\) contains invalid characters/'),
+ );
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Malformed inline YAML string: {this, is not, supported} at line 1.
+ */
+ public function testNotSupportedMissingValue()
+ {
+ Inline::parse('{this, is not, supported}');
+ }
+
+ public function testVeryLongQuotedStrings()
+ {
+ $longStringWithQuotes = str_repeat("x\r\n\\\"x\"x", 1000);
+
+ $yamlString = Inline::dump(array('longStringWithQuotes' => $longStringWithQuotes));
+ $arrayFromYaml = Inline::parse($yamlString);
+
+ $this->assertEquals($longStringWithQuotes, $arrayFromYaml['longStringWithQuotes']);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Missing mapping key
+ */
+ public function testMappingKeysCannotBeOmitted()
+ {
+ Inline::parse('{: foo}');
+ }
+
+ /**
+ * @dataProvider getTestsForNullValues
+ */
+ public function testParseMissingMappingValueAsNull($yaml, $expected)
+ {
+ $this->assertSame($expected, Inline::parse($yaml));
+ }
+
+ public function getTestsForNullValues()
+ {
+ return array(
+ 'null before closing curly brace' => array('{foo:}', array('foo' => null)),
+ 'null before comma' => array('{foo:, bar: baz}', array('foo' => null, 'bar' => 'baz')),
+ );
+ }
+
+ public function testTheEmptyStringIsAValidMappingKey()
+ {
+ $this->assertSame(array('' => 'foo'), Inline::parse('{ "": foo }'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Implicit casting of incompatible mapping keys to strings is not supported. Quote your evaluable mapping keys instead
+ *
+ * @dataProvider getNotPhpCompatibleMappingKeyData
+ */
+ public function testImplicitStringCastingOfMappingKeysIsDeprecated($yaml, $expected)
+ {
+ $this->assertSame($expected, Inline::parse($yaml));
+ }
+
+ public function getNotPhpCompatibleMappingKeyData()
+ {
+ return array(
+ 'boolean-true' => array('{true: "foo"}', array('true' => 'foo')),
+ 'boolean-false' => array('{false: "foo"}', array('false' => 'foo')),
+ 'null' => array('{null: "foo"}', array('null' => 'foo')),
+ 'float' => array('{0.25: "foo"}', array('0.25' => 'foo')),
+ );
+ }
+
+ public function testTagWithoutValueInSequence()
+ {
+ $value = Inline::parse('[!foo]', Yaml::PARSE_CUSTOM_TAGS);
+
+ $this->assertInstanceOf(TaggedValue::class, $value[0]);
+ $this->assertSame('foo', $value[0]->getTag());
+ $this->assertSame('', $value[0]->getValue());
+ }
+
+ public function testTagWithEmptyValueInSequence()
+ {
+ $value = Inline::parse('[!foo ""]', Yaml::PARSE_CUSTOM_TAGS);
+
+ $this->assertInstanceOf(TaggedValue::class, $value[0]);
+ $this->assertSame('foo', $value[0]->getTag());
+ $this->assertSame('', $value[0]->getValue());
+ }
+
+ public function testTagWithoutValueInMapping()
+ {
+ $value = Inline::parse('{foo: !bar}', Yaml::PARSE_CUSTOM_TAGS);
+
+ $this->assertInstanceOf(TaggedValue::class, $value['foo']);
+ $this->assertSame('bar', $value['foo']->getTag());
+ $this->assertSame('', $value['foo']->getValue());
+ }
+
+ public function testTagWithEmptyValueInMapping()
+ {
+ $value = Inline::parse('{foo: !bar ""}', Yaml::PARSE_CUSTOM_TAGS);
+
+ $this->assertInstanceOf(TaggedValue::class, $value['foo']);
+ $this->assertSame('bar', $value['foo']->getTag());
+ $this->assertSame('', $value['foo']->getValue());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Unexpected end of line, expected one of ",}" at line 1 (near "{abc: 'def'").
+ */
+ public function testUnfinishedInlineMap()
+ {
+ Inline::parse("{abc: 'def'");
+ }
+}
diff --git a/vendor/symfony/yaml/Tests/ParseExceptionTest.php b/vendor/symfony/yaml/Tests/ParseExceptionTest.php
new file mode 100644
index 0000000..39579ed
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/ParseExceptionTest.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Yaml\Exception\ParseException;
+
+class ParseExceptionTest extends TestCase
+{
+ public function testGetMessage()
+ {
+ $exception = new ParseException('Error message', 42, 'foo: bar', '/var/www/app/config.yml');
+ $message = 'Error message in "/var/www/app/config.yml" at line 42 (near "foo: bar")';
+
+ $this->assertEquals($message, $exception->getMessage());
+ }
+
+ public function testGetMessageWithUnicodeInFilename()
+ {
+ $exception = new ParseException('Error message', 42, 'foo: bar', 'äöü.yml');
+ $message = 'Error message in "äöü.yml" at line 42 (near "foo: bar")';
+
+ $this->assertEquals($message, $exception->getMessage());
+ }
+}
diff --git a/vendor/symfony/yaml/Tests/ParserTest.php b/vendor/symfony/yaml/Tests/ParserTest.php
new file mode 100644
index 0000000..16ad0af
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/ParserTest.php
@@ -0,0 +1,2104 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Yaml\Exception\ParseException;
+use Symfony\Component\Yaml\Parser;
+use Symfony\Component\Yaml\Tag\TaggedValue;
+use Symfony\Component\Yaml\Yaml;
+
+class ParserTest extends TestCase
+{
+ /** @var Parser */
+ protected $parser;
+
+ protected function setUp()
+ {
+ $this->parser = new Parser();
+ }
+
+ protected function tearDown()
+ {
+ $this->parser = null;
+
+ chmod(__DIR__.'/Fixtures/not_readable.yml', 0644);
+ }
+
+ /**
+ * @dataProvider getDataFormSpecifications
+ */
+ public function testSpecifications($expected, $yaml, $comment)
+ {
+ $this->assertEquals($expected, var_export($this->parser->parse($yaml), true), $comment);
+ }
+
+ public function getDataFormSpecifications()
+ {
+ return $this->loadTestsFromFixtureFiles('index.yml');
+ }
+
+ public function getNonStringMappingKeysData()
+ {
+ return $this->loadTestsFromFixtureFiles('nonStringKeys.yml');
+ }
+
+ public function testTabsInYaml()
+ {
+ // test tabs in YAML
+ $yamls = array(
+ "foo:\n bar",
+ "foo:\n bar",
+ "foo:\n bar",
+ "foo:\n bar",
+ );
+
+ foreach ($yamls as $yaml) {
+ try {
+ $content = $this->parser->parse($yaml);
+
+ $this->fail('YAML files must not contain tabs');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\Exception', $e, 'YAML files must not contain tabs');
+ $this->assertEquals('A YAML file cannot contain tabs as indentation at line 2 (near "'.strpbrk($yaml, "\t").'").', $e->getMessage(), 'YAML files must not contain tabs');
+ }
+ }
+ }
+
+ public function testEndOfTheDocumentMarker()
+ {
+ $yaml = <<<'EOF'
+--- %YAML:1.0
+foo
+...
+EOF;
+
+ $this->assertEquals('foo', $this->parser->parse($yaml));
+ }
+
+ public function getBlockChompingTests()
+ {
+ $tests = array();
+
+ $yaml = <<<'EOF'
+foo: |-
+ one
+ two
+bar: |-
+ one
+ two
+
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo",
+ 'bar' => "one\ntwo",
+ );
+ $tests['Literal block chomping strip with single trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |-
+ one
+ two
+
+bar: |-
+ one
+ two
+
+
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo",
+ 'bar' => "one\ntwo",
+ );
+ $tests['Literal block chomping strip with multiple trailing newlines'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+{}
+
+
+EOF;
+ $expected = array();
+ $tests['Literal block chomping strip with multiple trailing newlines after a 1-liner'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |-
+ one
+ two
+bar: |-
+ one
+ two
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo",
+ 'bar' => "one\ntwo",
+ );
+ $tests['Literal block chomping strip without trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |
+ one
+ two
+bar: |
+ one
+ two
+
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo\n",
+ 'bar' => "one\ntwo\n",
+ );
+ $tests['Literal block chomping clip with single trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |
+ one
+ two
+
+bar: |
+ one
+ two
+
+
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo\n",
+ 'bar' => "one\ntwo\n",
+ );
+ $tests['Literal block chomping clip with multiple trailing newlines'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo:
+- bar: |
+ one
+
+ two
+EOF;
+ $expected = array(
+ 'foo' => array(
+ array(
+ 'bar' => "one\n\ntwo",
+ ),
+ ),
+ );
+ $tests['Literal block chomping clip with embedded blank line inside unindented collection'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |
+ one
+ two
+bar: |
+ one
+ two
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo\n",
+ 'bar' => "one\ntwo",
+ );
+ $tests['Literal block chomping clip without trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |+
+ one
+ two
+bar: |+
+ one
+ two
+
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo\n",
+ 'bar' => "one\ntwo\n",
+ );
+ $tests['Literal block chomping keep with single trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |+
+ one
+ two
+
+bar: |+
+ one
+ two
+
+
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo\n\n",
+ 'bar' => "one\ntwo\n\n",
+ );
+ $tests['Literal block chomping keep with multiple trailing newlines'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: |+
+ one
+ two
+bar: |+
+ one
+ two
+EOF;
+ $expected = array(
+ 'foo' => "one\ntwo\n",
+ 'bar' => "one\ntwo",
+ );
+ $tests['Literal block chomping keep without trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >-
+ one
+ two
+bar: >-
+ one
+ two
+
+EOF;
+ $expected = array(
+ 'foo' => 'one two',
+ 'bar' => 'one two',
+ );
+ $tests['Folded block chomping strip with single trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >-
+ one
+ two
+
+bar: >-
+ one
+ two
+
+
+EOF;
+ $expected = array(
+ 'foo' => 'one two',
+ 'bar' => 'one two',
+ );
+ $tests['Folded block chomping strip with multiple trailing newlines'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >-
+ one
+ two
+bar: >-
+ one
+ two
+EOF;
+ $expected = array(
+ 'foo' => 'one two',
+ 'bar' => 'one two',
+ );
+ $tests['Folded block chomping strip without trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >
+ one
+ two
+bar: >
+ one
+ two
+
+EOF;
+ $expected = array(
+ 'foo' => "one two\n",
+ 'bar' => "one two\n",
+ );
+ $tests['Folded block chomping clip with single trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >
+ one
+ two
+
+bar: >
+ one
+ two
+
+
+EOF;
+ $expected = array(
+ 'foo' => "one two\n",
+ 'bar' => "one two\n",
+ );
+ $tests['Folded block chomping clip with multiple trailing newlines'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >
+ one
+ two
+bar: >
+ one
+ two
+EOF;
+ $expected = array(
+ 'foo' => "one two\n",
+ 'bar' => 'one two',
+ );
+ $tests['Folded block chomping clip without trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >+
+ one
+ two
+bar: >+
+ one
+ two
+
+EOF;
+ $expected = array(
+ 'foo' => "one two\n",
+ 'bar' => "one two\n",
+ );
+ $tests['Folded block chomping keep with single trailing newline'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >+
+ one
+ two
+
+bar: >+
+ one
+ two
+
+
+EOF;
+ $expected = array(
+ 'foo' => "one two\n\n",
+ 'bar' => "one two\n\n",
+ );
+ $tests['Folded block chomping keep with multiple trailing newlines'] = array($expected, $yaml);
+
+ $yaml = <<<'EOF'
+foo: >+
+ one
+ two
+bar: >+
+ one
+ two
+EOF;
+ $expected = array(
+ 'foo' => "one two\n",
+ 'bar' => 'one two',
+ );
+ $tests['Folded block chomping keep without trailing newline'] = array($expected, $yaml);
+
+ return $tests;
+ }
+
+ /**
+ * @dataProvider getBlockChompingTests
+ */
+ public function testBlockChomping($expected, $yaml)
+ {
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
+ /**
+ * Regression test for issue #7989.
+ *
+ * @see https://github.com/symfony/symfony/issues/7989
+ */
+ public function testBlockLiteralWithLeadingNewlines()
+ {
+ $yaml = <<<'EOF'
+foo: |-
+
+
+ bar
+
+EOF;
+ $expected = array(
+ 'foo' => "\n\nbar",
+ );
+
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
+ public function testObjectSupportEnabled()
+ {
+ $input = <<<'EOF'
+foo: !php/object O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";}
+bar: 1
+EOF;
+ $this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, Yaml::PARSE_OBJECT), '->parse() is able to parse objects');
+ }
+
+ public function testObjectSupportDisabledButNoExceptions()
+ {
+ $input = <<<'EOF'
+foo: !php/object O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";}
+bar: 1
+EOF;
+ $this->assertEquals(array('foo' => null, 'bar' => 1), $this->parser->parse($input), '->parse() does not parse objects');
+ }
+
+ /**
+ * @dataProvider getObjectForMapTests
+ */
+ public function testObjectForMap($yaml, $expected)
+ {
+ $flags = Yaml::PARSE_OBJECT_FOR_MAP;
+
+ $this->assertEquals($expected, $this->parser->parse($yaml, $flags));
+ }
+
+ public function getObjectForMapTests()
+ {
+ $tests = array();
+
+ $yaml = <<<'EOF'
+foo:
+ fiz: [cat]
+EOF;
+ $expected = new \stdClass();
+ $expected->foo = new \stdClass();
+ $expected->foo->fiz = array('cat');
+ $tests['mapping'] = array($yaml, $expected);
+
+ $yaml = '{ "foo": "bar", "fiz": "cat" }';
+ $expected = new \stdClass();
+ $expected->foo = 'bar';
+ $expected->fiz = 'cat';
+ $tests['inline-mapping'] = array($yaml, $expected);
+
+ $yaml = "foo: bar\nbaz: foobar";
+ $expected = new \stdClass();
+ $expected->foo = 'bar';
+ $expected->baz = 'foobar';
+ $tests['object-for-map-is-applied-after-parsing'] = array($yaml, $expected);
+
+ $yaml = <<<'EOT'
+array:
+ - key: one
+ - key: two
+EOT;
+ $expected = new \stdClass();
+ $expected->array = array();
+ $expected->array[0] = new \stdClass();
+ $expected->array[0]->key = 'one';
+ $expected->array[1] = new \stdClass();
+ $expected->array[1]->key = 'two';
+ $tests['nest-map-and-sequence'] = array($yaml, $expected);
+
+ $yaml = <<<'YAML'
+map:
+ 1: one
+ 2: two
+YAML;
+ $expected = new \stdClass();
+ $expected->map = new \stdClass();
+ $expected->map->{1} = 'one';
+ $expected->map->{2} = 'two';
+ $tests['numeric-keys'] = array($yaml, $expected);
+
+ $yaml = <<<'YAML'
+map:
+ '0': one
+ '1': two
+YAML;
+ $expected = new \stdClass();
+ $expected->map = new \stdClass();
+ $expected->map->{0} = 'one';
+ $expected->map->{1} = 'two';
+ $tests['zero-indexed-numeric-keys'] = array($yaml, $expected);
+
+ return $tests;
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testObjectsSupportDisabledWithExceptions()
+ {
+ $yaml = <<<'EOF'
+foo: !php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";}
+bar: 1
+EOF;
+
+ $this->parser->parse($yaml, Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE);
+ }
+
+ public function testCanParseContentWithTrailingSpaces()
+ {
+ $yaml = "items: \n foo: bar";
+
+ $expected = array(
+ 'items' => array('foo' => 'bar'),
+ );
+
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
+ /**
+ * @requires extension iconv
+ */
+ public function testNonUtf8Exception()
+ {
+ $yamls = array(
+ iconv('UTF-8', 'ISO-8859-1', "foo: 'äöüß'"),
+ iconv('UTF-8', 'ISO-8859-15', "euro: '€'"),
+ iconv('UTF-8', 'CP1252', "cp1252: '©ÉÇáñ'"),
+ );
+
+ foreach ($yamls as $yaml) {
+ try {
+ $this->parser->parse($yaml);
+
+ $this->fail('charsets other than UTF-8 are rejected.');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('Symfony\Component\Yaml\Exception\ParseException', $e, 'charsets other than UTF-8 are rejected.');
+ }
+ }
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testUnindentedCollectionException()
+ {
+ $yaml = <<<'EOF'
+
+collection:
+-item1
+-item2
+-item3
+
+EOF;
+
+ $this->parser->parse($yaml);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testShortcutKeyUnindentedCollectionException()
+ {
+ $yaml = <<<'EOF'
+
+collection:
+- key: foo
+ foo: bar
+
+EOF;
+
+ $this->parser->parse($yaml);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessageRegExp /^Multiple documents are not supported.+/
+ */
+ public function testMultipleDocumentsNotSupportedException()
+ {
+ Yaml::parse(<<<'EOL'
+# Ranking of 1998 home runs
+---
+- Mark McGwire
+- Sammy Sosa
+- Ken Griffey
+
+# Team ranking
+---
+- Chicago Cubs
+- St Louis Cardinals
+EOL
+ );
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testSequenceInAMapping()
+ {
+ Yaml::parse(<<<'EOF'
+yaml:
+ hash: me
+ - array stuff
+EOF
+ );
+ }
+
+ public function testSequenceInMappingStartedBySingleDashLine()
+ {
+ $yaml = <<<'EOT'
+a:
+-
+ b:
+ -
+ bar: baz
+- foo
+d: e
+EOT;
+ $expected = array(
+ 'a' => array(
+ array(
+ 'b' => array(
+ array(
+ 'bar' => 'baz',
+ ),
+ ),
+ ),
+ 'foo',
+ ),
+ 'd' => 'e',
+ );
+
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
+ public function testSequenceFollowedByCommentEmbeddedInMapping()
+ {
+ $yaml = <<<'EOT'
+a:
+ b:
+ - c
+# comment
+ d: e
+EOT;
+ $expected = array(
+ 'a' => array(
+ 'b' => array('c'),
+ 'd' => 'e',
+ ),
+ );
+
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
+ public function testNonStringFollowedByCommentEmbeddedInMapping()
+ {
+ $yaml = <<<'EOT'
+a:
+ b:
+ {}
+# comment
+ d:
+ 1.1
+# another comment
+EOT;
+ $expected = array(
+ 'a' => array(
+ 'b' => array(),
+ 'd' => 1.1,
+ ),
+ );
+
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
+ public function getParseExceptionNotAffectedMultiLineStringLastResortParsing()
+ {
+ $tests = array();
+
+ $yaml = <<<'EOT'
+a
+ b:
+EOT;
+ $tests['parse error on first line'] = array($yaml);
+
+ $yaml = <<<'EOT'
+a
+
+b
+ c:
+EOT;
+ $tests['parse error due to inconsistent indentation'] = array($yaml);
+
+ $yaml = <<<'EOT'
+ & * ! | > ' " % @ ` #, { asd a;sdasd }-@^qw3
+EOT;
+ $tests['symfony/symfony/issues/22967#issuecomment-322067742'] = array($yaml);
+
+ return $tests;
+ }
+
+ /**
+ * @dataProvider getParseExceptionNotAffectedMultiLineStringLastResortParsing
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseExceptionNotAffectedByMultiLineStringLastResortParsing($yaml)
+ {
+ $this->parser->parse($yaml);
+ }
+
+ public function testMultiLineStringLastResortParsing()
+ {
+ $yaml = <<<'EOT'
+test:
+ You can have things that don't look like strings here
+ true
+ yes you can
+EOT;
+ $expected = array(
+ 'test' => 'You can have things that don\'t look like strings here true yes you can',
+ );
+
+ $this->assertSame($expected, $this->parser->parse($yaml));
+
+ $yaml = <<<'EOT'
+a:
+ b
+ c
+EOT;
+ $expected = array(
+ 'a' => 'b c',
+ );
+
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testMappingInASequence()
+ {
+ Yaml::parse(<<<'EOF'
+yaml:
+ - array stuff
+ hash: me
+EOF
+ );
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage missing colon
+ */
+ public function testScalarInSequence()
+ {
+ Yaml::parse(<<<'EOF'
+foo:
+ - bar
+"missing colon"
+ foo: bar
+EOF
+ );
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Duplicate key "child" detected
+ *
+ * > It is an error for two equal keys to appear in the same mapping node.
+ * > In such a case the YAML processor may continue, ignoring the second
+ * > `key: value` pair and issuing an appropriate warning. This strategy
+ * > preserves a consistent information model for one-pass and random access
+ * > applications.
+ *
+ * @see http://yaml.org/spec/1.2/spec.html#id2759572
+ * @see http://yaml.org/spec/1.1/#id932806
+ */
+ public function testMappingDuplicateKeyBlock()
+ {
+ $input = <<<'EOD'
+parent:
+ child: first
+ child: duplicate
+parent:
+ child: duplicate
+ child: duplicate
+EOD;
+ $expected = array(
+ 'parent' => array(
+ 'child' => 'first',
+ ),
+ );
+ $this->assertSame($expected, Yaml::parse($input));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Duplicate key "child" detected
+ */
+ public function testMappingDuplicateKeyFlow()
+ {
+ $input = <<<'EOD'
+parent: { child: first, child: duplicate }
+parent: { child: duplicate, child: duplicate }
+EOD;
+ $expected = array(
+ 'parent' => array(
+ 'child' => 'first',
+ ),
+ );
+ $this->assertSame($expected, Yaml::parse($input));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @dataProvider getParseExceptionOnDuplicateData
+ */
+ public function testParseExceptionOnDuplicate($input, $duplicateKey, $lineNumber)
+ {
+ $this->expectExceptionMessage(sprintf('Duplicate key "%s" detected at line %d', $duplicateKey, $lineNumber));
+
+ Yaml::parse($input);
+ }
+
+ public function getParseExceptionOnDuplicateData()
+ {
+ $tests = array();
+
+ $yaml = <<<EOD
+parent: { child: first, child: duplicate }
+EOD;
+ $tests[] = array($yaml, 'child', 1);
+
+ $yaml = <<<EOD
+parent:
+ child: first,
+ child: duplicate
+EOD;
+ $tests[] = array($yaml, 'child', 3);
+
+ $yaml = <<<EOD
+parent: { child: foo }
+parent: { child: bar }
+EOD;
+ $tests[] = array($yaml, 'parent', 2);
+
+ $yaml = <<<EOD
+parent: { child_mapping: { value: bar}, child_mapping: { value: bar} }
+EOD;
+ $tests[] = array($yaml, 'child_mapping', 1);
+
+ $yaml = <<<EOD
+parent:
+ child_mapping:
+ value: bar
+ child_mapping:
+ value: bar
+EOD;
+ $tests[] = array($yaml, 'child_mapping', 4);
+
+ $yaml = <<<EOD
+parent: { child_sequence: ['key1', 'key2', 'key3'], child_sequence: ['key1', 'key2', 'key3'] }
+EOD;
+ $tests[] = array($yaml, 'child_sequence', 1);
+
+ $yaml = <<<EOD
+parent:
+ child_sequence:
+ - key1
+ - key2
+ - key3
+ child_sequence:
+ - key1
+ - key2
+ - key3
+EOD;
+ $tests[] = array($yaml, 'child_sequence', 6);
+
+ return $tests;
+ }
+
+ public function testEmptyValue()
+ {
+ $input = <<<'EOF'
+hash:
+EOF;
+
+ $this->assertEquals(array('hash' => null), Yaml::parse($input));
+ }
+
+ public function testCommentAtTheRootIndent()
+ {
+ $this->assertEquals(array(
+ 'services' => array(
+ 'app.foo_service' => array(
+ 'class' => 'Foo',
+ ),
+ 'app/bar_service' => array(
+ 'class' => 'Bar',
+ ),
+ ),
+ ), Yaml::parse(<<<'EOF'
+# comment 1
+services:
+# comment 2
+ # comment 3
+ app.foo_service:
+ class: Foo
+# comment 4
+ # comment 5
+ app/bar_service:
+ class: Bar
+EOF
+ ));
+ }
+
+ public function testStringBlockWithComments()
+ {
+ $this->assertEquals(array('content' => <<<'EOT'
+# comment 1
+header
+
+ # comment 2
+ <body>
+ <h1>title</h1>
+ </body>
+
+footer # comment3
+EOT
+ ), Yaml::parse(<<<'EOF'
+content: |
+ # comment 1
+ header
+
+ # comment 2
+ <body>
+ <h1>title</h1>
+ </body>
+
+ footer # comment3
+EOF
+ ));
+ }
+
+ public function testFoldedStringBlockWithComments()
+ {
+ $this->assertEquals(array(array('content' => <<<'EOT'
+# comment 1
+header
+
+ # comment 2
+ <body>
+ <h1>title</h1>
+ </body>
+
+footer # comment3
+EOT
+ )), Yaml::parse(<<<'EOF'
+-
+ content: |
+ # comment 1
+ header
+
+ # comment 2
+ <body>
+ <h1>title</h1>
+ </body>
+
+ footer # comment3
+EOF
+ ));
+ }
+
+ public function testNestedFoldedStringBlockWithComments()
+ {
+ $this->assertEquals(array(array(
+ 'title' => 'some title',
+ 'content' => <<<'EOT'
+# comment 1
+header
+
+ # comment 2
+ <body>
+ <h1>title</h1>
+ </body>
+
+footer # comment3
+EOT
+ )), Yaml::parse(<<<'EOF'
+-
+ title: some title
+ content: |
+ # comment 1
+ header
+
+ # comment 2
+ <body>
+ <h1>title</h1>
+ </body>
+
+ footer # comment3
+EOF
+ ));
+ }
+
+ public function testReferenceResolvingInInlineStrings()
+ {
+ $this->assertEquals(array(
+ 'var' => 'var-value',
+ 'scalar' => 'var-value',
+ 'list' => array('var-value'),
+ 'list_in_list' => array(array('var-value')),
+ 'map_in_list' => array(array('key' => 'var-value')),
+ 'embedded_mapping' => array(array('key' => 'var-value')),
+ 'map' => array('key' => 'var-value'),
+ 'list_in_map' => array('key' => array('var-value')),
+ 'map_in_map' => array('foo' => array('bar' => 'var-value')),
+ ), Yaml::parse(<<<'EOF'
+var: &var var-value
+scalar: *var
+list: [ *var ]
+list_in_list: [[ *var ]]
+map_in_list: [ { key: *var } ]
+embedded_mapping: [ key: *var ]
+map: { key: *var }
+list_in_map: { key: [*var] }
+map_in_map: { foo: { bar: *var } }
+EOF
+ ));
+ }
+
+ public function testYamlDirective()
+ {
+ $yaml = <<<'EOF'
+%YAML 1.2
+---
+foo: 1
+bar: 2
+EOF;
+ $this->assertEquals(array('foo' => 1, 'bar' => 2), $this->parser->parse($yaml));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Numeric keys are not supported. Quote your evaluable mapping keys instead
+ */
+ public function testFloatKeys()
+ {
+ $yaml = <<<'EOF'
+foo:
+ 1.2: "bar"
+ 1.3: "baz"
+EOF;
+
+ $this->parser->parse($yaml);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Non-string keys are not supported. Quote your evaluable mapping keys instead
+ */
+ public function testBooleanKeys()
+ {
+ $yaml = <<<'EOF'
+true: foo
+false: bar
+EOF;
+
+ $this->parser->parse($yaml);
+ }
+
+ public function testExplicitStringCasting()
+ {
+ $yaml = <<<'EOF'
+'1.2': "bar"
+!!str 1.3: "baz"
+
+'true': foo
+!!str false: bar
+
+!!str null: 'null'
+'~': 'null'
+EOF;
+
+ $expected = array(
+ '1.2' => 'bar',
+ '1.3' => 'baz',
+ 'true' => 'foo',
+ 'false' => 'bar',
+ 'null' => 'null',
+ '~' => 'null',
+ );
+
+ $this->assertEquals($expected, $this->parser->parse($yaml));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage A colon cannot be used in an unquoted mapping value
+ */
+ public function testColonInMappingValueException()
+ {
+ $yaml = <<<'EOF'
+foo: bar: baz
+EOF;
+
+ $this->parser->parse($yaml);
+ }
+
+ public function testColonInMappingValueExceptionNotTriggeredByColonInComment()
+ {
+ $yaml = <<<'EOT'
+foo:
+ bar: foobar # Note: a comment after a colon
+EOT;
+
+ $this->assertSame(array('foo' => array('bar' => 'foobar')), $this->parser->parse($yaml));
+ }
+
+ /**
+ * @dataProvider getCommentLikeStringInScalarBlockData
+ */
+ public function testCommentLikeStringsAreNotStrippedInBlockScalars($yaml, $expectedParserResult)
+ {
+ $this->assertSame($expectedParserResult, $this->parser->parse($yaml));
+ }
+
+ public function getCommentLikeStringInScalarBlockData()
+ {
+ $tests = array();
+
+ $yaml = <<<'EOT'
+pages:
+ -
+ title: some title
+ content: |
+ # comment 1
+ header
+
+ # comment 2
+ <body>
+ <h1>title</h1>
+ </body>
+
+ footer # comment3
+EOT;
+ $expected = array(
+ 'pages' => array(
+ array(
+ 'title' => 'some title',
+ 'content' => <<<'EOT'
+# comment 1
+header
+
+ # comment 2
+ <body>
+ <h1>title</h1>
+ </body>
+
+footer # comment3
+EOT
+ ,
+ ),
+ ),
+ );
+ $tests[] = array($yaml, $expected);
+
+ $yaml = <<<'EOT'
+test: |
+ foo
+ # bar
+ baz
+collection:
+ - one: |
+ foo
+ # bar
+ baz
+ - two: |
+ foo
+ # bar
+ baz
+EOT;
+ $expected = array(
+ 'test' => <<<'EOT'
+foo
+# bar
+baz
+
+EOT
+ ,
+ 'collection' => array(
+ array(
+ 'one' => <<<'EOT'
+foo
+# bar
+baz
+
+EOT
+ ,
+ ),
+ array(
+ 'two' => <<<'EOT'
+foo
+# bar
+baz
+EOT
+ ,
+ ),
+ ),
+ );
+ $tests[] = array($yaml, $expected);
+
+ $yaml = <<<'EOT'
+foo:
+ bar:
+ scalar-block: >
+ line1
+ line2>
+ baz:
+# comment
+ foobar: ~
+EOT;
+ $expected = array(
+ 'foo' => array(
+ 'bar' => array(
+ 'scalar-block' => "line1 line2>\n",
+ ),
+ 'baz' => array(
+ 'foobar' => null,
+ ),
+ ),
+ );
+ $tests[] = array($yaml, $expected);
+
+ $yaml = <<<'EOT'
+a:
+ b: hello
+# c: |
+# first row
+# second row
+ d: hello
+EOT;
+ $expected = array(
+ 'a' => array(
+ 'b' => 'hello',
+ 'd' => 'hello',
+ ),
+ );
+ $tests[] = array($yaml, $expected);
+
+ return $tests;
+ }
+
+ public function testBlankLinesAreParsedAsNewLinesInFoldedBlocks()
+ {
+ $yaml = <<<'EOT'
+test: >
+ <h2>A heading</h2>
+
+ <ul>
+ <li>a list</li>
+ <li>may be a good example</li>
+ </ul>
+EOT;
+
+ $this->assertSame(
+ array(
+ 'test' => <<<'EOT'
+<h2>A heading</h2>
+<ul> <li>a list</li> <li>may be a good example</li> </ul>
+EOT
+ ,
+ ),
+ $this->parser->parse($yaml)
+ );
+ }
+
+ public function testAdditionallyIndentedLinesAreParsedAsNewLinesInFoldedBlocks()
+ {
+ $yaml = <<<'EOT'
+test: >
+ <h2>A heading</h2>
+
+ <ul>
+ <li>a list</li>
+ <li>may be a good example</li>
+ </ul>
+EOT;
+
+ $this->assertSame(
+ array(
+ 'test' => <<<'EOT'
+<h2>A heading</h2>
+<ul>
+ <li>a list</li>
+ <li>may be a good example</li>
+</ul>
+EOT
+ ,
+ ),
+ $this->parser->parse($yaml)
+ );
+ }
+
+ /**
+ * @dataProvider getBinaryData
+ */
+ public function testParseBinaryData($data)
+ {
+ $this->assertSame(array('data' => 'Hello world'), $this->parser->parse($data));
+ }
+
+ public function getBinaryData()
+ {
+ return array(
+ 'enclosed with double quotes' => array('data: !!binary "SGVsbG8gd29ybGQ="'),
+ 'enclosed with single quotes' => array("data: !!binary 'SGVsbG8gd29ybGQ='"),
+ 'containing spaces' => array('data: !!binary "SGVs bG8gd 29ybGQ="'),
+ 'in block scalar' => array(
+ <<<'EOT'
+data: !!binary |
+ SGVsbG8gd29ybGQ=
+EOT
+ ),
+ 'containing spaces in block scalar' => array(
+ <<<'EOT'
+data: !!binary |
+ SGVs bG8gd 29ybGQ=
+EOT
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider getInvalidBinaryData
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ */
+ public function testParseInvalidBinaryData($data, $expectedMessage)
+ {
+ if (method_exists($this, 'expectException')) {
+ $this->expectExceptionMessageRegExp($expectedMessage);
+ } else {
+ $this->setExpectedExceptionRegExp(ParseException::class, $expectedMessage);
+ }
+
+ $this->parser->parse($data);
+ }
+
+ public function getInvalidBinaryData()
+ {
+ return array(
+ 'length not a multiple of four' => array('data: !!binary "SGVsbG8d29ybGQ="', '/The normalized base64 encoded data \(data without whitespace characters\) length must be a multiple of four \(\d+ bytes given\)/'),
+ 'invalid characters' => array('!!binary "SGVsbG8#d29ybGQ="', '/The base64 encoded data \(.*\) contains invalid characters/'),
+ 'too many equals characters' => array('data: !!binary "SGVsbG8gd29yb==="', '/The base64 encoded data \(.*\) contains invalid characters/'),
+ 'misplaced equals character' => array('data: !!binary "SGVsbG8gd29ybG=Q"', '/The base64 encoded data \(.*\) contains invalid characters/'),
+ 'length not a multiple of four in block scalar' => array(
+ <<<'EOT'
+data: !!binary |
+ SGVsbG8d29ybGQ=
+EOT
+ ,
+ '/The normalized base64 encoded data \(data without whitespace characters\) length must be a multiple of four \(\d+ bytes given\)/',
+ ),
+ 'invalid characters in block scalar' => array(
+ <<<'EOT'
+data: !!binary |
+ SGVsbG8#d29ybGQ=
+EOT
+ ,
+ '/The base64 encoded data \(.*\) contains invalid characters/',
+ ),
+ 'too many equals characters in block scalar' => array(
+ <<<'EOT'
+data: !!binary |
+ SGVsbG8gd29yb===
+EOT
+ ,
+ '/The base64 encoded data \(.*\) contains invalid characters/',
+ ),
+ 'misplaced equals character in block scalar' => array(
+ <<<'EOT'
+data: !!binary |
+ SGVsbG8gd29ybG=Q
+EOT
+ ,
+ '/The base64 encoded data \(.*\) contains invalid characters/',
+ ),
+ );
+ }
+
+ public function testParseDateAsMappingValue()
+ {
+ $yaml = <<<'EOT'
+date: 2002-12-14
+EOT;
+ $expectedDate = new \DateTime();
+ $expectedDate->setTimeZone(new \DateTimeZone('UTC'));
+ $expectedDate->setDate(2002, 12, 14);
+ $expectedDate->setTime(0, 0, 0);
+
+ $this->assertEquals(array('date' => $expectedDate), $this->parser->parse($yaml, Yaml::PARSE_DATETIME));
+ }
+
+ /**
+ * @param $lineNumber
+ * @param $yaml
+ * @dataProvider parserThrowsExceptionWithCorrectLineNumberProvider
+ */
+ public function testParserThrowsExceptionWithCorrectLineNumber($lineNumber, $yaml)
+ {
+ if (method_exists($this, 'expectException')) {
+ $this->expectException('\Symfony\Component\Yaml\Exception\ParseException');
+ $this->expectExceptionMessage(sprintf('Unexpected characters near "," at line %d (near "bar: "123",").', $lineNumber));
+ } else {
+ $this->setExpectedException('\Symfony\Component\Yaml\Exception\ParseException', sprintf('Unexpected characters near "," at line %d (near "bar: "123",").', $lineNumber));
+ }
+
+ $this->parser->parse($yaml);
+ }
+
+ public function parserThrowsExceptionWithCorrectLineNumberProvider()
+ {
+ return array(
+ array(
+ 4,
+ <<<'YAML'
+foo:
+ -
+ # bar
+ bar: "123",
+YAML
+ ),
+ array(
+ 5,
+ <<<'YAML'
+foo:
+ -
+ # bar
+ # bar
+ bar: "123",
+YAML
+ ),
+ array(
+ 8,
+ <<<'YAML'
+foo:
+ -
+ # foobar
+ baz: 123
+bar:
+ -
+ # bar
+ bar: "123",
+YAML
+ ),
+ array(
+ 10,
+ <<<'YAML'
+foo:
+ -
+ # foobar
+ # foobar
+ baz: 123
+bar:
+ -
+ # bar
+ # bar
+ bar: "123",
+YAML
+ ),
+ );
+ }
+
+ public function testParseMultiLineQuotedString()
+ {
+ $yaml = <<<EOT
+foo: "bar
+ baz
+ foobar
+foo"
+bar: baz
+EOT;
+
+ $this->assertSame(array('foo' => 'bar baz foobar foo', 'bar' => 'baz'), $this->parser->parse($yaml));
+ }
+
+ public function testMultiLineQuotedStringWithTrailingBackslash()
+ {
+ $yaml = <<<YAML
+foobar:
+ "foo\
+ bar"
+YAML;
+
+ $this->assertSame(array('foobar' => 'foobar'), $this->parser->parse($yaml));
+ }
+
+ public function testCommentCharactersInMultiLineQuotedStrings()
+ {
+ $yaml = <<<YAML
+foo:
+ foobar: 'foo
+ #bar'
+ bar: baz
+YAML;
+ $expected = array(
+ 'foo' => array(
+ 'foobar' => 'foo #bar',
+ 'bar' => 'baz',
+ ),
+ );
+
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
+ public function testBlankLinesInQuotedMultiLineString()
+ {
+ $yaml = <<<YAML
+foobar: 'foo
+
+ bar'
+YAML;
+ $expected = array(
+ 'foobar' => "foo\nbar",
+ );
+
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
+ public function testParseMultiLineUnquotedString()
+ {
+ $yaml = <<<EOT
+foo: bar
+ baz
+ foobar
+ foo
+bar: baz
+EOT;
+
+ $this->assertSame(array('foo' => 'bar baz foobar foo', 'bar' => 'baz'), $this->parser->parse($yaml));
+ }
+
+ public function testParseMultiLineString()
+ {
+ $this->assertEquals("foo bar\nbaz", $this->parser->parse("foo\nbar\n\nbaz"));
+ }
+
+ /**
+ * @dataProvider multiLineDataProvider
+ */
+ public function testParseMultiLineMappingValue($yaml, $expected, $parseError)
+ {
+ $this->assertEquals($expected, $this->parser->parse($yaml));
+ }
+
+ public function multiLineDataProvider()
+ {
+ $tests = array();
+
+ $yaml = <<<'EOF'
+foo:
+- bar:
+ one
+
+ two
+ three
+EOF;
+ $expected = array(
+ 'foo' => array(
+ array(
+ 'bar' => "one\ntwo three",
+ ),
+ ),
+ );
+
+ $tests[] = array($yaml, $expected, false);
+
+ $yaml = <<<'EOF'
+bar
+"foo"
+EOF;
+ $expected = 'bar "foo"';
+
+ $tests[] = array($yaml, $expected, false);
+
+ $yaml = <<<'EOF'
+bar
+"foo
+EOF;
+ $expected = 'bar "foo';
+
+ $tests[] = array($yaml, $expected, false);
+
+ $yaml = <<<'EOF'
+bar
+
+'foo'
+EOF;
+ $expected = "bar\n'foo'";
+
+ $tests[] = array($yaml, $expected, false);
+
+ $yaml = <<<'EOF'
+bar
+
+foo'
+EOF;
+ $expected = "bar\nfoo'";
+
+ $tests[] = array($yaml, $expected, false);
+
+ return $tests;
+ }
+
+ public function testTaggedInlineMapping()
+ {
+ $this->assertEquals(new TaggedValue('foo', array('foo' => 'bar')), $this->parser->parse('!foo {foo: bar}', Yaml::PARSE_CUSTOM_TAGS));
+ }
+
+ /**
+ * @dataProvider taggedValuesProvider
+ */
+ public function testCustomTagSupport($expected, $yaml)
+ {
+ $this->assertEquals($expected, $this->parser->parse($yaml, Yaml::PARSE_CUSTOM_TAGS));
+ }
+
+ public function taggedValuesProvider()
+ {
+ return array(
+ 'scalars' => array(
+ array(
+ 'foo' => new TaggedValue('inline', 'bar'),
+ 'quz' => new TaggedValue('long', 'this is a long text'),
+ ),
+ <<<YAML
+foo: !inline bar
+quz: !long >
+ this is a long
+ text
+YAML
+ ),
+ 'sequences' => array(
+ array(new TaggedValue('foo', array('yaml')), new TaggedValue('quz', array('bar'))),
+ <<<YAML
+- !foo
+ - yaml
+- !quz [bar]
+YAML
+ ),
+ 'mappings' => array(
+ new TaggedValue('foo', array('foo' => new TaggedValue('quz', array('bar')), 'quz' => new TaggedValue('foo', array('quz' => 'bar')))),
+ <<<YAML
+!foo
+foo: !quz [bar]
+quz: !foo
+ quz: bar
+YAML
+ ),
+ 'inline' => array(
+ array(new TaggedValue('foo', array('foo', 'bar')), new TaggedValue('quz', array('foo' => 'bar', 'quz' => new TaggedValue('bar', array('one' => 'bar'))))),
+ <<<YAML
+- !foo [foo, bar]
+- !quz {foo: bar, quz: !bar {one: bar}}
+YAML
+ ),
+ 'spaces-around-tag-value-in-sequence' => array(
+ array(new TaggedValue('foo', 'bar')),
+ '[ !foo bar ]',
+ ),
+ );
+ }
+
+ public function testNonSpecificTagSupport()
+ {
+ $this->assertSame('12', $this->parser->parse('! 12'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Tags support is not enabled. Enable the `Yaml::PARSE_CUSTOM_TAGS` flag to use "!iterator" at line 1 (near "!iterator [foo]").
+ */
+ public function testCustomTagsDisabled()
+ {
+ $this->parser->parse('!iterator [foo]');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Tags support is not enabled. Enable the `Yaml::PARSE_CUSTOM_TAGS` flag to use "!iterator" at line 1 (near "!iterator foo").
+ */
+ public function testUnsupportedTagWithScalar()
+ {
+ $this->parser->parse('!iterator foo');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage The string "!!iterator foo" could not be parsed as it uses an unsupported built-in tag at line 1 (near "!!iterator foo").
+ */
+ public function testUnsupportedBuiltInTagWithScalar()
+ {
+ $this->parser->parse('!!iterator foo');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage The built-in tag "!!foo" is not implemented at line 1 (near "!!foo").
+ */
+ public function testExceptionWhenUsingUnsuportedBuiltInTags()
+ {
+ $this->parser->parse('!!foo');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Complex mappings are not supported at line 1 (near "? "1"").
+ */
+ public function testComplexMappingThrowsParseException()
+ {
+ $yaml = <<<YAML
+? "1"
+:
+ name: végétalien
+YAML;
+
+ $this->parser->parse($yaml);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Complex mappings are not supported at line 2 (near "? "1"").
+ */
+ public function testComplexMappingNestedInMappingThrowsParseException()
+ {
+ $yaml = <<<YAML
+diet:
+ ? "1"
+ :
+ name: végétalien
+YAML;
+
+ $this->parser->parse($yaml);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Complex mappings are not supported at line 1 (near "- ? "1"").
+ */
+ public function testComplexMappingNestedInSequenceThrowsParseException()
+ {
+ $yaml = <<<YAML
+- ? "1"
+ :
+ name: végétalien
+YAML;
+
+ $this->parser->parse($yaml);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Unable to parse at line 1 (near "[parameters]").
+ */
+ public function testParsingIniThrowsException()
+ {
+ $ini = <<<INI
+[parameters]
+ foo = bar
+ bar = %foo%
+INI;
+
+ $this->parser->parse($ini);
+ }
+
+ private function loadTestsFromFixtureFiles($testsFile)
+ {
+ $parser = new Parser();
+
+ $tests = array();
+ $files = $parser->parseFile(__DIR__.'/Fixtures/'.$testsFile);
+ foreach ($files as $file) {
+ $yamls = file_get_contents(__DIR__.'/Fixtures/'.$file.'.yml');
+
+ // split YAMLs documents
+ foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) {
+ if (!$yaml) {
+ continue;
+ }
+
+ $test = $parser->parse($yaml);
+ if (isset($test['todo']) && $test['todo']) {
+ // TODO
+ } else {
+ eval('$expected = '.trim($test['php']).';');
+
+ $tests[] = array(var_export($expected, true), $test['yaml'], $test['test']);
+ }
+ }
+ }
+
+ return $tests;
+ }
+
+ public function testCanParseVeryLongValue()
+ {
+ $longStringWithSpaces = str_repeat('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ', 20000);
+ $trickyVal = array('x' => $longStringWithSpaces);
+
+ $yamlString = Yaml::dump($trickyVal);
+ $arrayFromYaml = $this->parser->parse($yamlString);
+
+ $this->assertEquals($trickyVal, $arrayFromYaml);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Reference "foo" does not exist at line 2
+ */
+ public function testParserCleansUpReferencesBetweenRuns()
+ {
+ $yaml = <<<YAML
+foo: &foo
+ baz: foobar
+bar:
+ <<: *foo
+YAML;
+ $this->parser->parse($yaml);
+
+ $yaml = <<<YAML
+bar:
+ <<: *foo
+YAML;
+ $this->parser->parse($yaml);
+ }
+
+ public function testPhpConstantTagMappingKey()
+ {
+ $yaml = <<<YAML
+transitions:
+ !php/const 'Symfony\Component\Yaml\Tests\B::FOO':
+ from:
+ - !php/const 'Symfony\Component\Yaml\Tests\B::BAR'
+ to: !php/const 'Symfony\Component\Yaml\Tests\B::BAZ'
+YAML;
+ $expected = array(
+ 'transitions' => array(
+ 'foo' => array(
+ 'from' => array(
+ 'bar',
+ ),
+ 'to' => 'baz',
+ ),
+ ),
+ );
+
+ $this->assertSame($expected, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT));
+ }
+
+ public function testMergeKeysWhenMappingsAreParsedAsObjects()
+ {
+ $yaml = <<<YAML
+foo: &FOO
+ bar: 1
+bar: &BAR
+ baz: 2
+ <<: *FOO
+baz:
+ baz_foo: 3
+ <<:
+ baz_bar: 4
+foobar:
+ bar: ~
+ <<: [*FOO, *BAR]
+YAML;
+ $expected = (object) array(
+ 'foo' => (object) array(
+ 'bar' => 1,
+ ),
+ 'bar' => (object) array(
+ 'baz' => 2,
+ 'bar' => 1,
+ ),
+ 'baz' => (object) array(
+ 'baz_foo' => 3,
+ 'baz_bar' => 4,
+ ),
+ 'foobar' => (object) array(
+ 'bar' => null,
+ 'baz' => 2,
+ ),
+ );
+
+ $this->assertEquals($expected, $this->parser->parse($yaml, Yaml::PARSE_OBJECT_FOR_MAP));
+ }
+
+ public function testFilenamesAreParsedAsStringsWithoutFlag()
+ {
+ $file = __DIR__.'/Fixtures/index.yml';
+
+ $this->assertSame($file, $this->parser->parse($file));
+ }
+
+ public function testParseFile()
+ {
+ $this->assertInternalType('array', $this->parser->parseFile(__DIR__.'/Fixtures/index.yml'));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessageRegExp #^File ".+/Fixtures/nonexistent.yml" does not exist\.$#
+ */
+ public function testParsingNonExistentFilesThrowsException()
+ {
+ $this->parser->parseFile(__DIR__.'/Fixtures/nonexistent.yml');
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessageRegExp #^File ".+/Fixtures/not_readable.yml" cannot be read\.$#
+ */
+ public function testParsingNotReadableFilesThrowsException()
+ {
+ if ('\\' === \DIRECTORY_SEPARATOR) {
+ $this->markTestSkipped('chmod is not supported on Windows');
+ }
+
+ $file = __DIR__.'/Fixtures/not_readable.yml';
+ chmod($file, 0200);
+
+ $this->parser->parseFile($file);
+ }
+
+ public function testParseReferencesOnMergeKeys()
+ {
+ $yaml = <<<YAML
+mergekeyrefdef:
+ a: foo
+ <<: &quux
+ b: bar
+ c: baz
+mergekeyderef:
+ d: quux
+ <<: *quux
+YAML;
+ $expected = array(
+ 'mergekeyrefdef' => array(
+ 'a' => 'foo',
+ 'b' => 'bar',
+ 'c' => 'baz',
+ ),
+ 'mergekeyderef' => array(
+ 'd' => 'quux',
+ 'b' => 'bar',
+ 'c' => 'baz',
+ ),
+ );
+
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
+ public function testParseReferencesOnMergeKeysWithMappingsParsedAsObjects()
+ {
+ $yaml = <<<YAML
+mergekeyrefdef:
+ a: foo
+ <<: &quux
+ b: bar
+ c: baz
+mergekeyderef:
+ d: quux
+ <<: *quux
+YAML;
+ $expected = (object) array(
+ 'mergekeyrefdef' => (object) array(
+ 'a' => 'foo',
+ 'b' => 'bar',
+ 'c' => 'baz',
+ ),
+ 'mergekeyderef' => (object) array(
+ 'd' => 'quux',
+ 'b' => 'bar',
+ 'c' => 'baz',
+ ),
+ );
+
+ $this->assertEquals($expected, $this->parser->parse($yaml, Yaml::PARSE_OBJECT_FOR_MAP));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Yaml\Exception\ParseException
+ * @expectedExceptionMessage Reference "foo" does not exist
+ */
+ public function testEvalRefException()
+ {
+ $yaml = <<<EOE
+foo: { &foo { a: Steve, <<: *foo} }
+EOE;
+ $this->parser->parse($yaml);
+ }
+
+ /**
+ * @dataProvider indentedMappingData
+ */
+ public function testParseIndentedMappings($yaml, $expected)
+ {
+ $this->assertSame($expected, $this->parser->parse($yaml));
+ }
+
+ public function indentedMappingData()
+ {
+ $tests = array();
+
+ $yaml = <<<YAML
+foo:
+ - bar: "foobar"
+ # A comment
+ baz: "foobaz"
+YAML;
+ $expected = array(
+ 'foo' => array(
+ array(
+ 'bar' => 'foobar',
+ 'baz' => 'foobaz',
+ ),
+ ),
+ );
+ $tests['comment line is first line in indented block'] = array($yaml, $expected);
+
+ $yaml = <<<YAML
+foo:
+ - bar:
+ # comment
+ baz: [1, 2, 3]
+YAML;
+ $expected = array(
+ 'foo' => array(
+ array(
+ 'bar' => array(
+ 'baz' => array(1, 2, 3),
+ ),
+ ),
+ ),
+ );
+ $tests['mapping value on new line starting with a comment line'] = array($yaml, $expected);
+
+ $yaml = <<<YAML
+foo:
+ -
+ bar: foobar
+YAML;
+ $expected = array(
+ 'foo' => array(
+ array(
+ 'bar' => 'foobar',
+ ),
+ ),
+ );
+ $tests['mapping in sequence starting on a new line'] = array($yaml, $expected);
+
+ $yaml = <<<YAML
+foo:
+
+ bar: baz
+YAML;
+ $expected = array(
+ 'foo' => array(
+ 'bar' => 'baz',
+ ),
+ );
+ $tests['blank line at the beginning of an indented mapping value'] = array($yaml, $expected);
+
+ return $tests;
+ }
+}
+
+class B
+{
+ public $b = 'foo';
+
+ const FOO = 'foo';
+ const BAR = 'bar';
+ const BAZ = 'baz';
+}
diff --git a/vendor/symfony/yaml/Tests/YamlTest.php b/vendor/symfony/yaml/Tests/YamlTest.php
new file mode 100644
index 0000000..3f6c252
--- /dev/null
+++ b/vendor/symfony/yaml/Tests/YamlTest.php
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Tests;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Yaml\Yaml;
+
+class YamlTest extends TestCase
+{
+ public function testParseAndDump()
+ {
+ $data = array('lorem' => 'ipsum', 'dolor' => 'sit');
+ $yml = Yaml::dump($data);
+ $parsed = Yaml::parse($yml);
+ $this->assertEquals($data, $parsed);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The indentation must be greater than zero
+ */
+ public function testZeroIndentationThrowsException()
+ {
+ Yaml::dump(array('lorem' => 'ipsum', 'dolor' => 'sit'), 2, 0);
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @expectedExceptionMessage The indentation must be greater than zero
+ */
+ public function testNegativeIndentationThrowsException()
+ {
+ Yaml::dump(array('lorem' => 'ipsum', 'dolor' => 'sit'), 2, -4);
+ }
+}
diff --git a/vendor/symfony/yaml/Unescaper.php b/vendor/symfony/yaml/Unescaper.php
new file mode 100644
index 0000000..9c3a19e
--- /dev/null
+++ b/vendor/symfony/yaml/Unescaper.php
@@ -0,0 +1,138 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+use Symfony\Component\Yaml\Exception\ParseException;
+
+/**
+ * Unescaper encapsulates unescaping rules for single and double-quoted
+ * YAML strings.
+ *
+ * @author Matthew Lewinski <matthew@lewinski.org>
+ *
+ * @internal
+ */
+class Unescaper
+{
+ /**
+ * Regex fragment that matches an escaped character in a double quoted string.
+ */
+ const REGEX_ESCAPED_CHARACTER = '\\\\(x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|.)';
+
+ /**
+ * Unescapes a single quoted string.
+ *
+ * @param string $value A single quoted string
+ *
+ * @return string The unescaped string
+ */
+ public function unescapeSingleQuotedString(string $value): string
+ {
+ return str_replace('\'\'', '\'', $value);
+ }
+
+ /**
+ * Unescapes a double quoted string.
+ *
+ * @param string $value A double quoted string
+ *
+ * @return string The unescaped string
+ */
+ public function unescapeDoubleQuotedString(string $value): string
+ {
+ $callback = function ($match) {
+ return $this->unescapeCharacter($match[0]);
+ };
+
+ // evaluate the string
+ return preg_replace_callback('/'.self::REGEX_ESCAPED_CHARACTER.'/u', $callback, $value);
+ }
+
+ /**
+ * Unescapes a character that was found in a double-quoted string.
+ *
+ * @param string $value An escaped character
+ *
+ * @return string The unescaped character
+ */
+ private function unescapeCharacter(string $value): string
+ {
+ switch ($value[1]) {
+ case '0':
+ return "\x0";
+ case 'a':
+ return "\x7";
+ case 'b':
+ return "\x8";
+ case 't':
+ return "\t";
+ case "\t":
+ return "\t";
+ case 'n':
+ return "\n";
+ case 'v':
+ return "\xB";
+ case 'f':
+ return "\xC";
+ case 'r':
+ return "\r";
+ case 'e':
+ return "\x1B";
+ case ' ':
+ return ' ';
+ case '"':
+ return '"';
+ case '/':
+ return '/';
+ case '\\':
+ return '\\';
+ case 'N':
+ // U+0085 NEXT LINE
+ return "\xC2\x85";
+ case '_':
+ // U+00A0 NO-BREAK SPACE
+ return "\xC2\xA0";
+ case 'L':
+ // U+2028 LINE SEPARATOR
+ return "\xE2\x80\xA8";
+ case 'P':
+ // U+2029 PARAGRAPH SEPARATOR
+ return "\xE2\x80\xA9";
+ case 'x':
+ return self::utf8chr(hexdec(substr($value, 2, 2)));
+ case 'u':
+ return self::utf8chr(hexdec(substr($value, 2, 4)));
+ case 'U':
+ return self::utf8chr(hexdec(substr($value, 2, 8)));
+ default:
+ throw new ParseException(sprintf('Found unknown escape character "%s".', $value));
+ }
+ }
+
+ /**
+ * Get the UTF-8 character for the given code point.
+ */
+ private static function utf8chr(int $c): string
+ {
+ if (0x80 > $c %= 0x200000) {
+ return \chr($c);
+ }
+ if (0x800 > $c) {
+ return \chr(0xC0 | $c >> 6).\chr(0x80 | $c & 0x3F);
+ }
+ if (0x10000 > $c) {
+ return \chr(0xE0 | $c >> 12).\chr(0x80 | $c >> 6 & 0x3F).\chr(0x80 | $c & 0x3F);
+ }
+
+ return \chr(0xF0 | $c >> 18).\chr(0x80 | $c >> 12 & 0x3F).\chr(0x80 | $c >> 6 & 0x3F).\chr(0x80 | $c & 0x3F);
+ }
+}
diff --git a/vendor/symfony/yaml/Yaml.php b/vendor/symfony/yaml/Yaml.php
new file mode 100644
index 0000000..80de7e8
--- /dev/null
+++ b/vendor/symfony/yaml/Yaml.php
@@ -0,0 +1,102 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+use Symfony\Component\Yaml\Exception\ParseException;
+
+/**
+ * Yaml offers convenience methods to load and dump YAML.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @final
+ */
+class Yaml
+{
+ const DUMP_OBJECT = 1;
+ const PARSE_EXCEPTION_ON_INVALID_TYPE = 2;
+ const PARSE_OBJECT = 4;
+ const PARSE_OBJECT_FOR_MAP = 8;
+ const DUMP_EXCEPTION_ON_INVALID_TYPE = 16;
+ const PARSE_DATETIME = 32;
+ const DUMP_OBJECT_AS_MAP = 64;
+ const DUMP_MULTI_LINE_LITERAL_BLOCK = 128;
+ const PARSE_CONSTANT = 256;
+ const PARSE_CUSTOM_TAGS = 512;
+ const DUMP_EMPTY_ARRAY_AS_SEQUENCE = 1024;
+
+ /**
+ * Parses a YAML file into a PHP value.
+ *
+ * Usage:
+ * <code>
+ * $array = Yaml::parseFile('config.yml');
+ * print_r($array);
+ * </code>
+ *
+ * @param string $filename The path to the YAML file to be parsed
+ * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior
+ *
+ * @return mixed The YAML converted to a PHP value
+ *
+ * @throws ParseException If the file could not be read or the YAML is not valid
+ */
+ public static function parseFile(string $filename, int $flags = 0)
+ {
+ $yaml = new Parser();
+
+ return $yaml->parseFile($filename, $flags);
+ }
+
+ /**
+ * Parses YAML into a PHP value.
+ *
+ * Usage:
+ * <code>
+ * $array = Yaml::parse(file_get_contents('config.yml'));
+ * print_r($array);
+ * </code>
+ *
+ * @param string $input A string containing YAML
+ * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior
+ *
+ * @return mixed The YAML converted to a PHP value
+ *
+ * @throws ParseException If the YAML is not valid
+ */
+ public static function parse(string $input, int $flags = 0)
+ {
+ $yaml = new Parser();
+
+ return $yaml->parse($input, $flags);
+ }
+
+ /**
+ * Dumps a PHP value to a YAML string.
+ *
+ * The dump method, when supplied with an array, will do its best
+ * to convert the array into friendly YAML.
+ *
+ * @param mixed $input The PHP value
+ * @param int $inline The level where you switch to inline YAML
+ * @param int $indent The amount of spaces to use for indentation of nested nodes
+ * @param int $flags A bit field of DUMP_* constants to customize the dumped YAML string
+ *
+ * @return string A YAML string representing the original PHP value
+ */
+ public static function dump($input, int $inline = 2, int $indent = 4, int $flags = 0): string
+ {
+ $yaml = new Dumper($indent);
+
+ return $yaml->dump($input, $inline, 0, $flags);
+ }
+}
diff --git a/vendor/symfony/yaml/composer.json b/vendor/symfony/yaml/composer.json
new file mode 100644
index 0000000..6537e42
--- /dev/null
+++ b/vendor/symfony/yaml/composer.json
@@ -0,0 +1,43 @@
+{
+ "name": "symfony/yaml",
+ "type": "library",
+ "description": "Symfony Yaml Component",
+ "keywords": [],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": "^7.1.3",
+ "symfony/polyfill-ctype": "~1.8"
+ },
+ "require-dev": {
+ "symfony/console": "~3.4|~4.0"
+ },
+ "conflict": {
+ "symfony/console": "<3.4"
+ },
+ "suggest": {
+ "symfony/console": "For validating YAML files using the lint command"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Component\\Yaml\\": "" },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.1-dev"
+ }
+ }
+}
diff --git a/vendor/symfony/yaml/phpunit.xml.dist b/vendor/symfony/yaml/phpunit.xml.dist
new file mode 100644
index 0000000..7c732f8
--- /dev/null
+++ b/vendor/symfony/yaml/phpunit.xml.dist
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+ backupGlobals="false"
+ colors="true"
+ bootstrap="vendor/autoload.php"
+ failOnRisky="true"
+ failOnWarning="true"
+>
+ <php>
+ <ini name="error_reporting" value="-1" />
+ </php>
+
+ <testsuites>
+ <testsuite name="Symfony Yaml Component Test Suite">
+ <directory>./Tests/</directory>
+ </testsuite>
+ </testsuites>
+
+ <filter>
+ <whitelist>
+ <directory>./</directory>
+ <exclude>
+ <directory>./Tests</directory>
+ <directory>./vendor</directory>
+ </exclude>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/vendor/webmozart/assert/.composer-auth.json b/vendor/webmozart/assert/.composer-auth.json
new file mode 100644
index 0000000..eea8001
--- /dev/null
+++ b/vendor/webmozart/assert/.composer-auth.json
@@ -0,0 +1,7 @@
+{
+ "github-oauth": {
+ "github.com": "PLEASE DO NOT USE THIS TOKEN IN YOUR OWN PROJECTS/FORKS",
+ "github.com": "This token is reserved for testing the webmozart/* repositories",
+ "github.com": "a9debbffdd953ee9b3b82dbc3b807cde2086bb86"
+ }
+}
diff --git a/vendor/webmozart/assert/.styleci.yml b/vendor/webmozart/assert/.styleci.yml
new file mode 100644
index 0000000..c2ad4a5
--- /dev/null
+++ b/vendor/webmozart/assert/.styleci.yml
@@ -0,0 +1,11 @@
+preset: symfony
+
+finder:
+ exclude:
+ - "tests"
+
+enabled:
+ - ordered_use
+
+disabled:
+ - phpdoc_annotation_without_dot # This is still buggy: https://github.com/symfony/symfony/pull/19198
diff --git a/vendor/webmozart/assert/CHANGELOG.md b/vendor/webmozart/assert/CHANGELOG.md
new file mode 100644
index 0000000..65fbc8f
--- /dev/null
+++ b/vendor/webmozart/assert/CHANGELOG.md
@@ -0,0 +1,53 @@
+Changelog
+=========
+
+## UNRELEASED
+
+### Added
+
+* added `Assert::minCount()`
+* added `Assert::maxCount()`
+* added `Assert::countBetween()`
+* added `Assert::isCountable()`
+* added `Assert::notWhitespaceOnly()`
+* added `Assert::natural()`
+* added `Assert::notContains()`
+* added `Assert::isArrayAccessible()`
+* added `Assert::isInstanceOfAny()`
+* added `Assert::isIterable()`
+
+### Fixed
+
+* `stringNotEmpty` will no longer report "0" is an empty string
+
+## 1.2.0 (2016-11-23)
+
+ * added `Assert::throws()`
+ * added `Assert::count()`
+ * added extension point `Assert::reportInvalidArgument()` for custom subclasses
+
+## 1.1.0 (2016-08-09)
+
+ * added `Assert::object()`
+ * added `Assert::propertyExists()`
+ * added `Assert::propertyNotExists()`
+ * added `Assert::methodExists()`
+ * added `Assert::methodNotExists()`
+ * added `Assert::uuid()`
+
+## 1.0.2 (2015-08-24)
+
+ * integrated Style CI
+ * add tests for minimum package dependencies on Travis CI
+
+## 1.0.1 (2015-05-12)
+
+ * added support for PHP 5.3.3
+
+## 1.0.0 (2015-05-12)
+
+ * first stable release
+
+## 1.0.0-beta (2015-03-19)
+
+ * first beta release
diff --git a/vendor/webmozart/assert/LICENSE b/vendor/webmozart/assert/LICENSE
new file mode 100644
index 0000000..9e2e307
--- /dev/null
+++ b/vendor/webmozart/assert/LICENSE
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Bernhard Schussek
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/webmozart/assert/README.md b/vendor/webmozart/assert/README.md
new file mode 100644
index 0000000..1c1ede7
--- /dev/null
+++ b/vendor/webmozart/assert/README.md
@@ -0,0 +1,252 @@
+Webmozart Assert
+================
+
+[![Build Status](https://travis-ci.org/webmozart/assert.svg?branch=master)](https://travis-ci.org/webmozart/assert)
+[![Build status](https://ci.appveyor.com/api/projects/status/lyg83bcsisrr94se/branch/master?svg=true)](https://ci.appveyor.com/project/webmozart/assert/branch/master)
+[![Latest Stable Version](https://poser.pugx.org/webmozart/assert/v/stable.svg)](https://packagist.org/packages/webmozart/assert)
+[![Total Downloads](https://poser.pugx.org/webmozart/assert/downloads.svg)](https://packagist.org/packages/webmozart/assert)
+[![Dependency Status](https://www.versioneye.com/php/webmozart:assert/1.2.0/badge.svg)](https://www.versioneye.com/php/webmozart:assert/1.2.0)
+
+Latest release: [1.2.0](https://packagist.org/packages/webmozart/assert#1.2.0)
+
+PHP >= 5.3.9
+
+This library contains efficient assertions to test the input and output of
+your methods. With these assertions, you can greatly reduce the amount of coding
+needed to write a safe implementation.
+
+All assertions in the [`Assert`] class throw an `\InvalidArgumentException` if
+they fail.
+
+FAQ
+---
+
+**What's the difference to [beberlei/assert]?**
+
+This library is heavily inspired by Benjamin Eberlei's wonderful [assert package],
+but fixes a usability issue with error messages that can't be fixed there without
+breaking backwards compatibility.
+
+This package features usable error messages by default. However, you can also
+easily write custom error messages:
+
+```
+Assert::string($path, 'The path is expected to be a string. Got: %s');
+```
+
+In [beberlei/assert], the ordering of the `%s` placeholders is different for
+every assertion. This package, on the contrary, provides consistent placeholder
+ordering for all assertions:
+
+* `%s`: The tested value as string, e.g. `"/foo/bar"`.
+* `%2$s`, `%3$s`, ...: Additional assertion-specific values, e.g. the
+ minimum/maximum length, allowed values, etc.
+
+Check the source code of the assertions to find out details about the additional
+available placeholders.
+
+Installation
+------------
+
+Use [Composer] to install the package:
+
+```
+$ composer require webmozart/assert
+```
+
+Example
+-------
+
+```php
+use Webmozart\Assert\Assert;
+
+class Employee
+{
+ public function __construct($id)
+ {
+ Assert::integer($id, 'The employee ID must be an integer. Got: %s');
+ Assert::greaterThan($id, 0, 'The employee ID must be a positive integer. Got: %s');
+ }
+}
+```
+
+If you create an employee with an invalid ID, an exception is thrown:
+
+```php
+new Employee('foobar');
+// => InvalidArgumentException:
+// The employee ID must be an integer. Got: string
+
+new Employee(-10);
+// => InvalidArgumentException:
+// The employee ID must be a positive integer. Got: -10
+```
+
+Assertions
+----------
+
+The [`Assert`] class provides the following assertions:
+
+### Type Assertions
+
+Method | Description
+-------------------------------------------------------- | --------------------------------------------------
+`string($value, $message = '')` | Check that a value is a string
+`stringNotEmpty($value, $message = '')` | Check that a value is a non-empty string
+`integer($value, $message = '')` | Check that a value is an integer
+`integerish($value, $message = '')` | Check that a value casts to an integer
+`float($value, $message = '')` | Check that a value is a float
+`numeric($value, $message = '')` | Check that a value is numeric
+`natural($value, $message= ''')` | Check that a value is a non-negative integer
+`boolean($value, $message = '')` | Check that a value is a boolean
+`scalar($value, $message = '')` | Check that a value is a scalar
+`object($value, $message = '')` | Check that a value is an object
+`resource($value, $type = null, $message = '')` | Check that a value is a resource
+`isCallable($value, $message = '')` | Check that a value is a callable
+`isArray($value, $message = '')` | Check that a value is an array
+`isTraversable($value, $message = '')` (deprecated) | Check that a value is an array or a `\Traversable`
+`isIterable($value, $message = '')` | Check that a value is an array or a `\Traversable`
+`isCountable($value, $message = '')` | Check that a value is an array or a `\Countable`
+`isInstanceOf($value, $class, $message = '')` | Check that a value is an `instanceof` a class
+`isInstanceOfAny($value, array $classes, $message = '')` | Check that a value is an `instanceof` a at least one class on the array of classes
+`notInstanceOf($value, $class, $message = '')` | Check that a value is not an `instanceof` a class
+`isArrayAccessible($value, $message = '')` | Check that a value can be accessed as an array
+
+### Comparison Assertions
+
+Method | Description
+----------------------------------------------- | --------------------------------------------------
+`true($value, $message = '')` | Check that a value is `true`
+`false($value, $message = '')` | Check that a value is `false`
+`null($value, $message = '')` | Check that a value is `null`
+`notNull($value, $message = '')` | Check that a value is not `null`
+`isEmpty($value, $message = '')` | Check that a value is `empty()`
+`notEmpty($value, $message = '')` | Check that a value is not `empty()`
+`eq($value, $value2, $message = '')` | Check that a value equals another (`==`)
+`notEq($value, $value2, $message = '')` | Check that a value does not equal another (`!=`)
+`same($value, $value2, $message = '')` | Check that a value is identical to another (`===`)
+`notSame($value, $value2, $message = '')` | Check that a value is not identical to another (`!==`)
+`greaterThan($value, $value2, $message = '')` | Check that a value is greater than another
+`greaterThanEq($value, $value2, $message = '')` | Check that a value is greater than or equal to another
+`lessThan($value, $value2, $message = '')` | Check that a value is less than another
+`lessThanEq($value, $value2, $message = '')` | Check that a value is less than or equal to another
+`range($value, $min, $max, $message = '')` | Check that a value is within a range
+`oneOf($value, array $values, $message = '')` | Check that a value is one of a list of values
+
+### String Assertions
+
+You should check that a value is a string with `Assert::string()` before making
+any of the following assertions.
+
+Method | Description
+--------------------------------------------------- | -----------------------------------------------------------------
+`contains($value, $subString, $message = '')` | Check that a string contains a substring
+`notContains($value, $subString, $message = '')` | Check that a string does not contains a substring
+`startsWith($value, $prefix, $message = '')` | Check that a string has a prefix
+`startsWithLetter($value, $message = '')` | Check that a string starts with a letter
+`endsWith($value, $suffix, $message = '')` | Check that a string has a suffix
+`regex($value, $pattern, $message = '')` | Check that a string matches a regular expression
+`alpha($value, $message = '')` | Check that a string contains letters only
+`digits($value, $message = '')` | Check that a string contains digits only
+`alnum($value, $message = '')` | Check that a string contains letters and digits only
+`lower($value, $message = '')` | Check that a string contains lowercase characters only
+`upper($value, $message = '')` | Check that a string contains uppercase characters only
+`length($value, $length, $message = '')` | Check that a string has a certain number of characters
+`minLength($value, $min, $message = '')` | Check that a string has at least a certain number of characters
+`maxLength($value, $max, $message = '')` | Check that a string has at most a certain number of characters
+`lengthBetween($value, $min, $max, $message = '')` | Check that a string has a length in the given range
+`uuid($value, $message = '')` | Check that a string is a valid UUID
+`notWhitespaceOnly($value, $message = '')` | Check that a string contains at least one non-whitespace character
+
+### File Assertions
+
+Method | Description
+----------------------------------- | --------------------------------------------------
+`fileExists($value, $message = '')` | Check that a value is an existing path
+`file($value, $message = '')` | Check that a value is an existing file
+`directory($value, $message = '')` | Check that a value is an existing directory
+`readable($value, $message = '')` | Check that a value is a readable path
+`writable($value, $message = '')` | Check that a value is a writable path
+
+### Object Assertions
+
+Method | Description
+----------------------------------------------------- | --------------------------------------------------
+`classExists($value, $message = '')` | Check that a value is an existing class name
+`subclassOf($value, $class, $message = '')` | Check that a class is a subclass of another
+`implementsInterface($value, $class, $message = '')` | Check that a class implements an interface
+`propertyExists($value, $property, $message = '')` | Check that a property exists in a class/object
+`propertyNotExists($value, $property, $message = '')` | Check that a property does not exist in a class/object
+`methodExists($value, $method, $message = '')` | Check that a method exists in a class/object
+`methodNotExists($value, $method, $message = '')` | Check that a method does not exist in a class/object
+
+### Array Assertions
+
+Method | Description
+-------------------------------------------------- | ------------------------------------------------------------------
+`keyExists($array, $key, $message = '')` | Check that a key exists in an array
+`keyNotExists($array, $key, $message = '')` | Check that a key does not exist in an array
+`count($array, $number, $message = '')` | Check that an array contains a specific number of elements
+`minCount($array, $min, $message = '')` | Check that an array contains at least a certain number of elements
+`maxCount($array, $max, $message = '')` | Check that an array contains at most a certain number of elements
+`countBetween($array, $min, $max, $message = '')` | Check that an array has a count in the given range
+
+### Function Assertions
+
+Method | Description
+------------------------------------------- | -----------------------------------------------------------------------------------------------------
+`throws($closure, $class, $message = '')` | Check that a function throws a certain exception. Subclasses of the exception class will be accepted.
+
+### Collection Assertions
+
+All of the above assertions can be prefixed with `all*()` to test the contents
+of an array or a `\Traversable`:
+
+```php
+Assert::allIsInstanceOf($employees, 'Acme\Employee');
+```
+
+### Nullable Assertions
+
+All of the above assertions can be prefixed with `nullOr*()` to run the
+assertion only if it the value is not `null`:
+
+```php
+Assert::nullOrString($middleName, 'The middle name must be a string or null. Got: %s');
+```
+
+Authors
+-------
+
+* [Bernhard Schussek] a.k.a. [@webmozart]
+* [The Community Contributors]
+
+Contribute
+----------
+
+Contributions to the package are always welcome!
+
+* Report any bugs or issues you find on the [issue tracker].
+* You can grab the source code at the package's [Git repository].
+
+Support
+-------
+
+If you are having problems, send a mail to bschussek@gmail.com or shout out to
+[@webmozart] on Twitter.
+
+License
+-------
+
+All contents of this package are licensed under the [MIT license].
+
+[beberlei/assert]: https://github.com/beberlei/assert
+[assert package]: https://github.com/beberlei/assert
+[Composer]: https://getcomposer.org
+[Bernhard Schussek]: http://webmozarts.com
+[The Community Contributors]: https://github.com/webmozart/assert/graphs/contributors
+[issue tracker]: https://github.com/webmozart/assert/issues
+[Git repository]: https://github.com/webmozart/assert
+[@webmozart]: https://twitter.com/webmozart
+[MIT license]: LICENSE
+[`Assert`]: src/Assert.php
diff --git a/vendor/webmozart/assert/composer.json b/vendor/webmozart/assert/composer.json
new file mode 100644
index 0000000..c49e623
--- /dev/null
+++ b/vendor/webmozart/assert/composer.json
@@ -0,0 +1,34 @@
+{
+ "name": "webmozart/assert",
+ "description": "Assertions to validate method input/output with nice error messages.",
+ "keywords": ["assert", "check", "validate"],
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ }
+ ],
+ "require": {
+ "php": "^5.3.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.6",
+ "sebastian/version": "^1.0.1"
+ },
+ "autoload": {
+ "psr-4": {
+ "Webmozart\\Assert\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Webmozart\\Assert\\Tests\\": "tests/"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3-dev"
+ }
+ }
+}
diff --git a/vendor/webmozart/assert/src/Assert.php b/vendor/webmozart/assert/src/Assert.php
new file mode 100644
index 0000000..e2f89c0
--- /dev/null
+++ b/vendor/webmozart/assert/src/Assert.php
@@ -0,0 +1,1087 @@
+<?php
+
+/*
+ * This file is part of the webmozart/assert package.
+ *
+ * (c) Bernhard Schussek <bschussek@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Webmozart\Assert;
+
+use ArrayAccess;
+use BadMethodCallException;
+use Closure;
+use Countable;
+use Exception;
+use InvalidArgumentException;
+use Throwable;
+use Traversable;
+
+/**
+ * Efficient assertions to validate the input/output of your methods.
+ *
+ * @method static void nullOrString($value, $message = '')
+ * @method static void nullOrStringNotEmpty($value, $message = '')
+ * @method static void nullOrInteger($value, $message = '')
+ * @method static void nullOrIntegerish($value, $message = '')
+ * @method static void nullOrFloat($value, $message = '')
+ * @method static void nullOrNumeric($value, $message = '')
+ * @method static void nullOrBoolean($value, $message = '')
+ * @method static void nullOrScalar($value, $message = '')
+ * @method static void nullOrObject($value, $message = '')
+ * @method static void nullOrResource($value, $type = null, $message = '')
+ * @method static void nullOrIsCallable($value, $message = '')
+ * @method static void nullOrIsArray($value, $message = '')
+ * @method static void nullOrIsTraversable($value, $message = '')
+ * @method static void nullOrIsArrayAccessible($value, $message = '')
+ * @method static void nullOrIsCountable($value, $message = '')
+ * @method static void nullOrIsInstanceOf($value, $class, $message = '')
+ * @method static void nullOrNotInstanceOf($value, $class, $message = '')
+ * @method static void nullOrIsInstanceOfAny($value, $classes, $message = '')
+ * @method static void nullOrIsEmpty($value, $message = '')
+ * @method static void nullOrNotEmpty($value, $message = '')
+ * @method static void nullOrTrue($value, $message = '')
+ * @method static void nullOrFalse($value, $message = '')
+ * @method static void nullOrEq($value, $value2, $message = '')
+ * @method static void nullOrNotEq($value,$value2, $message = '')
+ * @method static void nullOrSame($value, $value2, $message = '')
+ * @method static void nullOrNotSame($value, $value2, $message = '')
+ * @method static void nullOrGreaterThan($value, $value2, $message = '')
+ * @method static void nullOrGreaterThanEq($value, $value2, $message = '')
+ * @method static void nullOrLessThan($value, $value2, $message = '')
+ * @method static void nullOrLessThanEq($value, $value2, $message = '')
+ * @method static void nullOrRange($value, $min, $max, $message = '')
+ * @method static void nullOrOneOf($value, $values, $message = '')
+ * @method static void nullOrContains($value, $subString, $message = '')
+ * @method static void nullOrNotContains($value, $subString, $message = '')
+ * @method static void nullOrNotWhitespaceOnly($value, $message = '')
+ * @method static void nullOrStartsWith($value, $prefix, $message = '')
+ * @method static void nullOrStartsWithLetter($value, $message = '')
+ * @method static void nullOrEndsWith($value, $suffix, $message = '')
+ * @method static void nullOrRegex($value, $pattern, $message = '')
+ * @method static void nullOrAlpha($value, $message = '')
+ * @method static void nullOrDigits($value, $message = '')
+ * @method static void nullOrAlnum($value, $message = '')
+ * @method static void nullOrLower($value, $message = '')
+ * @method static void nullOrUpper($value, $message = '')
+ * @method static void nullOrLength($value, $length, $message = '')
+ * @method static void nullOrMinLength($value, $min, $message = '')
+ * @method static void nullOrMaxLength($value, $max, $message = '')
+ * @method static void nullOrLengthBetween($value, $min, $max, $message = '')
+ * @method static void nullOrFileExists($value, $message = '')
+ * @method static void nullOrFile($value, $message = '')
+ * @method static void nullOrDirectory($value, $message = '')
+ * @method static void nullOrReadable($value, $message = '')
+ * @method static void nullOrWritable($value, $message = '')
+ * @method static void nullOrClassExists($value, $message = '')
+ * @method static void nullOrSubclassOf($value, $class, $message = '')
+ * @method static void nullOrImplementsInterface($value, $interface, $message = '')
+ * @method static void nullOrPropertyExists($value, $property, $message = '')
+ * @method static void nullOrPropertyNotExists($value, $property, $message = '')
+ * @method static void nullOrMethodExists($value, $method, $message = '')
+ * @method static void nullOrMethodNotExists($value, $method, $message = '')
+ * @method static void nullOrKeyExists($value, $key, $message = '')
+ * @method static void nullOrKeyNotExists($value, $key, $message = '')
+ * @method static void nullOrCount($value, $key, $message = '')
+ * @method static void nullOrMinCount($value, $min, $message = '')
+ * @method static void nullOrMaxCount($value, $max, $message = '')
+ * @method static void nullCountBetween($value, $min, $max, $message = '')
+ * @method static void nullOrUuid($values, $message = '')
+ * @method static void allString($values, $message = '')
+ * @method static void allStringNotEmpty($values, $message = '')
+ * @method static void allInteger($values, $message = '')
+ * @method static void allIntegerish($values, $message = '')
+ * @method static void allFloat($values, $message = '')
+ * @method static void allNumeric($values, $message = '')
+ * @method static void allBoolean($values, $message = '')
+ * @method static void allScalar($values, $message = '')
+ * @method static void allObject($values, $message = '')
+ * @method static void allResource($values, $type = null, $message = '')
+ * @method static void allIsCallable($values, $message = '')
+ * @method static void allIsArray($values, $message = '')
+ * @method static void allIsTraversable($values, $message = '')
+ * @method static void allIsArrayAccessible($values, $message = '')
+ * @method static void allIsCountable($values, $message = '')
+ * @method static void allIsInstanceOf($values, $class, $message = '')
+ * @method static void allNotInstanceOf($values, $class, $message = '')
+ * @method static void allIsInstanceOfAny($values, $classes, $message = '')
+ * @method static void allNull($values, $message = '')
+ * @method static void allNotNull($values, $message = '')
+ * @method static void allIsEmpty($values, $message = '')
+ * @method static void allNotEmpty($values, $message = '')
+ * @method static void allTrue($values, $message = '')
+ * @method static void allFalse($values, $message = '')
+ * @method static void allEq($values, $value2, $message = '')
+ * @method static void allNotEq($values,$value2, $message = '')
+ * @method static void allSame($values, $value2, $message = '')
+ * @method static void allNotSame($values, $value2, $message = '')
+ * @method static void allGreaterThan($values, $value2, $message = '')
+ * @method static void allGreaterThanEq($values, $value2, $message = '')
+ * @method static void allLessThan($values, $value2, $message = '')
+ * @method static void allLessThanEq($values, $value2, $message = '')
+ * @method static void allRange($values, $min, $max, $message = '')
+ * @method static void allOneOf($values, $values, $message = '')
+ * @method static void allContains($values, $subString, $message = '')
+ * @method static void allNotContains($values, $subString, $message = '')
+ * @method static void allNotWhitespaceOnly($values, $message = '')
+ * @method static void allStartsWith($values, $prefix, $message = '')
+ * @method static void allStartsWithLetter($values, $message = '')
+ * @method static void allEndsWith($values, $suffix, $message = '')
+ * @method static void allRegex($values, $pattern, $message = '')
+ * @method static void allAlpha($values, $message = '')
+ * @method static void allDigits($values, $message = '')
+ * @method static void allAlnum($values, $message = '')
+ * @method static void allLower($values, $message = '')
+ * @method static void allUpper($values, $message = '')
+ * @method static void allLength($values, $length, $message = '')
+ * @method static void allMinLength($values, $min, $message = '')
+ * @method static void allMaxLength($values, $max, $message = '')
+ * @method static void allLengthBetween($values, $min, $max, $message = '')
+ * @method static void allFileExists($values, $message = '')
+ * @method static void allFile($values, $message = '')
+ * @method static void allDirectory($values, $message = '')
+ * @method static void allReadable($values, $message = '')
+ * @method static void allWritable($values, $message = '')
+ * @method static void allClassExists($values, $message = '')
+ * @method static void allSubclassOf($values, $class, $message = '')
+ * @method static void allImplementsInterface($values, $interface, $message = '')
+ * @method static void allPropertyExists($values, $property, $message = '')
+ * @method static void allPropertyNotExists($values, $property, $message = '')
+ * @method static void allMethodExists($values, $method, $message = '')
+ * @method static void allMethodNotExists($values, $method, $message = '')
+ * @method static void allKeyExists($values, $key, $message = '')
+ * @method static void allKeyNotExists($values, $key, $message = '')
+ * @method static void allCount($values, $key, $message = '')
+ * @method static void allMinCount($values, $min, $message = '')
+ * @method static void allMaxCount($values, $max, $message = '')
+ * @method static void allCountBetween($values, $min, $max, $message = '')
+ * @method static void allUuid($values, $message = '')
+ *
+ * @since 1.0
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class Assert
+{
+ public static function string($value, $message = '')
+ {
+ if (!is_string($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a string. Got: %s',
+ static::typeToString($value)
+ ));
+ }
+ }
+
+ public static function stringNotEmpty($value, $message = '')
+ {
+ static::string($value, $message);
+ static::notEq($value, '', $message);
+ }
+
+ public static function integer($value, $message = '')
+ {
+ if (!is_int($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected an integer. Got: %s',
+ static::typeToString($value)
+ ));
+ }
+ }
+
+ public static function integerish($value, $message = '')
+ {
+ if (!is_numeric($value) || $value != (int) $value) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected an integerish value. Got: %s',
+ static::typeToString($value)
+ ));
+ }
+ }
+
+ public static function float($value, $message = '')
+ {
+ if (!is_float($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a float. Got: %s',
+ static::typeToString($value)
+ ));
+ }
+ }
+
+ public static function numeric($value, $message = '')
+ {
+ if (!is_numeric($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a numeric. Got: %s',
+ static::typeToString($value)
+ ));
+ }
+ }
+
+ public static function natural($value, $message = '')
+ {
+ if (!is_int($value) || $value < 0) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a non-negative integer. Got %s',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function boolean($value, $message = '')
+ {
+ if (!is_bool($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a boolean. Got: %s',
+ static::typeToString($value)
+ ));
+ }
+ }
+
+ public static function scalar($value, $message = '')
+ {
+ if (!is_scalar($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a scalar. Got: %s',
+ static::typeToString($value)
+ ));
+ }
+ }
+
+ public static function object($value, $message = '')
+ {
+ if (!is_object($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected an object. Got: %s',
+ static::typeToString($value)
+ ));
+ }
+ }
+
+ public static function resource($value, $type = null, $message = '')
+ {
+ if (!is_resource($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a resource. Got: %s',
+ static::typeToString($value)
+ ));
+ }
+
+ if ($type && $type !== get_resource_type($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a resource of type %2$s. Got: %s',
+ static::typeToString($value),
+ $type
+ ));
+ }
+ }
+
+ public static function isCallable($value, $message = '')
+ {
+ if (!is_callable($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a callable. Got: %s',
+ static::typeToString($value)
+ ));
+ }
+ }
+
+ public static function isArray($value, $message = '')
+ {
+ if (!is_array($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected an array. Got: %s',
+ static::typeToString($value)
+ ));
+ }
+ }
+
+ public static function isTraversable($value, $message = '')
+ {
+ @trigger_error(
+ sprintf(
+ 'The "%s" assertion is deprecated. You should stop using it, as it will soon be removed in 2.0 version. Use "isIterable" or "isInstanceOf" instead.',
+ __METHOD__
+ ),
+ E_USER_DEPRECATED
+ );
+
+ if (!is_array($value) && !($value instanceof Traversable)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a traversable. Got: %s',
+ static::typeToString($value)
+ ));
+ }
+ }
+
+ public static function isArrayAccessible($value, $message = '')
+ {
+ if (!is_array($value) && !($value instanceof ArrayAccess)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected an array accessible. Got: %s',
+ static::typeToString($value)
+ ));
+ }
+ }
+
+ public static function isCountable($value, $message = '')
+ {
+ if (!is_array($value) && !($value instanceof Countable)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a countable. Got: %s',
+ static::typeToString($value)
+ ));
+ }
+ }
+
+ public static function isIterable($value, $message = '')
+ {
+ if (!is_array($value) && !($value instanceof Traversable)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected an iterable. Got: %s',
+ static::typeToString($value)
+ ));
+ }
+ }
+
+ public static function isInstanceOf($value, $class, $message = '')
+ {
+ if (!($value instanceof $class)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected an instance of %2$s. Got: %s',
+ static::typeToString($value),
+ $class
+ ));
+ }
+ }
+
+ public static function notInstanceOf($value, $class, $message = '')
+ {
+ if ($value instanceof $class) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected an instance other than %2$s. Got: %s',
+ static::typeToString($value),
+ $class
+ ));
+ }
+ }
+
+ public static function isInstanceOfAny($value, array $classes, $message = '')
+ {
+ foreach ($classes as $class) {
+ if ($value instanceof $class) {
+ return;
+ }
+ }
+
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected an instance of any of %2$s. Got: %s',
+ static::typeToString($value),
+ implode(', ', array_map(array('static', 'valueToString'), $classes))
+ ));
+ }
+
+ public static function isEmpty($value, $message = '')
+ {
+ if (!empty($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected an empty value. Got: %s',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function notEmpty($value, $message = '')
+ {
+ if (empty($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a non-empty value. Got: %s',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function null($value, $message = '')
+ {
+ if (null !== $value) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected null. Got: %s',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function notNull($value, $message = '')
+ {
+ if (null === $value) {
+ static::reportInvalidArgument(
+ $message ?: 'Expected a value other than null.'
+ );
+ }
+ }
+
+ public static function true($value, $message = '')
+ {
+ if (true !== $value) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value to be true. Got: %s',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function false($value, $message = '')
+ {
+ if (false !== $value) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value to be false. Got: %s',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function eq($value, $value2, $message = '')
+ {
+ if ($value2 != $value) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value equal to %2$s. Got: %s',
+ static::valueToString($value),
+ static::valueToString($value2)
+ ));
+ }
+ }
+
+ public static function notEq($value, $value2, $message = '')
+ {
+ if ($value2 == $value) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a different value than %s.',
+ static::valueToString($value2)
+ ));
+ }
+ }
+
+ public static function same($value, $value2, $message = '')
+ {
+ if ($value2 !== $value) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value identical to %2$s. Got: %s',
+ static::valueToString($value),
+ static::valueToString($value2)
+ ));
+ }
+ }
+
+ public static function notSame($value, $value2, $message = '')
+ {
+ if ($value2 === $value) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value not identical to %s.',
+ static::valueToString($value2)
+ ));
+ }
+ }
+
+ public static function greaterThan($value, $limit, $message = '')
+ {
+ if ($value <= $limit) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value greater than %2$s. Got: %s',
+ static::valueToString($value),
+ static::valueToString($limit)
+ ));
+ }
+ }
+
+ public static function greaterThanEq($value, $limit, $message = '')
+ {
+ if ($value < $limit) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value greater than or equal to %2$s. Got: %s',
+ static::valueToString($value),
+ static::valueToString($limit)
+ ));
+ }
+ }
+
+ public static function lessThan($value, $limit, $message = '')
+ {
+ if ($value >= $limit) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value less than %2$s. Got: %s',
+ static::valueToString($value),
+ static::valueToString($limit)
+ ));
+ }
+ }
+
+ public static function lessThanEq($value, $limit, $message = '')
+ {
+ if ($value > $limit) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value less than or equal to %2$s. Got: %s',
+ static::valueToString($value),
+ static::valueToString($limit)
+ ));
+ }
+ }
+
+ public static function range($value, $min, $max, $message = '')
+ {
+ if ($value < $min || $value > $max) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value between %2$s and %3$s. Got: %s',
+ static::valueToString($value),
+ static::valueToString($min),
+ static::valueToString($max)
+ ));
+ }
+ }
+
+ public static function oneOf($value, array $values, $message = '')
+ {
+ if (!in_array($value, $values, true)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected one of: %2$s. Got: %s',
+ static::valueToString($value),
+ implode(', ', array_map(array('static', 'valueToString'), $values))
+ ));
+ }
+ }
+
+ public static function contains($value, $subString, $message = '')
+ {
+ if (false === strpos($value, $subString)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value to contain %2$s. Got: %s',
+ static::valueToString($value),
+ static::valueToString($subString)
+ ));
+ }
+ }
+
+ public static function notContains($value, $subString, $message = '')
+ {
+ if (false !== strpos($value, $subString)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: '%2$s was not expected to be contained in a value. Got: %s',
+ static::valueToString($value),
+ static::valueToString($subString)
+ ));
+ }
+ }
+
+ public static function notWhitespaceOnly($value, $message = '')
+ {
+ if (preg_match('/^\s*$/', $value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a non-whitespace string. Got: %s',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function startsWith($value, $prefix, $message = '')
+ {
+ if (0 !== strpos($value, $prefix)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value to start with %2$s. Got: %s',
+ static::valueToString($value),
+ static::valueToString($prefix)
+ ));
+ }
+ }
+
+ public static function startsWithLetter($value, $message = '')
+ {
+ $valid = isset($value[0]);
+
+ if ($valid) {
+ $locale = setlocale(LC_CTYPE, 0);
+ setlocale(LC_CTYPE, 'C');
+ $valid = ctype_alpha($value[0]);
+ setlocale(LC_CTYPE, $locale);
+ }
+
+ if (!$valid) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value to start with a letter. Got: %s',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function endsWith($value, $suffix, $message = '')
+ {
+ if ($suffix !== substr($value, -static::strlen($suffix))) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value to end with %2$s. Got: %s',
+ static::valueToString($value),
+ static::valueToString($suffix)
+ ));
+ }
+ }
+
+ public static function regex($value, $pattern, $message = '')
+ {
+ if (!preg_match($pattern, $value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'The value %s does not match the expected pattern.',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function alpha($value, $message = '')
+ {
+ $locale = setlocale(LC_CTYPE, 0);
+ setlocale(LC_CTYPE, 'C');
+ $valid = !ctype_alpha($value);
+ setlocale(LC_CTYPE, $locale);
+
+ if ($valid) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value to contain only letters. Got: %s',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function digits($value, $message = '')
+ {
+ $locale = setlocale(LC_CTYPE, 0);
+ setlocale(LC_CTYPE, 'C');
+ $valid = !ctype_digit($value);
+ setlocale(LC_CTYPE, $locale);
+
+ if ($valid) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value to contain digits only. Got: %s',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function alnum($value, $message = '')
+ {
+ $locale = setlocale(LC_CTYPE, 0);
+ setlocale(LC_CTYPE, 'C');
+ $valid = !ctype_alnum($value);
+ setlocale(LC_CTYPE, $locale);
+
+ if ($valid) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value to contain letters and digits only. Got: %s',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function lower($value, $message = '')
+ {
+ $locale = setlocale(LC_CTYPE, 0);
+ setlocale(LC_CTYPE, 'C');
+ $valid = !ctype_lower($value);
+ setlocale(LC_CTYPE, $locale);
+
+ if ($valid) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value to contain lowercase characters only. Got: %s',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function upper($value, $message = '')
+ {
+ $locale = setlocale(LC_CTYPE, 0);
+ setlocale(LC_CTYPE, 'C');
+ $valid = !ctype_upper($value);
+ setlocale(LC_CTYPE, $locale);
+
+ if ($valid) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value to contain uppercase characters only. Got: %s',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function length($value, $length, $message = '')
+ {
+ if ($length !== static::strlen($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value to contain %2$s characters. Got: %s',
+ static::valueToString($value),
+ $length
+ ));
+ }
+ }
+
+ public static function minLength($value, $min, $message = '')
+ {
+ if (static::strlen($value) < $min) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value to contain at least %2$s characters. Got: %s',
+ static::valueToString($value),
+ $min
+ ));
+ }
+ }
+
+ public static function maxLength($value, $max, $message = '')
+ {
+ if (static::strlen($value) > $max) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value to contain at most %2$s characters. Got: %s',
+ static::valueToString($value),
+ $max
+ ));
+ }
+ }
+
+ public static function lengthBetween($value, $min, $max, $message = '')
+ {
+ $length = static::strlen($value);
+
+ if ($length < $min || $length > $max) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a value to contain between %2$s and %3$s characters. Got: %s',
+ static::valueToString($value),
+ $min,
+ $max
+ ));
+ }
+ }
+
+ public static function fileExists($value, $message = '')
+ {
+ static::string($value);
+
+ if (!file_exists($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'The file %s does not exist.',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function file($value, $message = '')
+ {
+ static::fileExists($value, $message);
+
+ if (!is_file($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'The path %s is not a file.',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function directory($value, $message = '')
+ {
+ static::fileExists($value, $message);
+
+ if (!is_dir($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'The path %s is no directory.',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function readable($value, $message = '')
+ {
+ if (!is_readable($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'The path %s is not readable.',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function writable($value, $message = '')
+ {
+ if (!is_writable($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'The path %s is not writable.',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function classExists($value, $message = '')
+ {
+ if (!class_exists($value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected an existing class name. Got: %s',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function subclassOf($value, $class, $message = '')
+ {
+ if (!is_subclass_of($value, $class)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected a sub-class of %2$s. Got: %s',
+ static::valueToString($value),
+ static::valueToString($class)
+ ));
+ }
+ }
+
+ public static function implementsInterface($value, $interface, $message = '')
+ {
+ if (!in_array($interface, class_implements($value))) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected an implementation of %2$s. Got: %s',
+ static::valueToString($value),
+ static::valueToString($interface)
+ ));
+ }
+ }
+
+ public static function propertyExists($classOrObject, $property, $message = '')
+ {
+ if (!property_exists($classOrObject, $property)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected the property %s to exist.',
+ static::valueToString($property)
+ ));
+ }
+ }
+
+ public static function propertyNotExists($classOrObject, $property, $message = '')
+ {
+ if (property_exists($classOrObject, $property)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected the property %s to not exist.',
+ static::valueToString($property)
+ ));
+ }
+ }
+
+ public static function methodExists($classOrObject, $method, $message = '')
+ {
+ if (!method_exists($classOrObject, $method)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected the method %s to exist.',
+ static::valueToString($method)
+ ));
+ }
+ }
+
+ public static function methodNotExists($classOrObject, $method, $message = '')
+ {
+ if (method_exists($classOrObject, $method)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected the method %s to not exist.',
+ static::valueToString($method)
+ ));
+ }
+ }
+
+ public static function keyExists($array, $key, $message = '')
+ {
+ if (!array_key_exists($key, $array)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected the key %s to exist.',
+ static::valueToString($key)
+ ));
+ }
+ }
+
+ public static function keyNotExists($array, $key, $message = '')
+ {
+ if (array_key_exists($key, $array)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected the key %s to not exist.',
+ static::valueToString($key)
+ ));
+ }
+ }
+
+ public static function count($array, $number, $message = '')
+ {
+ static::eq(
+ count($array),
+ $number,
+ $message ?: sprintf('Expected an array to contain %d elements. Got: %d.', $number, count($array))
+ );
+ }
+
+ public static function minCount($array, $min, $message = '')
+ {
+ if (count($array) < $min) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected an array to contain at least %2$d elements. Got: %d',
+ count($array),
+ $min
+ ));
+ }
+ }
+
+ public static function maxCount($array, $max, $message = '')
+ {
+ if (count($array) > $max) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected an array to contain at most %2$d elements. Got: %d',
+ count($array),
+ $max
+ ));
+ }
+ }
+
+ public static function countBetween($array, $min, $max, $message = '')
+ {
+ $count = count($array);
+
+ if ($count < $min || $count > $max) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Expected an array to contain between %2$d and %3$d elements. Got: %d',
+ $count,
+ $min,
+ $max
+ ));
+ }
+ }
+
+ public static function uuid($value, $message = '')
+ {
+ $value = str_replace(array('urn:', 'uuid:', '{', '}'), '', $value);
+
+ // The nil UUID is special form of UUID that is specified to have all
+ // 128 bits set to zero.
+ if ('00000000-0000-0000-0000-000000000000' === $value) {
+ return;
+ }
+
+ if (!preg_match('/^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/', $value)) {
+ static::reportInvalidArgument(sprintf(
+ $message ?: 'Value %s is not a valid UUID.',
+ static::valueToString($value)
+ ));
+ }
+ }
+
+ public static function throws(Closure $expression, $class = 'Exception', $message = '')
+ {
+ static::string($class);
+
+ $actual = 'none';
+
+ try {
+ $expression();
+ } catch (Exception $e) {
+ $actual = get_class($e);
+ if ($e instanceof $class) {
+ return;
+ }
+ } catch (Throwable $e) {
+ $actual = get_class($e);
+ if ($e instanceof $class) {
+ return;
+ }
+ }
+
+ static::reportInvalidArgument($message ?: sprintf(
+ 'Expected to throw "%s", got "%s"',
+ $class,
+ $actual
+ ));
+ }
+
+ public static function __callStatic($name, $arguments)
+ {
+ if ('nullOr' === substr($name, 0, 6)) {
+ if (null !== $arguments[0]) {
+ $method = lcfirst(substr($name, 6));
+ call_user_func_array(array('static', $method), $arguments);
+ }
+
+ return;
+ }
+
+ if ('all' === substr($name, 0, 3)) {
+ static::isIterable($arguments[0]);
+
+ $method = lcfirst(substr($name, 3));
+ $args = $arguments;
+
+ foreach ($arguments[0] as $entry) {
+ $args[0] = $entry;
+
+ call_user_func_array(array('static', $method), $args);
+ }
+
+ return;
+ }
+
+ throw new BadMethodCallException('No such method: '.$name);
+ }
+
+ protected static function valueToString($value)
+ {
+ if (null === $value) {
+ return 'null';
+ }
+
+ if (true === $value) {
+ return 'true';
+ }
+
+ if (false === $value) {
+ return 'false';
+ }
+
+ if (is_array($value)) {
+ return 'array';
+ }
+
+ if (is_object($value)) {
+ return get_class($value);
+ }
+
+ if (is_resource($value)) {
+ return 'resource';
+ }
+
+ if (is_string($value)) {
+ return '"'.$value.'"';
+ }
+
+ return (string) $value;
+ }
+
+ protected static function typeToString($value)
+ {
+ return is_object($value) ? get_class($value) : gettype($value);
+ }
+
+ protected static function strlen($value)
+ {
+ if (!function_exists('mb_detect_encoding')) {
+ return strlen($value);
+ }
+
+ if (false === $encoding = mb_detect_encoding($value)) {
+ return strlen($value);
+ }
+
+ return mb_strwidth($value, $encoding);
+ }
+
+ protected static function reportInvalidArgument($message)
+ {
+ throw new InvalidArgumentException($message);
+ }
+
+ private function __construct()
+ {
+ }
+}